diff --git a/README.md b/README.md
index 8e17ccba8..cf64bf2d7 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,7 @@ Complete
* [Highcharts](http://www.highcharts.com/) (by [damianog](https://github.com/damianog))
* [History.js](https://github.com/balupton/History.js/) (by [Boris Yankov](https://github.com/borisyankov))
* [Humane.js](http://wavded.github.com/humane-js/) (by [John Vrbanac](https://github.com/jmvrbanac))
+* [i18next](http://i18next.com/) (by [Maarten Docter](https://github.com/mdocter))
* [Impress.js](https://github.com/bartaz/impress.js) (by [Boris Yankov](https://github.com/borisyankov))
* [iScroll](http://cubiq.org/iscroll-4) (by [Boris Yankov](https://github.com/borisyankov))
* [Jasmine](http://pivotal.github.com/jasmine/) (by [Boris Yankov](https://github.com/borisyankov))
@@ -49,6 +50,7 @@ Complete
* [Knockout.js](http://knockoutjs.com/) (by [Boris Yankov](https://github.com/borisyankov))
* [Knockout.Mapping](https://github.com/SteveSanderson/knockout.mapping) (by [Boris Yankov](https://github.com/borisyankov))
* [Knockout.Validation](https://github.com/ericmbarnard/Knockout-Validation) (by [Dan Ludwig](https://github.com/danludwig))
+* [KoLite](https://github.com/CodeSeven/kolite) (by [Boris Yankov](https://github.com/borisyankov))
* [linq.js](http://linqjs.codeplex.com/) (by [Marcin Najder](https://github.com/marcinnajder))
* [Modernizr](http://modernizr.com/) (by [Boris Yankov](https://github.com/borisyankov))
* [Moment.js](https://github.com/timrwood/moment) (by [Michael Lakerveld](https://github.com/Lakerfield))
diff --git a/breeze/breeze-tests.ts b/breeze/breeze-tests.ts
index 2f3e7e23d..06a50b3fc 100644
--- a/breeze/breeze-tests.ts
+++ b/breeze/breeze-tests.ts
@@ -1,8 +1,19 @@
-///
+///
import breeze = module(Breeze);
import core = module(BreezeCore);
+function test_dataType() {
+ var typ = breeze.DataType.DateTime;
+ var nm = typ.getName();
+ var isNumber = typ.isNumeric;
+ var dv = typ.defaultValue;
+ var symbs = breeze.DataType.getSymbols();
+ var x = typ.parentEnum === breeze.DataType;
+ var isFalse = breeze.DataType.contains(breeze.DataType.Double);
+ var dt = breeze.DataType.fromName("Decimal");
+}
+
function test_dataProperty() {
var lastNameProp = new breeze.DataProperty({
name: "lastName",
@@ -11,7 +22,17 @@ function test_dataProperty() {
maxLength: 20
});
var personEntityType: breeze.EntityType;
- personEntityType.addProperty(lastNameProp);
+ personEntityType.addProperty(lastNameProp);
+}
+
+function test_dataService() {
+ var ds = new breeze.DataService({
+ serviceName: "api/NorthwindIBModel",
+ hasServerMetadata: true
+ });
+ var em = new breeze.EntityManager({
+ dataService: ds
+ });
}
function test_entityAspect() {
@@ -22,10 +43,9 @@ function test_entityAspect() {
var orderDateErrors = order.entityAspect.getValidationErrors("OrderDate");
var orderDateProperty = order.entityType.getProperty("OrderDate");
var orderDateErrors = order.entityAspect.getValidationErrors(orderDateProperty);
- order.entityAspect.loadNavigationProperty("Orders")
- .then(function (data) {
- var orders = data.results;
- }).fail(function (exception) { });
+ order.entityAspect.loadNavigationProperty("Orders").then(function (data) {
+ var orders = data.results;
+ }).fail(function (exception) { });
order.entityAspect.rejectChanges();
order.entityAspect.setDeleted();
order.entityAspect.setModified();
@@ -37,31 +57,30 @@ function test_entityAspect() {
var isOk = order.entityAspect.validateProperty("Order");
var orderDateProperty = order.entityType.getProperty("OrderDate");
//var isOk = order.entityAspect.validateProperty(OrderDateProperty);
- order.entityAspect.propertyChanged.subscribe(
- function (propertyChangedArgs) {
+ order.entityAspect.propertyChanged.subscribe(function (propertyChangedArgs) {
var entity = propertyChangedArgs.entity;
var propertyNameChanged = propertyChangedArgs.propertyName;
var oldValue = propertyChangedArgs.oldValue;
var newValue = propertyChangedArgs.newValue;
});
- order.entityAspect.validationErrorsChanged.subscribe(
- function (validationChangeArgs) {
+ order.entityAspect.validationErrorsChanged.subscribe(function (validationChangeArgs) {
var entity = validationChangeArgs.entity;
var errorsAdded = validationChangeArgs.added;
var errorsCleared = validationChangeArgs.removed;
});
+
}
function test_entityKey() {
var em1: breeze.EntityManager;
var employee1: breeze.Entity;
var empType = em1.metadataStore.getEntityType("Employee");
- var entityKey = new breeze.EntityKey(empType, 1);
+ var entityKey = new breeze.EntityKey( empType, 1);
var empKey = employee1.entityAspect.getKey();
var empTerrType = em1.metadataStore.getEntityType("EmployeeTerritory");
- var empTerrKey = new breeze.EntityKey(empTerrType, [1, 77]);
+ var empTerrKey = new breeze.EntityKey( empTerrType, [1, 77]);
var empType = em1.metadataStore.getEntityType("Employee");
- var empKey1 = new breeze.EntityKey(empType, 1);
+ var empKey1 = new breeze.EntityKey( empType, 1);
var empKey2 = employee1.entityAspect.getKey();
if (empKey1.equals(empKey2)) { }
if (breeze.EntityKey.equals(empKey1, empKey2)) { }
@@ -130,7 +149,7 @@ function test_entityManager() {
queryOptions: queryOptions,
validationOptions: validationOptions
});
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
var cust1 = custType.createEntity();
em1.addEntity(cust1);
em1.attachEntity(cust1, breeze.EntityState.Added);
@@ -189,9 +208,11 @@ function test_entityManager() {
.fail(function (exception) {
});
var employeeType = em1.metadataStore.getEntityType("Employee");
- var employeeKey = new breeze.EntityKey(employeeType, 1);
- var employee = em1.findEntityByKey(employeeKey);
- var custType = em1.metadataStore.getEntityType("Customer");
+ var employeeKey = new breeze.EntityKey( employeeType, 1);
+ var employee = em1.fetchEntityByKey(employeeKey);
+ var emp2 = em1.fetchEntityByKey("Employee", 6);
+ var emp3 = em1.fetchEntityByKey("Entityee", [6]);
+ var custType = em1.metadataStore.getEntityType("Customer");
var custumer = custType.createEntity();
var customerId = em.generateTempKeyValue(custumer);
em1.saveChanges()
@@ -199,25 +220,25 @@ function test_entityManager() {
var sameCust1 = data.results[0];
});
var changedEntities = em1.getChanges();
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
var changedCustomers = em1.getChanges(custType);
- var custType = em1.metadataStore.getEntityType("Customer");
- var orderType = em1.metadataStore.getEntityType("Order");
+ var custType = em1.metadataStore.getEntityType("Customer");
+ var orderType = em1.metadataStore.getEntityType("Order");
var changedCustomersAndOrders = em1.getChanges([custType, orderType]);
var entities = em1.getEntities();
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
var customers = em1.getEntities(custType);
- var custType = em1.metadataStore.getEntityType("Customer");
- var orderType = em1.metadataStore.getEntityType("Order");
+ var custType = em1.metadataStore.getEntityType("Customer");
+ var orderType = em1.metadataStore.getEntityType("Order");
var customersAndOrders = em1.getChanges([custType, orderType]);
- var custType = em1.metadataStore.getEntityType("Customer");
- var orderType = em1.metadataStore.getEntityType("Order");
+ var custType = em1.metadataStore.getEntityType("Customer");
+ var orderType = em1.metadataStore.getEntityType("Order");
var addedCustomersAndOrders = em1.getEntities([custType, orderType], breeze.EntityState.Added);
if (em1.hasChanges()) { }
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
if (em1.hasChanges(custType)) { }
- var custType = em1.metadataStore.getEntityType("Customer");
- var orderType = em1.metadataStore.getEntityType("Order");
+ var custType = em1.metadataStore.getEntityType("Customer");
+ var orderType = em1.metadataStore.getEntityType("Order");
if (em1.hasChanges([custType, orderType])) { }
var bundle = em1.exportEntities();
window.localStorage.setItem("myEntityManager", bundle);
@@ -258,10 +279,10 @@ function test_entityManager() {
var entity = changeArgs.entity;
});
var em = new breeze.EntityManager({ serviceName: "api/NorthwindIBModel" });
- em.hasChanges.subscribe(function (args) {
- var hasChanges = args.hasChanges;
- var entityManager = args.entityManager;
- });
+ //em.hasChanges.subscribe(function (args) {
+ // var hasChanges = args.hasChanges;
+ // var entityManager = args.entityManager;
+ //});
}
function test_entityQuery() {
@@ -309,13 +330,13 @@ function test_entityQuery() {
var customerQuery = breeze.EntityQuery.fromEntities(customer);
var metadataStore: breeze.MetadataStore;
var empType = metadataStore.getEntityType("Employee");
- var entityKey = new breeze.EntityKey(empType, 1);
+ var entityKey = new breeze.EntityKey( empType, 1);
var query = breeze.EntityQuery.fromEntityKey(entityKey);
var employee: breeze.Entity;
var entityKey = employee.entityAspect.getKey();
var query = breeze.EntityQuery.fromEntityKey(entityKey);
var ordersNavProp = employee.entityType.getProperty("Orders");
- var query = breeze.EntityQuery.fromEntityNavigation(employee, ordersNavProp);
+ var query = breeze.EntityQuery.fromEntityNavigation(employee, ordersNavProp);
var query = new breeze.EntityQuery("Customers")
.orderBy("CompanyName");
var query = new breeze.EntityQuery("Customers")
@@ -396,6 +417,7 @@ function test_entityState() {
return es === breeze.EntityState.Unchanged;
var es = anEntity.entityAspect.entityState;
return es.isUnchangedOrModified();
+
return es === breeze.EntityState.Unchanged || es === breeze.EntityState.Modified;
}
@@ -413,11 +435,11 @@ function test_entityType() {
myEntityType.addProperty(dataProperty1);
myEntityType.addProperty(dataProperty2);
myEntityType.addProperty(navigationProperty1);
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
var countryProp = custType.getProperty("Country");
var valFn = function (v) {
if (v == null) return true;
- return (core.stringStartsWith(v, "US"));
+ return (v.substring(0,2) === "US");
};
var countryValidator = new breeze.Validator("countryIsUS", valFn,
{ displayName: "Country", messageTemplate: "'%displayName%' must start with 'US'" });
@@ -426,74 +448,74 @@ function test_entityType() {
var someEntityLevelValidator: breeze.Validator;
custType.addValidator(someEntityLevelValidator);
custType.validators.push(someEntityLevelValidator);
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
var cust1 = custType.createEntity();
em1.addEntity(cust1);
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
var customerNameDataProp = custType.getDataProperty("CustomerName");
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
var customerOrdersNavProp = custType.getDataProperty("Orders");
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
var arrayOfProps = custType.getProperties();
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
var companyNameProp = custType.getProperty("CompanyName");
- var orderDetailType = em1.metadataStore.getEntityType("OrderDetail");
+ var orderDetailType = em1.metadataStore.getEntityType("OrderDetail");
var companyNameProp2 = orderDetailType.getProperty("Order.Customer.CompanyName");
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
var arrayOfPropNames = custType.getPropertyNames();
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
custType.setProperties({
autoGeneratedKeyType: breeze.AutoGeneratedKeyType.Identity,
defaultResourceName: "CustomersAndIncludedOrders"
});
}
-function test_enum() {
- var prototype = {
- nextDay: function () {
- var nextIndex = (this.dayIndex + 1) % 7;
- return DayOfWeek.getSymbols()[nextIndex];
- }
- };
- var DayOfWeek = new core.Enum("DayOfWeek", prototype);
- DayOfWeek.Monday = DayOfWeek.addSymbol({ dayIndex: 0 });
- var symbol = DayOfWeek.Friday;
- if (DayOfWeek.contains(symbol)) { }
- var dayOfWeek = DayOfWeek.from("Thursday");
- var symbols = DayOfWeek.getNames();
- var symbols = DayOfWeek.getSymbols();
- if (core.Enum.isSymbol(DayOfWeek.Wednesday)) { };
- DayOfWeek.seal();
- var name = DayOfWeek.Monday.getName();
- var name = DayOfWeek.Monday.toString();
+//function test_enum() {
+// var prototype = {
+// nextDay: function () {
+// var nextIndex = (this.dayIndex + 1) % 7;
+// return DayOfWeek.getSymbols()[nextIndex];
+// }
+// };
+// var DayOfWeek = new core.Enum("DayOfWeek", prototype);
+// DayOfWeek.Monday = DayOfWeek.addSymbol({ dayIndex: 0 });
+// var symbol = DayOfWeek.Friday;
+// if (DayOfWeek.contains(symbol)) { }
+// var dayOfWeek = DayOfWeek.from("Thursday");
+// var symbols = DayOfWeek.getNames();
+// var symbols = DayOfWeek.getSymbols();
+// if (core.Enum.isSymbol(DayOfWeek.Wednesday)) { };
+// DayOfWeek.seal();
+// var name = DayOfWeek.Monday.getName();
+// var name = DayOfWeek.Monday.toString();
- var prototype = {
- nextDay: function () {
- var nextIndex = (this.dayIndex + 1) % 7;
- return DayOfWeek.getSymbols()[nextIndex];
- }
- };
- var DayOfWeek = new core.Enum("DayOfWeek", prototype);
- DayOfWeek.Monday = DayOfWeek.addSymbol({ dayIndex: 0 });
- DayOfWeek.Tuesday = DayOfWeek.addSymbol({ dayIndex: 1 });
- DayOfWeek.Wednesday = DayOfWeek.addSymbol({ dayIndex: 2 });
- DayOfWeek.Thursday = DayOfWeek.addSymbol({ dayIndex: 3 });
- DayOfWeek.Friday = DayOfWeek.addSymbol({ dayIndex: 4 });
- DayOfWeek.Saturday = DayOfWeek.addSymbol({ dayIndex: 5, isWeekend: true });
- DayOfWeek.Sunday = DayOfWeek.addSymbol({ dayIndex: 6, isWeekend: true });
- DayOfWeek.seal();
- DayOfWeek.Monday.nextDay() === DayOfWeek.Tuesday;
- DayOfWeek.Sunday.nextDay() === DayOfWeek.Monday;
- DayOfWeek.Tuesday.isWeekend === undefined;
- DayOfWeek.Saturday.isWeekend == true;
- DayOfWeek instanceof core.Enum;
- core.Enum.isSymbol(DayOfWeek.Wednesday);
- DayOfWeek.contains(DayOfWeek.Thursday);
- DayOfWeek.Tuesday.parentEnum == DayOfWeek;
- DayOfWeek.getSymbols().length === 7;
- DayOfWeek.Friday.toString() === "Friday";
-}
+// var prototype = {
+// nextDay: function () {
+// var nextIndex = (this.dayIndex + 1) % 7;
+// return DayOfWeek.getSymbols()[nextIndex];
+// }
+// };
+// var DayOfWeek = new core.Enum("DayOfWeek", prototype);
+// DayOfWeek.Monday = DayOfWeek.addSymbol({ dayIndex: 0 });
+// DayOfWeek.Tuesday = DayOfWeek.addSymbol({ dayIndex: 1 });
+// DayOfWeek.Wednesday = DayOfWeek.addSymbol({ dayIndex: 2 });
+// DayOfWeek.Thursday = DayOfWeek.addSymbol({ dayIndex: 3 });
+// DayOfWeek.Friday = DayOfWeek.addSymbol({ dayIndex: 4 });
+// DayOfWeek.Saturday = DayOfWeek.addSymbol({ dayIndex: 5, isWeekend: true });
+// DayOfWeek.Sunday = DayOfWeek.addSymbol({ dayIndex: 6, isWeekend: true });
+// DayOfWeek.seal();
+// DayOfWeek.Monday.nextDay() === DayOfWeek.Tuesday;
+// DayOfWeek.Sunday.nextDay() === DayOfWeek.Monday;
+// DayOfWeek.Tuesday.isWeekend === undefined;
+// DayOfWeek.Saturday.isWeekend == true;
+// DayOfWeek instanceof core.Enum;
+// core.Enum.isSymbol(DayOfWeek.Wednesday);
+// DayOfWeek.contains(DayOfWeek.Thursday);
+// DayOfWeek.Tuesday.parentEnum == DayOfWeek;
+// DayOfWeek.getSymbols().length === 7;
+// DayOfWeek.Friday.toString() === "Friday";
+//}
function test_event() {
var myEntityManager: breeze.EntityManager;
@@ -502,7 +524,7 @@ function test_event() {
core.Event.enable("propertyChanged", myEntityManager, false);
core.Event.enable("propertyChanged", myEntityManager, true);
core.Event.enable("propertyChanged", myEntity.entityAspect, false);
- core.Event.enable("propertyChanged", myEntity.entityAspect, null);
+ core.Event.enable("propertyChanged", myEntity.entityAspect, null);
core.Event.enable("validationErrorsChanged", myEntityManager, function (em) {
return em.customTag === "blue";
});
@@ -548,6 +570,11 @@ function test_namingConventions() {
return clientPropertyName.substr(0, 1).toUpperCase() + clientPropertyName.substr(1);
}
});
+ var nc = new breeze.NamingConvention({
+ serverPropertyNameToClient: function (x) {
+ return "xxx";
+ }
+ });
var ms = new breeze.MetadataStore({ namingConvention: namingConv });
var em = new breeze.EntityManager({ metadataStore: ms });
var namingConv = new breeze.NamingConvention({
@@ -580,6 +607,8 @@ function test_navigationProperty() {
function test_predicate() {
var p1 = new breeze.Predicate("CompanyName", "StartsWith", "B");
+ var p1a = breeze.Predicate.create("CompanyName", "==", "City");
+ var p2a = p1a.and(p1a.not());
var query = new breeze.EntityQuery("Customers").where(p1);
var p2 = new breeze.Predicate("Region", breeze.FilterQueryOp.Equals, null);
var query = new breeze.EntityQuery("Customers").where(p2);
@@ -633,9 +662,9 @@ function test_queryOptions() {
em1.setProperties({ queryOptions: newQo });
var newQo = new breeze.QueryOptions({ mergeStrategy: breeze.MergeStrategy.OverwriteChanges });
newQo.setAsDefault();
- var queryOptions = em1.defaultQueryOptions.using(breeze.MergeStrategy.PreserveChanges);
- var queryOptions = em1.defaultQueryOptions.using(breeze.FetchStrategy.FromLocalCache);
- var queryOptions = em1.defaultQueryOptions.using({ mergeStrategy: breeze.MergeStrategy.OverwriteChanges });
+ var queryOptions = em1.queryOptions.using(breeze.MergeStrategy.PreserveChanges);
+ var queryOptions = em1.queryOptions.using(breeze.FetchStrategy.FromLocalCache);
+ var queryOptions = em1.queryOptions.using({ mergeStrategy: breeze.MergeStrategy.OverwriteChanges });
}
function test_validationOptions() {
@@ -652,16 +681,16 @@ function test_validationOptions() {
function test_validator() {
var valFn = function (v) {
if (v == null) return true;
- return (stringStartsWith(v, "US"));
+ return ( v.substr(0,2)=== "US");
};
var countryValidator = new breeze.Validator("countryIsUS", valFn, {
displayName: "Country",
messageTemplate: "'%displayName%' must start with 'US'"
});
var metadataStore: breeze.MetadataStore;
- var custType = metadataStore.getEntityType("Customer");
+ var custType = metadataStore.getEntityType("Customer");
var countryProp = custType.getProperty("Country");
- prop.validators.push(countryValidator);
+ countryProp.validators.push(countryValidator);
function isValidZipCode(value) {
var re = /^\d{5}([\-]\d{4})?$/;
return (re.test(value));
@@ -676,7 +705,7 @@ function test_validator() {
var zipCodeValidator = new breeze.Validator("zipCodeValidator", valFn,
{ messageTemplate: "For the US, this is not a valid PostalCode" });
var em1: breeze.EntityManager;
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
custType.validators.push(zipCodeValidator);
var numericRangeValidator = function (context) {
var valFn = function (v, ctx) {
@@ -693,72 +722,65 @@ function test_validator() {
});
};
freightProperty.validators.push(numericRangeValidator({ min: 100, max: 500 }));
- var productType = em1.metadataStore.getEntityType("Product");
+ var productType = em1.metadataStore.getEntityType("Product");
var discontinuedProperty = productType.getProperty("Discontinued");
discontinuedProperty.validators.push(breeze.Validator.bool());
- var orderType = em1.metadataStore.getEntityType("Order");
+ var orderType = em1.metadataStore.getEntityType("Order");
var freightProperty = orderType.getProperty("Freight");
regionProperty.validators.push(breeze.Validator.byte());
- var orderType = em1.metadataStore.getEntityType("Order");
+ var orderType = em1.metadataStore.getEntityType("Order");
var orderDateProperty = orderType.getProperty("OrderDate");
orderDateProperty.validators.push(breeze.Validator.date());
var v0 = breeze.Validator.maxLength({ maxLength: 5, displayName: "City" });
v0.validate("adasdfasdf");
var errMessage = v0.getMessage();
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
var customerIdProperty = custType.getProperty("CustomerID");
customerIdProperty.validators.push(breeze.Validator.guid());
- var orderType = em1.metadataStore.getEntityType("Order");
+ var orderType = em1.metadataStore.getEntityType("Order");
var freightProperty = orderType.getProperty("Freight");
freightProperty.validators.push(breeze.Validator.int16());
- var orderType = em1.metadataStore.getEntityType("Order");
+ var orderType = em1.metadataStore.getEntityType("Order");
var freightProperty = orderType.getProperty("Freight");
freightProperty.validators.push(breeze.Validator.int32());
- var orderType = em1.metadataStore.getEntityType("Order");
+ var orderType = em1.metadataStore.getEntityType("Order");
var freightProperty = orderType.getProperty("Freight");
freightProperty.validators.push(breeze.Validator.int64());
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
var regionProperty = custType.getProperty("Region");
regionProperty.validators.push(breeze.Validator.maxLength({ maxLength: 5 }));
- var orderType = em1.metadataStore.getEntityType("Order");
+ var orderType = em1.metadataStore.getEntityType("Order");
var freightProperty = orderType.getProperty("Freight");
freightProperty.validators.push(breeze.Validator.number());
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
var regionProperty = custType.getProperty("Region");
regionProperty.validators.push(breeze.Validator.required());
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
var regionProperty = custType.getProperty("Region");
regionProperty.validators.push(breeze.Validator.string());
- var custType = em1.metadataStore.getEntityType("Customer");
+ var custType = em1.metadataStore.getEntityType("Customer");
var regionProperty = custType.getProperty("Region");
regionProperty.validators.push(breeze.Validator.stringLength({ minLength: 2, maxLength: 5 }));
var validator = breeze.Validator.maxLength({ maxLength: 5, displayName: "City" });
var result = validator.validate("asdf");
- ok(result === null);
+ var ok = result === null;
result = validator.validate("adasdfasdf");
var errMsg = result.errorMessage;
var context = result.context;
var sameValidator = result.validator;
var valFn = function (v) {
if (v == null) return true;
- return (stringStartsWith(v, "US"));
+ return (v.substr(0,2) === "US");
};
var countryValidator = new breeze.Validator("countryIsUS", valFn, { displayName: "Country" });
- breeze.Validator.messageTemplates["countryIsUS", "'%displayName%' must start with 'US'");
+ breeze.Validator.messageTemplates["countryIsUS"] = "'%displayName%' must start with 'US'";
}
function test_demo() {
- var core = breeze.core,
- entityModel = breeze.entityModel;
- core.config.setProperties({
- trackingImplementation: entityModel.entityTracking_ko,
- remoteAccessImplementation: entityModel.remoteAccess_webApi
- });
+ var manager = new breeze.EntityManager('api/northwind');
- var manager = new entityModel.EntityManager('api/northwind');
-
- var query = new entityModel.EntityQuery()
+ var query = new breeze.EntityQuery()
.from("Employees");
manager.executeQuery(query).then(function (data) { });
diff --git a/breeze/breeze-0.65.d.ts b/breeze/breeze.d.ts
similarity index 58%
rename from breeze/breeze-0.65.d.ts
rename to breeze/breeze.d.ts
index 38346cf1f..9bacdf1f8 100644
--- a/breeze/breeze-0.65.d.ts
+++ b/breeze/breeze.d.ts
@@ -3,6 +3,8 @@
// Definitions by: Boris Yankov
// Definitions: https://github.com/borisyankov/DefinitelyTyped
+// Updated Jan 14 2011 - Jay Traband ( www.ideablade.com).
+
declare module BreezeCore {
@@ -10,7 +12,14 @@ declare module BreezeCore {
(error: Error): void;
}
- class Enum {
+ interface IEnum {
+ contains(object: any): bool;
+ fromName(name: string): EnumSymbol;
+ getNames(): string[];
+ getSymbols(): EnumSymbol[];
+ }
+
+ class Enum implements IEnum {
constructor (name: string, methodObj?: any);
addSymbol(propertiesObj?: any): EnumSymbol;
@@ -23,7 +32,7 @@ declare module BreezeCore {
}
class EnumSymbol {
- parentEnum: Enum;
+ parentEnum: IEnum;
getName(): string;
toString(): string;
@@ -51,96 +60,167 @@ declare module Breeze {
entityType: EntityType;
}
+ interface ComplexObject {
+ complexAspect: ComplexAspect;
+ complexType: ComplexType;
+ }
+
+ interface IProperty {
+ name: string;
+ parentEntityType: EntityType;
+ validators: Validator[];
+ isDataProperty: bool;
+ isNavigationProperty: bool;
+ }
+
+ interface IStructuralType {
+ complexProperties: DataProperty[];
+ dataProperties: DataProperty[];
+ name: string;
+ namespace: string;
+ shortName: string;
+ unmappedProperties: DataProperty[];
+ validators: Validator[];
+ }
+
class AutoGeneratedKeyType {
static Identity: AutoGeneratedKeyType;
static KeyGenerator: AutoGeneratedKeyType;
static None: AutoGeneratedKeyType;
}
- interface DataPropertyOptions {
- name?: string;
- nameOnServer?: string;
- dataType?: DataType;
- isNullable?: bool;
- isPartOfKey?: bool;
- isUnmapped?: bool;
- concurrencyMode?: string;
- maxLength?: number;
- fixedLength?: bool;
- validators?: Validator[];
+ class ComplexAspect {
+ complexObject: ComplexObject;
+ entityAspect: EntityAspect;
+ parent: Object;
+ parentProperty: DataProperty;
+ propertyPath: string;
+ originalValues: Object;
}
- class DataProperty {
+ class ComplexType implements IStructuralType {
+ complexProperties: DataProperty[];
+ dataProperties: DataProperty[];
+ name: string;
+ namespace: string;
+ shortName: string;
+ unmappedProperties: DataProperty[];
+ validators: Validator[];
+ addProperty(dataProperty: DataProperty);
+ getProperties(): DataProperty[];
+ }
+
+ class DataProperty implements IProperty {
+ complexTypeName: string;
concurrencyMode: string;
- dataType: DataType;
+ dataType: DataTypeSymbol;
defaultValue: any;
fixedLength: bool;
+ isComplexProperty: bool;
+ isDataProperty: bool;
+ isNavigationProperty: bool;
isNullable: bool;
isPartOfKey: bool;
isUnmapped: bool;
+
maxLength: number;
name: string;
+ nameOnServer: string;
parentEntityType: EntityType;
relatedNavigationProperty: NavigationProperty;
validators: Validator[];
-
constructor (config: DataPropertyOptions);
}
- class DataType {
- static Binary: DataType;
- static Boolean: DataType;
- static Byte: DataType;
- static DateTime: DataType;
- static Decimal: DataType;
- static Double: DataType;
- static Guid: DataType;
- static Int16: DataType;
- static Int32: DataType;
- static Int64: DataType;
- static Single: DataType;
- static String: DataType;
- static Undefined: DataType;
-
- defaultValue: any;
- isNumeric: bool;
-
- static toDataType(typeName: string): DataType;
+ interface DataPropertyOptions {
+ complexTypeName?: string;
+ concurrencyMode?: string;
+ dataType?: DataTypeSymbol;
+ defaultValue?: any;
+ fixedLength?: bool;
+ isNullable?: bool;
+ isPartOfKey?: bool;
+ isUnmapped?: bool;
+ maxLength?: number;
+ name?: string;
+ nameOnServer?: string;
+ validators?: Validator[];
}
- class EntityAction {
- static AcceptChanges: EntityAction;
- static Attach: EntityAction;
- static AttachOnImport: EntityAction;
- static AttachOnQuery: EntityAction;
- static Clear: EntityAction;
- static Detach: EntityAction;
- static EntityStateChange: EntityAction;
- static MergeOnImport: EntityAction;
- static MergeOnSave: EntityAction;
- static MergeOnQuery: EntityAction;
- static PropertyChange: EntityAction;
- static RejectChanges: EntityAction;
+ class DataService {
+ adapterName: string;
+ hasServerMetadata: bool;
+ serviceName: string;
+ constructor(config: DataServiceOptions);
}
+ interface DataServiceOptions {
+ adapterName?: string;
+ hasServerMetadata?: bool;
+ serviceName?: string;
+ }
+
+ class DataTypeSymbol extends BreezeCore.EnumSymbol {
+ defaultValue: any;
+ isNumeric: bool;
+ }
+ interface DataType extends BreezeCore.IEnum {
+ Binary: DataTypeSymbol;
+ Boolean: DataTypeSymbol;
+ Byte: DataTypeSymbol;
+ DateTime: DataTypeSymbol;
+ Decimal: DataTypeSymbol;
+ Double: DataTypeSymbol;
+ Guid: DataTypeSymbol;
+ Int16: DataTypeSymbol;
+ Int32: DataTypeSymbol;
+ Int64: DataTypeSymbol;
+ Single: DataTypeSymbol;
+ String: DataTypeSymbol;
+ Time: DataTypeSymbol;
+ Undefined: DataTypeSymbol;
+ toDataType(typeName: string): DataTypeSymbol;
+ parseDateFromServer(date: any): Date;
+
+ }
+ declare var DataType: DataType;
+
+ class EntityActionSymbol extends BreezeCore.EnumSymbol {
+ }
+ interface EntityAction extends BreezeCore.IEnum {
+ AcceptChanges: EntityActionSymbol;
+ Attach: EntityActionSymbol;
+ AttachOnImport: EntityActionSymbol;
+ AttachOnQuery: EntityActionSymbol;
+ Clear: EntityActionSymbol;
+ Detach: EntityActionSymbol;
+ EntityStateChange: EntityActionSymbol;
+ MergeOnImport: EntityActionSymbol;
+ MergeOnSave: EntityActionSymbol;
+ MergeOnQuery: EntityActionSymbol;
+ PropertyChange: EntityActionSymbol;
+ RejectChanges: EntityActionSymbol;
+ }
+ var EntityAction: EntityAction;
+
class EntityAspect {
entity: Entity;
entityManager: EntityManager;
- entityState: EntityState;
+ entityState: EntityStateSymbol;
isBeingSaved: bool;
originalValues: any;
- propertyChanged: BreezeCore.Event;
- validationErrorsChanged: BreezeCore.Event;
+ propertyChanged: PropertyChangedEvent;
+ validationErrorsChanged: ValidationErrorsChangedEvent;
acceptChanges(): void;
addValidationError(validationError: ValidationError): void;
+ clearValidationErrors(): void;
getKey(forceRefresh?: bool): EntityKey;
getValidationErrors(): ValidationError[];
getValidationErrors(property: string): ValidationError[];
- getValidationErrors(property: DataProperty): ValidationError[];
- getValidationErrors(property: NavigationProperty): ValidationError[];
+ getValidationErrors(property: IProperty): ValidationError[];
loadNavigationProperty(navigationProperty: string, callback?: Function, errorCallback?: Function): Promise;
loadNavigationProperty(navigationProperty: NavigationProperty, callback?: Function, errorCallback?: Function): Promise;
@@ -161,6 +241,27 @@ declare module Breeze {
validateProperty(property: NavigationProperty, context?: any): bool;
}
+ class PropertyChangedEventArgs {
+ entity: Entity;
+ propertyName: string;
+ oldValue: any;
+ newValue: any;
+ }
+
+ class PropertyChangedEvent extends BreezeCore.Event {
+ subscribe(callback?: (data: PropertyChangedEventArgs) => void ): number;
+ }
+
+ class ValidationErrorsChangedEventArgs {
+ entity: Entity;
+ added: ValidationError[];
+ removed: ValidationError[];
+ }
+
+ class ValidationErrorsChangedEvent extends BreezeCore.Event {
+ subscribe(callback?: (data: ValidationErrorsChangedEventArgs) => void ): number;
+ }
+
class EntityKey {
constructor (entityType: EntityType, keyValue: any);
constructor (entityType: EntityType, keyValues: any[]);
@@ -169,17 +270,88 @@ declare module Breeze {
static equals(k1: EntityKey, k2: EntityKey): bool;
}
+ class EntityManager {
+ dataService: DataService;
+ keyGeneratorCtor: Function;
+ metadataStore: MetadataStore;
+ queryOptions: QueryOptions;
+ saveOptions: SaveOptions;
+ serviceName: string;
+ validationOptions: ValidationOptions;
+
+ entityChanged: EntityChangedEvent;
+ // hasChanges: BreezeCore.Event;
+
+ constructor (config?: EntityManagerOptions);
+ constructor (config?: string);
+
+ addEntity(entity: Entity): Entity;
+ attachEntity(entity: Entity, entityState?: EntityStateSymbol): Entity;
+ clear(): void;
+ createEmptyCopy(): EntityManager;
+ detachEntity(entity: Entity): bool;
+
+ executeQuery(query: string, callback?: ExecuteQuerySuccessCallback, errorCallback?: ExecuteQueryErrorCallback): Promise;
+ executeQuery(query: EntityQuery, callback?: ExecuteQuerySuccessCallback, errorCallback?: ExecuteQueryErrorCallback): Promise;
+
+ executeQueryLocally(query: EntityQuery): Entity[];
+ exportEntities(entities?: Entity[]): string;
+ fetchEntityByKey(typeName: string, keyValue: any, checkLocalCacheFirst?: bool): Entity;
+ fetchEntityByKey(typeName: string, keyValues: any[], checkLocalCacheFirst?: bool): Entity;
+ fetchEntityByKey(entityKey: EntityKey): Entity;
+ fetchMetadata(callback?: (schema: any) => void , errorCallback?: BreezeCore.ErrorCallback): Promise;
+ generateTempKeyValue(entity: Entity): any;
+ getChanges(): Entity[];
+ getChanges(entityTypeName: string): Entity[];
+ getChanges(entityTypeNames: string[]): Entity[];
+ getChanges(entityType: EntityType): Entity[];
+ getChanges(entityTypes: EntityType[]): Entity[];
+
+ getEntities(entityTypeName: string, entityState?: EntityStateSymbol): Entity[];
+ getEntities(entityTypeNames?: string[], entityState?: EntityStateSymbol): Entity[];
+ getEntities(entityTypeName?: string, entityStates?: EntityStateSymbol[]): Entity[];
+ getEntities(entityTypeNames?: string[], entityStates?: EntityStateSymbol[]): Entity[];
+
+ getEntities(entityType: EntityType, entityState?: EntityStateSymbol): Entity[];
+ getEntities(entityTypes?: EntityType[], entityState?: EntityStateSymbol): Entity[];
+ getEntities(entityType?: EntityType, entityStates?: EntityStateSymbol[]): Entity[];
+ getEntities(entityTypes?: EntityType[], entityStates?: EntityStateSymbol[]): Entity[];
+
+ getEntityByKey(typeName: string, keyValue: any): Entity;
+ getEntityByKey(typeName: string, keyValues: any[]): Entity;
+ getEntityByKey(entityKey: EntityKey): Entity;
+
+ hasChanges(): bool;
+ hasChanges(entityTypeName: string): bool;
+ hasChanges(entityTypeNames: string[]): bool;
+ hasChanges(entityType: EntityType): bool;
+ hasChanges(entityTypes: EntityType[]): bool;
+
+ static importEntities(exportedString: string, config?: { mergeStrategy?: MergeStrategySymbol; }): EntityManager;
+ importEntities(exportedString: string, config?: { mergeStrategy?: MergeStrategySymbol; }): EntityManager;
+
+ rejectChanges(): Entity[];
+ saveChanges(entities?: Entity[], saveOptions?: SaveOptions, callback?: SaveChangesSuccessCallback, errorCallback?: SaveChangesErrorCallback): Promise;
+ setProperties(config: EntityManagerProperties): void;
+ }
+
interface EntityManagerOptions {
serviceName?: string;
+ dataService?: DataService;
metadataStore?: MetadataStore;
queryOptions?: QueryOptions;
saveOptions?: SaveOptions;
validationOptions?: ValidationOptions;
keyGeneratorCtor?: Function;
- remoteAccessImplementation?: RemoteAccessImplementation;
}
- interface RemoteAccessImplementation {
+ interface EntityManagerProperties {
+ serviceName?: string;
+ dataService?: DataService;
+ queryOptions?: QueryOptions;
+ saveOptions?: SaveOptions;
+ validationOptions?: ValidationOptions;
+ keyGeneratorCtor?: Function;
}
interface ExecuteQuerySuccessCallback {
@@ -198,69 +370,20 @@ declare module Breeze {
(error: { XHR: XMLHttpRequest; }): void;
}
- interface EntityManagerProperties {
- serviceName?: string;
- queryOptions?: QueryOptions;
- saveOptions?: SaveOptions;
- validationOptions?: ValidationOptions;
- remoteAccessImplementation?: RemoteAccessImplementation;
- keyGeneratorCtor?: Function;
+ class EntityChangedEventArgs {
+ entity: Entity;
+ entityAction: EntityActionSymbol;
+ args: Object;
}
- class EntityManager {
- keyGeneratorCtor: Function;
- metadataStore: MetadataStore;
- queryOptions: QueryOptions;
- remoteAccessImplementation: RemoteAccessImplementation;
- saveOptions: SaveOptions;
- serviceName: string;
- validationOptions: ValidationOptions;
-
- entityChanged: BreezeCore.Event;
- //hasChanges: BreezeCore.Event;
-
- constructor (config?: EntityManagerOptions);
- constructor (config?: string);
-
- addEntity(entity: Entity): Entity;
- attachEntity(entity: Entity, entityState?: EntityState): Entity;
- clear(): void;
- createEmptyCopy(): EntityManager;
- detachEntity(entity: Entity): bool;
-
- executeQuery(query: string, callback?: ExecuteQuerySuccessCallback, errorCallback?: ExecuteQueryErrorCallback): Promise;
- executeQuery(query: EntityQuery, callback?: ExecuteQuerySuccessCallback, errorCallback?: ExecuteQueryErrorCallback): Promise;
-
- executeQueryLocally(query: EntityQuery): Entity[];
- exportEntities(entities?: Entity[]): string;
- fetchMetadata(callback?: (schema: any) => void , errorCallback?: BreezeCore.ErrorCallback): Promise;
- findEntityByKey(entityKey: EntityKey): Entity;
- generateTempKeyValue(entity: Entity): any;
- getChanges(): Entity[];
-
- getChanges(entityType: EntityType): Entity[];
- getChanges(entityTypes: EntityType[]): Entity[];
-
- getEntities(entityTypes: EntityType, entityState?: EntityState): Entity[];
- getEntities(entityTypes?: EntityType[], entityState?: EntityState): Entity[];
- getEntities(entityType?: EntityType, entityStates?: EntityState[]): Entity[];
- getEntities(entityTypes?: EntityType[], entityStates?: EntityState[]): Entity[];
-
- hasChanges(): bool;
- hasChanges(entityType: EntityType): bool;
- hasChanges(entityTypes: EntityType[]): bool;
-
- static importEntities(exportedString: string, config?: { mergeStrategy?: MergeStrategy; }): EntityManager;
- importEntities(exportedString: string, config?: { mergeStrategy?: MergeStrategy; }): EntityManager;
-
- rejectChanges(): Entity[];
- saveChanges(entities?: Entity[], saveOptions?: SaveOptions, callback?: SaveChangesSuccessCallback, errorCallback?: SaveChangesErrorCallback): Promise;
- setProperties(config: EntityManagerProperties): void;
+ class EntityChangedEvent extends BreezeCore.Event {
+ subscribe(callback?: (data: EntityChangedEventArgs) => void ): number;
}
class EntityQuery {
entityManager: EntityManager;
orderByClause: OrderByClause;
+ parameters: Object;
queryOptions: QueryOptions;
resourceName: string;
skipCount: number;
@@ -271,6 +394,7 @@ declare module Breeze {
execute(callback?: ExecuteQuerySuccessCallback, errorCallback?: ExecuteQueryErrorCallback): Promise;
executeLocally(): Entity[];
+ expand(propertyPaths: string[]): EntityQuery;
expand(propertyPaths: string): EntityQuery;
static from(resourceName: string): EntityQuery;
from(resourceName: string): EntityQuery;
@@ -278,33 +402,32 @@ declare module Breeze {
static fromEntities(entities: Entity[]): EntityQuery;
static fromEntityKey(entityKey: EntityKey): EntityQuery;
static fromEntityNavigation(entity: Entity, navigationProperty: NavigationProperty): EntityQuery;
+ inlineCount(enabled?: bool): EntityQuery;
orderBy(propertyPaths: string): EntityQuery;
+ orderBy(propertyPaths: string[]): EntityQuery;
orderByDesc(propertyPaths: string): EntityQuery;
+ orderByDesc(propertyPaths: string[]): EntityQuery;
select(propertyPaths: string): EntityQuery;
+ select(propertyPaths: string[]): EntityQuery;
skip(count: number): EntityQuery;
take(count: number): EntityQuery;
top(count: number): EntityQuery;
using(obj: EntityManager): EntityQuery;
- using(obj: MergeStrategy): EntityQuery;
- //using(obj: FetchStrategy): EntityQuery; !!! same signature as MergeStrategy
+ using(obj: MergeStrategySymbol): EntityQuery;
+ using(obj: FetchStrategySymbol): EntityQuery;
where(predicate: Predicate): EntityQuery;
where(property: string, operator: string, value: any): EntityQuery;
- where(property: string, operator: FilterQueryOp, value: any): EntityQuery;
- where(predicate: FilterQueryOp): EntityQuery;
+ where(property: string, operator: FilterQueryOpSymbol, value: any): EntityQuery;
+ where(predicate: FilterQueryOpSymbol): EntityQuery;
+ withParameters(params: Object): EntityQuery;
}
interface OrderByClause {
}
- class EntityState {
- static Added: EntityState;
- static Deleted: EntityState;
- static Detached: EntityState;
- static Modified: EntityState;
- static Unchanged: EntityState;
-
+ class EntityStateSymbol extends BreezeCore.EnumSymbol {
isAdded(): bool;
isAddedModifiedOrDeleted(): bool;
isDeleted(): bool;
@@ -313,9 +436,18 @@ declare module Breeze {
isUnchanged(): bool;
isUnchangedOrModified(): bool;
}
+ interface EntityState extends BreezeCore.IEnum {
+ Added: EntityStateSymbol;
+ Deleted: EntityStateSymbol;
+ Detached: EntityStateSymbol;
+ Modified: EntityStateSymbol;
+ Unchanged: EntityStateSymbol;
+ }
+ var EntityState: EntityState;
- class EntityType {
+ class EntityType implements IStructuralType {
autoGeneratedKeyType: AutoGeneratedKeyType;
+ complexProperties: DataProperty[];
concurrencyProperties: DataProperty[];
dataProperties: DataProperty[];
defaultResourceName: string;
@@ -332,25 +464,23 @@ declare module Breeze {
constructor (config: MetadataStore);
constructor (config: EntityTypeOptions);
- addProperty(property: DataProperty): void;
- addProperty(property: NavigationProperty): void;
- addValidator(validator: Validator, property?: any): void;
- createEntity(): Entity;
+ addProperty(property: IProperty): void;
+ addValidator(validator: Validator, property?: IProperty): void;
+ createEntity(initialValues?: Object): Entity;
getDataProperty(propertyName: string): DataProperty;
getEntityCtor(): Function;
getNavigationProperty(propertyName: string): NavigationProperty;
- getProperties(): any;
- getProperty(propertyPath: string, throwIfNotFound?: bool): any;
+ getProperties(): IProperty[];
+ getProperty(propertyPath: string, throwIfNotFound?: bool): IProperty;
getPropertyNames(): string[];
setProperties(config: EntityTypeProperties): void;
toString(): string;
}
interface EntityTypeOptions {
- metadataStore?: MetadataStore;
- serviceName?: string;
shortName?: string;
namespace?: string;
+ autogeneratedKeyType?: AutoGeneratedKeyType;
defaultResourceName?: string;
}
@@ -359,22 +489,28 @@ declare module Breeze {
defaultResourceName?: string;
}
- class FetchStrategy {
- static FromLocalCache: MergeStrategy;
- static FromServer: MergeStrategy;
+ class FetchStrategySymbol extends BreezeCore.EnumSymbol {
}
+ interface FetchStrategy extends BreezeCore.IEnum {
+ FromLocalCache: FetchStrategySymbol;
+ FromServer: FetchStrategySymbol;
+ }
+ var FetchStrategy: FetchStrategy;
- class FilterQueryOp {
- static Contains: FilterQueryOp;
- static EndsWith: FilterQueryOp;
- static Equals: FilterQueryOp;
- static GreaterThan: FilterQueryOp;
- static GreaterThanOrEqual: FilterQueryOp;
- static LessThan: FilterQueryOp;
- static LessThanOrEqual: FilterQueryOp;
- static NotEquals: FilterQueryOp;
- static StartsWith: FilterQueryOp;
+ class FilterQueryOpSymbol extends BreezeCore.EnumSymbol {
}
+ interface FilterQueryOp extends BreezeCore.IEnum {
+ Contains: FilterQueryOpSymbol;
+ EndsWith: FilterQueryOpSymbol;
+ Equals: FilterQueryOpSymbol;
+ GreaterThan: FilterQueryOpSymbol;
+ GreaterThanOrEqual: FilterQueryOpSymbol;
+ LessThan: FilterQueryOpSymbol;
+ LessThanOrEqual: FilterQueryOpSymbol;
+ NotEquals: FilterQueryOpSymbol;
+ StartsWith: FilterQueryOpSymbol;
+ }
+ var FilterQueryOp: FilterQueryOp;
class LocalQueryComparisonOptions {
static caseInsensitiveSQL: LocalQueryComparisonOptions;
@@ -385,20 +521,26 @@ declare module Breeze {
setAsDefault(): void;
}
- class MergeStrategy {
- static OverwriteChanges: MergeStrategy;
- static PreserveChanges: MergeStrategy;
+ class MergeStrategySymbol extends BreezeCore.EnumSymbol {
}
+ interface MergeStrategy extends BreezeCore.IEnum {
+ OverwriteChanges: MergeStrategySymbol;
+ PreserveChanges: MergeStrategySymbol;
+ }
+ var MergeStrategy: MergeStrategy;
class MetadataStore {
namingConvention: NamingConvention;
constructor (config?: MetadataStoreOptions);
-
+ addDataService(dataService: DataService): void;
+ addEntityType(structuralType: IStructuralType): void;
exportMetadata(): string;
- fetchMetadata(serviceName: string, remoteAccessImplementation?: RemoteAccessImplementation, callback?: (data) => void , errorCallback?: BreezeCore.ErrorCallback): Promise;
- getEntityType(entityTypeName: string, okIfNotFound?: bool): EntityType;
- getEntityTypes(): EntityType[];
+ fetchMetadata(dataService: string, callback?: (data) => void , errorCallback?: BreezeCore.ErrorCallback): Promise;
+ fetchMetadata(dataService: DataService, callback?: (data) => void , errorCallback?: BreezeCore.ErrorCallback): Promise;
+ getDataService(serviceName: string): DataService;
+ getEntityType(entityTypeName: string, okIfNotFound?: bool): IStructuralType;
+ getEntityTypes(): IStructuralType[];
hasMetadataFor(serviceName: string): bool;
static importMetadata(exportedString: string): MetadataStore;
importMetadata(exportedString: string): MetadataStore;
@@ -420,22 +562,20 @@ declare module Breeze {
constructor (config: NamingConventionOptions);
clientPropertyNameToServer(clientPropertyName: string): string;
- clientPropertyNameToServer(clientPropertyName: string, property: DataProperty): string;
- clientPropertyNameToServer(clientPropertyName: string, property: NavigationProperty): string;
+ clientPropertyNameToServer(clientPropertyName: string, property: IProperty): string;
serverPropertyNameToClient(serverPropertyName: string): string;
- serverPropertyNameToClient(serverPropertyName: string, property: DataProperty): string;
- serverPropertyNameToClient(serverPropertyName: string, property: NavigationProperty): string;
+ serverPropertyNameToClient(serverPropertyName: string, property: IProperty): string;
setAsDefault();
}
interface NamingConventionOptions {
- serverPropertyNameToClient?: Function;
- clientPropertyNameToServer?: Function;
+ serverPropertyNameToClient?: (name: string) => string;
+ clientPropertyNameToServer?: (name: string) => string;
}
- class NavigationProperty {
+ class NavigationProperty implements IProperty {
associationName: string;
entityType: EntityType;
foreignKeyNames: string[];
@@ -463,8 +603,8 @@ declare module Breeze {
}
class Predicate {
- constructor (property: string, operator: string, value: any);
- constructor (property: string, operator: FilterQueryOp, value: any);
+ constructor (property: string, operator: string, value: any, valueIsLiteral?: bool);
+ constructor (property: string, operator: FilterQueryOpSymbol, value: any, valueIsLiteral?: bool);
and: PredicateMethod;
static and: PredicateMethod;
@@ -481,14 +621,14 @@ declare module Breeze {
toFunction(): Function;
toString(): string;
- validate(entityType: EntityType): bool;
+ validate(entityType: EntityType): void;
}
interface PredicateMethod {
(predicates: Predicate[]): Predicate;
(...predicates: Predicate[]): Predicate;
- (property: string, operator: string, value: any): Predicate;
- (property: string, operator: FilterQueryOp, value: any): Predicate;
+ (property: string, operator: string, value: any, valueIsLiteral?: bool): Predicate;
+ (property: string, operator: FilterQueryOpSymbol, value: any, valueIsLiteral?: bool): Predicate;
}
class Promise {
@@ -499,20 +639,20 @@ declare module Breeze {
class QueryOptions {
static defaultInstance: QueryOptions;
- fetchStrategy: FetchStrategy;
- mergeStrategy: MergeStrategy;
+ fetchStrategy: FetchStrategySymbol;
+ mergeStrategy: MergeStrategySymbol;
constructor (config?: QueryOptionsConfiguration);
setAsDefault(): void;
using(config: QueryOptionsConfiguration): QueryOptions;
- using(config: MergeStrategy): QueryOptions;
- // using(config: FetchStrategy): QueryOptions; !!! same signature as MergeStrategy
+ using(config: MergeStrategySymbol): QueryOptions;
+ using(config: FetchStrategySymbol): QueryOptions;
}
interface QueryOptionsConfiguration {
- fetchStrategy?: FetchStrategy;
- mergeStrategy?: MergeStrategy;
+ fetchStrategy?: FetchStrategySymbol;
+ mergeStrategy?: MergeStrategySymbol;
}
class SaveOptions {
@@ -527,7 +667,8 @@ declare module Breeze {
class ValidationError {
context: any;
errorMessage: string;
- property: any; // DataProperty | NavigationProperty
+ property: IProperty;
+ propertyName: string;
validator: Validator;
constructor (validator: Validator, context: any, errorMessage: string);
@@ -561,6 +702,7 @@ declare module Breeze {
static bool(): Validator;
static byte(): Validator;
static date(): Validator;
+ static duration(): Validator;
getMessage(): string;
static guid(): Validator;
static int16(): Validator;
@@ -571,6 +713,7 @@ declare module Breeze {
static required(): Validator;
static string(): Validator;
static stringLength(context: { maxLength: number; minLength: number; }): Validator;
+ validate(value: any, context?: any): ValidationError;
}
interface ValidatorFunction {
diff --git a/i18next/i18next.d.ts b/i18next/i18next.d.ts
new file mode 100644
index 000000000..572f74a77
--- /dev/null
+++ b/i18next/i18next.d.ts
@@ -0,0 +1,127 @@
+///
+
+// Type definitions for i18next (v1.5.10 incl. jQuery)
+// Project: http://i18next.com
+// Sources: https://github.com/jamuhl/i18next/
+// Definitions by: Maarten Docter - Blog: http://www.maartendocter.nl
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+interface IResourceStore {
+ [language: string]: IResourceStoreLanguage;
+}
+interface IResourceStoreLanguage {
+ [namespace: string]: IResourceStoreKey;
+}
+interface IResourceStoreKey {
+ [key: string];
+}
+
+interface I18nextOptions {
+ lng?: string; // Default value: undefined
+ load?: string; // Default value: 'all'
+ preload?: string[]; // Default value: []
+ lowerCaseLng?: bool; // Default value: false
+ returnObjectTrees?: bool; // Default value: false
+ fallbackLng?: string; // Default value: 'dev'
+ detectLngQS?: string; // Default value: 'setLng'
+ ns?: any; // Default value: 'translation' (string), can also be an object
+ nsseparator?: string; // Default value: '::'
+ keyseparator?: string; // Default value: '.'
+ selectorAttr?: string; // Default value: 'data-i18n'
+ debug?: bool; // Default value: false
+
+ resGetPath?: string; // Default value: 'locales/__lng__/__ns__.json'
+ resPostPath?: string; // Default value: 'locales/add/__lng__/__ns__'
+
+ getAsync?: bool; // Default value: true
+ postAsync?: bool; // Default value: true
+
+ resStore?: IResourceStore; // Default value: undefined
+ useLocalStorage?: bool; // Default value: false
+ localStorageExpirationTime?: number; // Default value: 7 * 24 * 60 * 60 * 1000 (in ms default one week)
+
+ dynamicLoad?: bool; // Default value: false
+ sendMissing?: bool; // Default value: false
+ sendMissingTo?: string; // Default value: 'fallback'. Other options are: current | all
+ sendType?: string; // Default value: 'POST'
+
+ interpolationPrefix?: string; // Default value: '__'
+ interpolationSuffix?: string; // Default value: '__'
+ reusePrefix?: string; // Default value: '$t('
+ reuseSuffix?: string; // Default value: ')'
+ pluralSuffix?: string; // Default value: '_plural'
+ pluralNotFound?: string; // Default value: ['plural_not_found' Math.random()].join( '' )
+ contextNotFound?: string; // Default value: ['context_not_found' Math.random()].join( '' )
+
+ setJqueryExt?: bool; // Default value: true
+ defaultValueFromContent?: bool; // Default value: true
+ useDataAttrOptions?: bool; // Default value: false
+ cookieExpirationTime?: number; // Default value: undefined
+ useCookie?: bool; // Default value: true
+ cookieName?: string; // Default value: 'i18next'
+
+ postProcess?: string; // Default value: undefined
+}
+
+interface I18nextStatic {
+
+ addPostProcessor(name: string, fn: (value: any, key: string, options: any) => string): void;
+ detectLanguage(): string;
+ functions: {
+ extend(target: any, ...objs: any[]): Object;
+ extend(deep: bool, target: any, ...objs: any[]): Object;
+ each(collection: any, callback: (indexInArray: any, valueOfElement: any) => any): any;
+ ajax(settings: JQueryAjaxSettings): JQueryXHR;
+ ajax(url: string, settings?: JQueryAjaxSettings): JQueryXHR;
+ cookie: {
+ create: (name: string, value: string, minutes: number) => void;
+ read: (name: string) => string;
+ remove: (name: string) => void;
+ };
+ detectLanguage(): string;
+ log(message: string);
+ toLanguages(language: string): string[];
+ regexEscape(str: string): string;
+ };
+ init(callback?: (t: (key: string, options?: any) => string) => void ): JQueryDeferred;
+ init(options?: I18nextOptions, callback?: (t: (key: string, options?: any) => string) => void ): JQueryDeferred;
+ lng(): string;
+ loadNamespace(namespace: string, callback?: () => void ): void;
+ loadNamespaces(namespaces: string[], callback?: () => void ): void;
+ pluralExtensions: {
+ addRule(language: string, obj: {
+ name: string;
+ numbers: number[];
+ plurals: (n: number) => number;
+ });
+ get (language: string, count: number): number;
+ rules: any;
+ setCurrentLng: (language: string) => void;
+ };
+ preload(language: string, callback?: (t: (key: string, options?: any) => string) => void ): void;
+ preload(languages: string[], callback?: (t: (key: string, options?: any) => string) => void ): void;
+ setDefaultNamespace(namespace: string): void;
+ setLng(language: string, callback?: (t: (key: string, options?: any) => string) => void ): void;
+ sync: {
+ load: (languages: string[], options: I18nextOptions, callback: (err: Error, store: IResourceStore) => void ) => void;
+ postMissing: (language: string, namespace: string, key: string, defaultValue: any, languages: string[]) => void;
+ };
+ t(key: string, options?: any): string;
+ translate(key: string, options?: any): string;
+}
+
+// jQuery extensions
+interface JQueryStatic {
+ i18n: I18nextStatic;
+ t: (key: string, options?: any) => string;
+}
+
+interface JQuery {
+ /* Note: options are same options as used by the translate function. Alternatively by
+ setting init option or translation option 'useDataAttrOptions = true' the Options
+ for translation will be read and cached in the elements data-i18n-options attribute.
+ */
+ i18n: (options?: I18nextOptions) => void;
+}
+
+declare var i18next: I18nextStatic;
\ No newline at end of file
diff --git a/i18next/lib/jquery.d.ts b/i18next/lib/jquery.d.ts
new file mode 100644
index 000000000..25e2aa626
--- /dev/null
+++ b/i18next/lib/jquery.d.ts
@@ -0,0 +1,758 @@
+/* *****************************************************************************
+Copyright (c) Microsoft Corporation. All rights reserved.
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+this file except in compliance with the License. You may obtain a copy of the
+License at http://www.apache.org/licenses/LICENSE-2.0
+
+THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+MERCHANTABLITY OR NON-INFRINGEMENT.
+
+See the Apache Version 2.0 License for specific language governing permissions
+and limitations under the License.
+***************************************************************************** */
+
+// Typing for the jQuery library, version 1.7.x
+
+/*
+ Interface for the AJAX setting that will configure the AJAX request
+*/
+interface JQueryAjaxSettings {
+ accepts?: any;
+ async?: bool;
+ beforeSend?(jqXHR: JQueryXHR, settings: JQueryAjaxSettings);
+ cache?: bool;
+ complete?(jqXHR: JQueryXHR, textStatus: string);
+ contents?: { [key: string]: any; };
+ contentType?: string;
+ context?: any;
+ converters?: { [key: string]: any; };
+ crossDomain?: bool;
+ data?: any;
+ dataFilter?(data: any, ty: any): any;
+ dataType?: string;
+ error?(jqXHR: JQueryXHR, textStatus: string, errorThrow: string): any;
+ global?: bool;
+ headers?: { [key: string]: any; };
+ ifModified?: bool;
+ isLocal?: bool;
+ jsonp?: string;
+ jsonpCallback?: any;
+ mimeType?: string;
+ password?: string;
+ processData?: bool;
+ scriptCharset?: string;
+ statusCode?: { [key: string]: any; };
+ success?(data: any, textStatus: string, jqXHR: JQueryXHR);
+ timeout?: number;
+ traditional?: bool;
+ type?: string;
+ url?: string;
+ username?: string;
+ xhr?: any;
+ xhrFields?: { [key: string]: any; };
+}
+
+/*
+ Interface for the jqXHR object
+*/
+interface JQueryXHR extends XMLHttpRequest, JQueryPromise {
+ overrideMimeType(mimeType: string);
+}
+
+/*
+ Interface for the JQuery callback
+*/
+interface JQueryCallback {
+ add(...callbacks: any[]): any;
+ disable(): any;
+ empty(): any;
+ fire(...arguments: any[]): any;
+ fired(): bool;
+ fireWith(context: any, ...args: any[]): any;
+ has(callback: any): bool;
+ lock(): any;
+ locked(): bool;
+ remove(...callbacks: any[]): any;
+}
+
+/*
+ Interface for the JQuery promise, part of callbacks
+*/
+interface JQueryPromise {
+ always(...alwaysCallbacks: any[]): JQueryDeferred;
+ done(...doneCallbacks: any[]): JQueryDeferred;
+ fail(...failCallbacks: any[]): JQueryDeferred;
+ progress(...progressCallbacks: any[]): JQueryDeferred;
+ state(): string;
+ pipe(doneFilter?: (...args: any[]) => any, failFilter?: (...args: any[]) => any, progressFilter?: (...args: any[]) => any): JQueryPromise;
+ then(doneCallbacks: any, failCallbacks: any, progressCallbacks?: any): JQueryDeferred;
+}
+
+/*
+ Interface for the JQuery deferred, part of callbacks
+*/
+interface JQueryDeferred extends JQueryPromise {
+ notify(...args: any[]): JQueryDeferred;
+ notifyWith(context: any, ...args: any[]): JQueryDeferred;
+
+ pipe(doneFilter?: any, failFilter?: any, progressFilter?: any): JQueryPromise;
+ progress(...progressCallbacks: any[]): JQueryDeferred;
+ promise(target? ): JQueryDeferred;
+ reject(...args: any[]): JQueryDeferred;
+ rejectWith(context:any, ...args: any[]): JQueryDeferred;
+ resolve(...args: any[]): JQueryDeferred;
+ resolveWith(context:any, ...args: any[]): JQueryDeferred;
+ state(): string;
+ then(doneCallbacks: any, failCallbacks: any, progressCallbacks?: any): JQueryDeferred;
+}
+
+/*
+ Interface of the JQuery extension of the W3C event object
+*/
+interface JQueryEventObject extends Event {
+ data: any;
+ delegateTarget: Element;
+ isDefaultPrevented(): bool;
+ isImmediatePropogationStopped(): bool;
+ isPropogationStopped(): bool;
+ namespace: string;
+ preventDefault(): any;
+ relatedTarget: Element;
+ result: any;
+ stopImmediatePropagation();
+ stopPropagation();
+ pageX: number;
+ pageY: number;
+ which: number;
+ metaKey: any;
+}
+
+/*
+ Collection of properties of the current browser
+*/
+interface JQueryBrowserInfo {
+ safari:bool;
+ opera:bool;
+ msie:bool;
+ mozilla:bool;
+ webkit:bool;
+ version:string;
+}
+
+interface JQuerySupport {
+ ajax?: bool;
+ boxModel?: bool;
+ changeBubbles?: bool;
+ checkClone?: bool;
+ checkOn?: bool;
+ cors?: bool;
+ cssFloat?: bool;
+ hrefNormalized?: bool;
+ htmlSerialize?: bool;
+ leadingWhitespace?: bool;
+ noCloneChecked?: bool;
+ noCloneEvent?: bool;
+ opacity?: bool;
+ optDisabled?: bool;
+ optSelected?: bool;
+ scriptEval?(): bool;
+ style?: bool;
+ submitBubbles?: bool;
+ tbody?: bool;
+}
+
+/*
+ Static members of jQuery (those on $ and jQuery themselves)
+*/
+interface JQueryStatic {
+
+ /****
+ AJAX
+ *****/
+ ajax(settings: JQueryAjaxSettings): JQueryXHR;
+ ajax(url: string, settings?: JQueryAjaxSettings): JQueryXHR;
+
+ ajaxPrefilter(dataTypes: string, handler: (opts: any, originalOpts: any, jqXHR: JQueryXHR) => any): any;
+ ajaxPrefilter(handler: (opts: any, originalOpts: any, jqXHR: JQueryXHR) => any): any;
+
+ ajaxSettings: JQueryAjaxSettings;
+
+ ajaxSetup(options: any);
+
+ get(url: string, data?: any, success?: any, dataType?: any): JQueryXHR;
+ getJSON(url: string, data?: any, success?: any): JQueryXHR;
+ getScript(url: string, success?: any): JQueryXHR;
+
+ param(obj: any): string;
+ param(obj: any, traditional: bool): string;
+
+ post(url: string, data?: any, success?: any, dataType?: any): JQueryXHR;
+
+ /*********
+ CALLBACKS
+ **********/
+ Callbacks(flags?: string): JQueryCallback;
+
+ /****
+ CORE
+ *****/
+ holdReady(hold: bool): any;
+
+ (selector: string, context?: any): JQuery;
+ (element: Element): JQuery;
+ (object: { }): JQuery;
+ (elementArray: Element[]): JQuery;
+ (object: JQuery): JQuery;
+ (func: Function): JQuery;
+ (array: any[]): JQuery;
+ (): JQuery;
+
+ noConflict(removeAll?: bool): Object;
+
+ when(...deferreds: any[]): JQueryPromise;
+
+ /***
+ CSS
+ ****/
+ css(e: any, propertyName: string, value?: any);
+ css(e: any, propertyName: any, value?: any);
+ cssHooks: { [key: string]: any; };
+ cssNumber: any;
+
+ /****
+ DATA
+ *****/
+ data(element: Element, key: string, value: any): any;
+ data(element: Element, key: string): any;
+ data(element: Element): any;
+
+ dequeue(element: Element, queueName?: string): any;
+
+ hasData(element: Element): bool;
+
+ queue(element: Element, queueName?: string): any[];
+ queue(element: Element, queueName: string, newQueueOrCallback: any): JQuery;
+
+ removeData(element: Element, name?: string): JQuery;
+
+ /*******
+ EFFECTS
+ ********/
+ fx: { tick: () => void; interval: number; stop: () => void; speeds: { slow: number; fast: number; }; off: bool; step: any; };
+
+ /******
+ EVENTS
+ *******/
+ proxy(fn: Function, context: any): any;
+ proxy(context: any, name: any): any;
+ Deferred(): JQueryDeferred;
+
+ /*********
+ INTERNALS
+ **********/
+ error(message: any);
+
+ /*************
+ MISCELLANEOUS
+ **************/
+ expr: any;
+ fn: any; //TODO: Decide how we want to type this
+ isReady: bool;
+
+ /**********
+ PROPERTIES
+ ***********/
+ browser: JQueryBrowserInfo;
+ support: JQuerySupport;
+
+ /*********
+ UTILITIES
+ **********/
+ contains(container: Element, contained: Element): bool;
+
+ each(collection: any, callback: (indexInArray: any, valueOfElement: any) => any): any;
+
+ extend(target: any, ...objs: any[]): Object;
+ extend(deep: bool, target: any, ...objs: any[]): Object;
+
+ globalEval(code: string): any;
+
+ grep(array: any[], func: any, invert?: bool): any[];
+
+ inArray(value: any, array: any[], fromIndex?: number): number;
+
+ isArray(obj: any): bool;
+ isEmptyObject(obj: any): bool;
+ isFunction(obj: any): bool;
+ isNumeric(value: any): bool;
+ isPlainObject(obj: any): bool;
+ isWindow(obj: any): bool;
+ isXMLDoc(node: Node): bool;
+
+ makeArray(obj: any): any[];
+
+ map(array: any[], callback: (elementOfArray: any, indexInArray: any) =>any): any[];
+
+ merge(first: any[], second: any[]): any[];
+
+ noop(): any;
+
+ now(): number;
+
+ parseJSON(json: string): Object;
+
+ //FIXME: This should return an XMLDocument
+ parseXML(data: string): any;
+
+ queue(element: Element, queueName: string, newQueue: any[]): JQuery;
+
+ trim(str: string): string;
+
+ type(obj: any): string;
+
+ unique(arr: any[]): any[];
+}
+
+/*
+ The jQuery instance members
+*/
+interface JQuery {
+ /****
+ AJAX
+ *****/
+ ajaxComplete(handler: any): JQuery;
+ ajaxError(handler: (event: any, jqXHR: any, settings: any, exception: any) => any): JQuery;
+ ajaxSend(handler: (event: any, jqXHR: any, settings: any, exception: any) => any): JQuery;
+ ajaxStart(handler: () => any): JQuery;
+ ajaxStop(handler: () => any): JQuery;
+ ajaxSuccess(handler: (event: any, jqXHR: any, settings: any, exception: any) => any): JQuery;
+
+ load(url: string, data?: any, complete?: any): JQuery;
+
+ serialize(): string;
+ serializeArray(): any[];
+
+ /**********
+ ATTRIBUTES
+ ***********/
+ addClass(classNames: string): JQuery;
+ addClass(func: (index: any, currentClass: any) => string): JQuery;
+
+ attr(attributeName: string): string;
+ attr(attributeName: string, value: any): JQuery;
+ attr(map: { [key: string]: any; }): JQuery;
+ attr(attributeName: string, func: (index: any, attr: any) => any): JQuery;
+
+ hasClass(className: string): bool;
+
+ html(): string;
+ html(htmlString: string): JQuery;
+ html(htmlContent: (index: number, oldhtml: string) => string): JQuery;
+
+ prop(propertyName: string): any;
+ prop(propertyName: string, value: any): JQuery;
+ prop(map: any): JQuery;
+ prop(propertyName: string, func: (index: any, oldPropertyValue: any) => any): JQuery;
+
+ removeAttr(attributeName: any): JQuery;
+
+ removeClass(className?: any): JQuery;
+ removeClass(func: (index: any, cls: any) => any): JQuery;
+
+ removeProp(propertyName: any): JQuery;
+
+ toggleClass(className: any, swtch?: bool): JQuery;
+ toggleClass(swtch?: bool): JQuery;
+ toggleClass(func: (index: any, cls: any, swtch: any) => any): JQuery;
+
+ val(): any;
+ val(value: string[]): JQuery;
+ val(value: string): JQuery;
+ val(value: number): JQuery;
+ val(func: (index: any, value: any) => any): JQuery;
+
+ /***
+ CSS
+ ****/
+ css(propertyName: string, value?: any): any;
+ css(propertyName: any, value?: any): any;
+
+ height(): number;
+ height(value: number): JQuery;
+ height(value: string): JQuery;
+ height(func: (index: any, height: any) => any): JQuery;
+
+ innerHeight(): number;
+ innerWidth(): number;
+
+ offset(): { left: number; top: number; };
+ offset(coordinates: any): JQuery;
+ offset(func: (index: any, coords: any) => any): JQuery;
+
+ outerHeight(includeMargin?: bool): number;
+ outerWidth(includeMargin?: bool): number;
+
+ position(): { top: number; left: number; };
+
+ scrollLeft(): number;
+ scrollLeft(value: number): JQuery;
+
+ scrollTop(): number;
+ scrollTop(value: number): JQuery;
+
+ width(): number;
+ width(value: number): JQuery;
+ width(value: string): JQuery;
+ width(func: (index: any, height: any) => any): JQuery;
+
+ /****
+ DATA
+ *****/
+ clearQueue(queueName?: string): JQuery;
+
+ data(key: string, value: any): JQuery;
+ data(obj: { [key: string]: any; }): JQuery;
+ data(key?: string): any;
+
+ dequeue(queueName?: string): JQuery;
+
+ removeData(nameOrList?: any): JQuery;
+
+ /********
+ DEFERRED
+ *********/
+ promise(type?: any, target?: any): JQueryPromise;
+
+ /*******
+ EFFECTS
+ ********/
+ animate(properties: any, duration?: any, complete?: Function): JQuery;
+ animate(properties: any, duration?: any, easing?: string, complete?: Function): JQuery;
+ animate(properties: any, options: { duration?: any; easing?: string; complete?: Function; step?: Function; queue?: bool; specialEasing?: any; });
+
+ delay(duration: number, queueName?: string): JQuery;
+
+ fadeIn(duration?: any, callback?: any): JQuery;
+ fadeIn(duration?: any, easing?: string, callback?: any): JQuery;
+
+ fadeOut(duration?: any, callback?: any): JQuery;
+ fadeOut(duration?: any, easing?: string, callback?: any): JQuery;
+
+ fadeTo(duration: any, opacity: number, callback?: any): JQuery;
+ fadeTo(duration: any, opacity: number, easing?: string, callback?: any): JQuery;
+
+ fadeToggle(duration?: any, callback?: any): JQuery;
+ fadeToggle(duration?: any, easing?: string, callback?: any): JQuery;
+
+ hide(duration?: any, callback?: any): JQuery;
+ hide(duration?: any, easing?: string, callback?: any): JQuery;
+
+ show(duration?: any, callback?: any): JQuery;
+ show(duration?: any, easing?: string, callback?: any): JQuery;
+
+ slideDown(duration?: any, callback?: any): JQuery;
+ slideDown(duration?: any, easing?: string, callback?: any): JQuery;
+
+ slideToggle(duration?: any, callback?: any): JQuery;
+ slideToggle(duration?: any, easing?: string, callback?: any): JQuery;
+
+ slideUp(duration?: any, callback?: any): JQuery;
+ slideUp(duration?: any, easing?: string, callback?: any): JQuery;
+
+ stop(clearQueue?: bool, jumpToEnd?: bool): JQuery;
+ stop(queue?:any, clearQueue?: bool, jumpToEnd?: bool): JQuery;
+
+ toggle(duration?: any, callback?: any): JQuery;
+ toggle(duration?: any, easing?: string, callback?: any): JQuery;
+ toggle(showOrHide: bool): JQuery;
+
+ /******
+ EVENTS
+ *******/
+ bind(eventType: string, eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ bind(eventType: string, eventData: any, preventBubble:bool): JQuery;
+ bind(eventType: string, preventBubble:bool): JQuery;
+ bind(...events: any[]);
+
+ blur(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ blur(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ change(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ change(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ click(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ click(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ dblclick(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ dblclick(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ delegate(selector: any, eventType: string, handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ focus(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ focus(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ focusin(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
+ focusin(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ focusout(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
+ focusout(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ hover(handlerIn: (eventObject: JQueryEventObject) => any, handlerOut: (eventObject: JQueryEventObject) => any): JQuery;
+ hover(handlerInOut: (eventObject: JQueryEventObject) => any): JQuery;
+
+ keydown(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ keydown(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ keypress(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ keypress(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ keyup(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ keyup(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ load(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ load(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ mousedown(): JQuery;
+ mousedown(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
+ mousedown(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ mouseevent(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
+ mouseevent(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ mouseenter(): JQuery;
+ mouseenter(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
+ mouseenter(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ mouseleave(): JQuery;
+ mouseleave(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
+ mouseleave(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ mousemove(): JQuery;
+ mousemove(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
+ mousemove(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ mouseout(): JQuery;
+ mouseout(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
+ mouseout(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ mouseover(): JQuery;
+ mouseover(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
+ mouseover(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ mouseup(): JQuery;
+ mouseup(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
+ mouseup(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ off(events?: string, selector?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ off(eventsMap: { [key: string]: any; }, selector?: any): JQuery;
+
+ on(events: string, selector?: any, data?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ on(eventsMap: { [key: string]: any; }, selector?: any, data?: any): JQuery;
+
+ one(events: string, selector?: any, data?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ one(eventsMap: { [key: string]: any; }, selector?: any, data?: any): JQuery;
+
+ ready(handler: any): JQuery;
+
+ resize(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ resize(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ scroll(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ scroll(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ select(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ select(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ submit(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ submit(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ trigger(eventType: string, ...extraParameters: any[]): JQuery;
+ trigger(event: JQueryEventObject): JQuery;
+
+ triggerHandler(eventType: string, ...extraParameters: any[]): Object;
+
+ unbind(eventType?: string, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ unbind(eventType: string, fls: bool): JQuery;
+ unbind(evt: any): JQuery;
+
+ undelegate(): JQuery;
+ undelegate(selector: any, eventType: string, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ undelegate(selector: any, events: any): JQuery;
+ undelegate(namespace: string): JQuery;
+
+ unload(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
+ unload(handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ /*********
+ INTERNALS
+ **********/
+
+ context: Element;
+ jquery: string;
+
+ error(handler: (eventObject: JQueryEventObject) => any): JQuery;
+ error(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
+
+ pushStack(elements: any[]): JQuery;
+ pushStack(elements: any[], name: any, arguments: any): JQuery;
+
+ /************
+ MANIPULATION
+ *************/
+ after(...content: any[]): JQuery;
+ after(func: (index: any) => any);
+
+ append(...content: any[]): JQuery;
+ append(func: (index: any, html: any) => any);
+
+ appendTo(target: any): JQuery;
+
+ before(...content: any[]): JQuery;
+ before(func: (index: any) => any);
+
+ clone(withDataAndEvents?: bool, deepWithDataAndEvents?: bool): JQuery;
+
+ detach(selector?: any): JQuery;
+
+ empty(): JQuery;
+
+ insertAfter(target: any): JQuery;
+ insertBefore(target: any): JQuery;
+
+ prepend(...content: any[]): JQuery;
+ prepend(func: (index: any, html: any) =>any): JQuery;
+
+ prependTo(target: any): JQuery;
+
+ remove(selector?: any): JQuery;
+
+ replaceAll(target: any): JQuery;
+
+ replaceWith(func: any): JQuery;
+
+ text(): string;
+ text(textString: any): JQuery;
+ text(textString: (index: number, text: string) => string): JQuery;
+
+ toArray(): any[];
+
+ unwrap(): JQuery;
+
+ wrap(wrappingElement: any): JQuery;
+ wrap(func: (index: any) =>any): JQuery;
+
+ wrapAll(wrappingElement: any): JQuery;
+
+ wrapInner(wrappingElement: any): JQuery;
+ wrapInner(func: (index: any) =>any): JQuery;
+
+ /*************
+ MISCELLANEOUS
+ **************/
+ each(func: (index: any, elem: Element) => any);
+
+ get(index?: number): any;
+
+ index(): number;
+ index(selector: string): number;
+ index(element: any): number;
+
+ /**********
+ PROPERTIES
+ ***********/
+ length: number;
+ [x: string]: HTMLElement;
+ [x: number]: HTMLElement;
+
+ /**********
+ TRAVERSING
+ ***********/
+ add(selector: string, context?: any): JQuery;
+ add(...elements: any[]): JQuery;
+ add(html: string): JQuery;
+ add(obj: JQuery): JQuery;
+
+ andSelf(): JQuery;
+
+ children(selector?: any): JQuery;
+
+ closest(selector: string): JQuery;
+ closest(selector: string, context?: Element): JQuery;
+ closest(obj: JQuery): JQuery;
+ closest(element: any): JQuery;
+ closest(selectors: any, context?: Element): any[];
+
+ contents(): JQuery;
+
+ end(): JQuery;
+
+ eq(index: number): JQuery;
+
+ filter(selector: string): JQuery;
+ filter(func: (index: any) =>any): JQuery;
+ filter(element: any): JQuery;
+ filter(obj: JQuery): JQuery;
+
+ find(selector: string): JQuery;
+ find(element: any): JQuery;
+ find(obj: JQuery): JQuery;
+
+ first(): JQuery;
+
+ has(selector: string): JQuery;
+ has(contained: Element): JQuery;
+
+ is(selector: string): bool;
+ is(func: (index: any) =>any): bool;
+ is(element: any): bool;
+ is(obj: JQuery): bool;
+
+ last(): JQuery;
+
+ map(callback: (index: any, domElement: Element) =>any): JQuery;
+
+ next(selector?: string): JQuery;
+
+ nextAll(selector?: string): JQuery;
+
+ nextUntil(selector?: string, filter?: string): JQuery;
+ nextUntil(element?: Element, filter?: string): JQuery;
+
+ not(selector: string): JQuery;
+ not(func: (index: any) =>any): JQuery;
+ not(element: any): JQuery;
+ not(obj: JQuery): JQuery;
+
+ offsetParent(): JQuery;
+
+ parent(selector?: string): JQuery;
+
+ parents(selector?: string): JQuery;
+
+ parentsUntil(selector?: string, filter?: string): JQuery;
+ parentsUntil(element?: Element, filter?: string): JQuery;
+
+ prev(selector?: string): JQuery;
+
+ prevAll(selector?: string): JQuery;
+
+ prevUntil(selector?: string, filter?:string): JQuery;
+ prevUntil(element?: Element, filter?:string): JQuery;
+
+ siblings(selector?: string): JQuery;
+
+ slice(start: number, end?: number): JQuery;
+
+ /*********
+ UTILITIES
+ **********/
+
+ queue(queueName?: string): any[];
+ queue(queueName: string, newQueueOrCallback: any): JQuery;
+ queue(newQueueOrCallback: any): JQuery;
+}
+
+declare var jQuery: JQueryStatic;
+declare var $: JQueryStatic;
diff --git a/i18next/lib/mocha.d.ts b/i18next/lib/mocha.d.ts
new file mode 100644
index 000000000..ee31e689d
--- /dev/null
+++ b/i18next/lib/mocha.d.ts
@@ -0,0 +1,44 @@
+// BDD
+declare function describe(cb: () => void);
+declare function describe(cb: (done:() => void) => void);
+declare function describe(title: string, cb: () => void);
+declare function describe(title: string, cb: (done:() => void) => void);
+
+declare function it(cb: () => void);
+declare function it(cb: (done:() => void) => void);
+declare function it(title: string, cb: () => void);
+declare function it(title: string, cb: (done:() => void) => void);
+
+declare function before(cb: () => void);
+declare function before(cb: (done:() => void) => void);
+declare function before(title: string, cb: () => void);
+declare function before(title: string, cb: (done:() => void) => void);
+
+declare function after(cb: () => void);
+declare function after(cb: (done:() => void) => void);
+declare function after(title: string, cb: () => void);
+declare function after(title: string, cb: (done:() => void) => void);
+
+declare function beforeEach(cb: () => void);
+declare function beforeEach(cb: (done:() => void) => void);
+declare function beforeEach(title: string, cb: () => void);
+declare function beforeEach(title: string, cb: (done:() => void) => void);
+
+declare function afterEach(cb: () => void);
+declare function afterEach(cb: (done:() => void) => void);
+declare function afterEach(title: string, cb: () => void);
+declare function afterEach(title: string, cb: (done:() => void) => void);
+
+
+// TDD
+declare function suite(title: string, cb: () => void);
+declare function test(title: string, cb: () => void);
+declare function test(title: string, cb: (done:() => void) => void);
+declare function setup(title: string, cb: () => void);
+declare function teardown(title: string, cb: () => void);
+
+declare function suite(cb: () => void);
+declare function test(cb: () => void);
+declare function test(cb: (done:() => void) => void);
+declare function setup(cb: () => void);
+declare function teardown(cb: () => void);
diff --git a/i18next/lib/sinon.d.ts b/i18next/lib/sinon.d.ts
new file mode 100644
index 000000000..25198e3b3
--- /dev/null
+++ b/i18next/lib/sinon.d.ts
@@ -0,0 +1,33 @@
+///
+
+interface spy {
+ called: bool;
+ getCall(x: number): any;
+ fakeServer: ISinonFakeServer;
+ calledOnce: bool;
+ calledWith(x: any, message: string): bool;
+}
+
+interface IJsonReponse {
+ responseCode: number;
+ responseHeaders: any;
+ responseString: string;
+}
+
+interface ISinonFakeServer {
+ create(): any;
+ restore(): void;
+ respondWith(postType: string, relativeUrl: string, x: any): any;
+ respond(): any;
+}
+
+declare module sinon {
+ export function spy(): spy;
+ export function spy(fn: Function): spy;
+ //export function spy(jquery: JQueryStatic , x: string): spy;
+ export function spy(jquery: JQueryStatic , x: any): spy;
+ export function spy(obj: Object , methodName: string): spy;
+ export var fakeServer: ISinonFakeServer;
+ export function stub(x: any, name: string);
+ export function useFakeTimers(): void;
+}
\ No newline at end of file
diff --git a/i18next/tests/i18next.d.tests.ts b/i18next/tests/i18next.d.tests.ts
new file mode 100644
index 000000000..f4ed24349
--- /dev/null
+++ b/i18next/tests/i18next.d.tests.ts
@@ -0,0 +1,1359 @@
+///
+///
+///
+///
+
+// declarations for expect.js
+declare var expect: (actual: string) => any;
+declare var expect: (actual: number) => any;
+
+// declarations for jsfixtures.js
+declare var setFixtures: (html) => void;
+
+describe('i18next', function () {
+
+ var i18n = $.i18n
+ , opts: I18nextOptions;
+
+ beforeEach(function () {
+ opts = {
+ lng: 'en-US',
+ load: 'all',
+ fallbackLng: 'dev',
+ preload: [],
+ lowerCaseLng: false,
+ ns: 'translation',
+ resGetPath: 'locales/__lng__/__ns__.json',
+ dynamicLoad: false,
+ useLocalStorage: false,
+ sendMissing: false,
+ resStore: false,
+ getAsync: true,
+ returnObjectTrees: false,
+ debug: true,
+ selectorAttr: 'data-i18n',
+ postProcess: '',
+ interpolationPrefix: '__',
+ interpolationSuffix: '__'
+ };
+ });
+
+
+ describe('Initialisation', function () {
+
+ describe('with passed in resource set', function () {
+
+ var resStore = {
+ dev: { translation: { 'simple_dev': 'ok_from_dev' } },
+ en: { translation: { 'simple_en': 'ok_from_en' } },
+ 'en-US': { translation: { 'simple_en-US': 'ok_from_en-US' } }
+ };
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, { resStore: resStore }),
+ function (t) { done(); });
+ });
+
+ it('it should provide passed in resources for translation', function () {
+ expect(i18n.t('simple_en-US')).to.be('ok_from_en-US');
+ expect(i18n.t('simple_en')).to.be('ok_from_en');
+ expect(i18n.t('simple_dev')).to.be('ok_from_dev');
+ });
+
+ });
+
+ describe('loading from server', function () {
+
+ describe('with static route', function () {
+
+ beforeEach(function (done) {
+ i18n.init(opts, function (t) { done(); });
+ });
+
+ it('it should provide loaded resources for translation', function () {
+ expect(i18n.t('simple_en-US')).to.be('ok_from_en-US');
+ expect(i18n.t('simple_en')).to.be('ok_from_en');
+ expect(i18n.t('simple_dev')).to.be('ok_from_dev');
+ });
+
+ });
+
+ describe('with dynamic route', function () {
+
+ beforeEach(function (done) {
+
+ var res = {
+ dev: { translation: { 'simple_dev': 'ok_from_dev' } },
+ en: { translation: { 'simple_en': 'ok_from_en' } },
+ 'en-US': { translation: { 'simple_en-US': 'ok_from_en-US' } }
+ };
+
+ var server = sinon.fakeServer.create();
+ server.autoRespond = true;
+
+ server.respondWith([200, { "Content-Type": "application/json" }, JSON.stringify(res)]);
+
+ i18n.init($.extend(opts, {
+ resGetPath: 'locales/resources.json?lng=__lng__&ns=__ns__',
+ dynamicLoad: true
+ }),
+ function (t) { server.restore(); done(); });
+ });
+
+ it('it should provide loaded resources for translation', function () {
+ expect(i18n.t('simple_en-US')).to.be('ok_from_en-US');
+ expect(i18n.t('simple_en')).to.be('ok_from_en');
+ expect(i18n.t('simple_dev')).to.be('ok_from_dev');
+ });
+
+ });
+
+ });
+
+ describe('advanced initialisation options', function () {
+
+ describe('setting load', function () {
+
+ describe('to current', function () {
+
+ var spy;
+
+ beforeEach(function (done) {
+ spy = sinon.spy(i18n.sync, '_fetchOne');
+ i18n.init($.extend(opts, {
+ load: 'current'
+ }),
+ function (t) { done(); });
+ });
+
+ afterEach(function () {
+ spy.restore();
+ });
+
+ it('it should load only current and fallback language', function () {
+ expect(spy.callCount).to.be(2); // en-US, en
+ });
+
+ it('it should provide loaded resources for translation', function () {
+ expect(i18n.t('simple_en-US')).to.be('ok_from_en-US');
+ expect(i18n.t('simple_en')).not.to.be('ok_from_en');
+ expect(i18n.t('simple_dev')).to.be('ok_from_dev');
+ });
+
+ });
+
+ describe('to unspecific', function () {
+
+ var spy;
+
+ beforeEach(function (done) {
+ spy = sinon.spy(i18n.sync, '_fetchOne');
+ i18n.init($.extend(opts, {
+ load: 'unspecific'
+ }),
+ function (t) { done(); });
+ });
+
+ afterEach(function () {
+ spy.restore();
+ });
+
+ it('it should load only unspecific and fallback language', function () {
+ expect(spy.callCount).to.be(2); // en-US, en
+ });
+
+ it('it should provide loaded resources for translation', function () {
+ expect(i18n.t('simple_en-US')).not.to.be('ok_from_en-US');
+ expect(i18n.t('simple_en')).to.be('ok_from_en');
+ expect(i18n.t('simple_dev')).to.be('ok_from_dev');
+ });
+
+ it('it should return unspecific language', function () {
+ expect(i18n.lng()).to.be('en');
+ });
+
+ });
+
+ });
+
+ describe('with fallback language set to false', function () {
+
+ var spy;
+
+ beforeEach(function (done) {
+ spy = sinon.spy(i18n.sync, '_fetchOne');
+ i18n.init($.extend(opts, {
+ fallbackLng: false
+ }),
+ function (t) { done(); });
+ });
+
+ afterEach(function () {
+ spy.restore();
+ });
+
+ it('it should load only specific and unspecific languages', function () {
+ expect(spy.callCount).to.be(2); // en-US, en
+ });
+
+ it('it should provide loaded resources for translation', function () {
+ expect(i18n.t('simple_en-US')).to.be('ok_from_en-US');
+ expect(i18n.t('simple_en')).to.be('ok_from_en');
+ expect(i18n.t('simple_dev')).not.to.be('ok_from_dev');
+ });
+
+ });
+
+ describe('preloading multiple languages', function () {
+
+ var spy;
+
+ beforeEach(function (done) {
+ spy = sinon.spy(i18n.sync, '_fetchOne');
+ i18n.init($.extend(opts, {
+ preload: ['fr', 'de-DE']
+ }),
+ function (t) { done(); });
+ });
+
+ afterEach(function () {
+ spy.restore();
+ });
+
+ it('it should load additional languages', function () {
+ expect(spy.callCount).to.be(6); // en-US, en, de-DE, de, fr, dev
+ });
+
+ describe('changing the language', function () {
+
+ beforeEach(function (done) {
+ spy.reset();
+ i18n.setLng('de-DE',
+ function (t) { done(); });
+ });
+
+ it('it should reload the preloaded languages', function () {
+ expect(spy.callCount).to.be(4); // de-DE, de, fr, dev
+ });
+
+ });
+
+ });
+
+ describe('with synchronous flag', function () {
+
+ beforeEach(function () {
+ i18n.init($.extend(opts, { getAsync: false }));
+ });
+
+ it('it should provide loaded resources for translation', function () {
+ expect(i18n.t('simple_en-US')).to.be('ok_from_en-US');
+ expect(i18n.t('simple_en')).to.be('ok_from_en');
+ expect(i18n.t('simple_dev')).to.be('ok_from_dev');
+ });
+
+ });
+
+ describe('with namespace', function () {
+
+ describe('with one namespace set', function () {
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, { ns: 'ns.special' }),
+ function (t) { done(); });
+ });
+
+ it('it should provide loaded resources for translation', function () {
+ expect(i18n.t('simple_en-US')).to.be('ok_from_special_en-US');
+ expect(i18n.t('simple_en')).to.be('ok_from_special_en');
+ expect(i18n.t('simple_dev')).to.be('ok_from_special_dev');
+ });
+
+ });
+
+ describe('with more than one namespace set', function () {
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, { ns: { namespaces: ['ns.common', 'ns.special'], defaultNs: 'ns.special' } }),
+ function (t) { done(); });
+ });
+
+ it('it should provide loaded resources for translation', function () {
+ // default ns
+ expect(i18n.t('simple_en-US')).to.be('ok_from_special_en-US');
+ expect(i18n.t('simple_en')).to.be('ok_from_special_en');
+ expect(i18n.t('simple_dev')).to.be('ok_from_special_dev');
+
+ // ns prefix
+ expect(i18n.t('ns.common:simple_en-US')).to.be('ok_from_common_en-US');
+ expect(i18n.t('ns.common:simple_en')).to.be('ok_from_common_en');
+ expect(i18n.t('ns.common:simple_dev')).to.be('ok_from_common_dev');
+
+ // ns in options
+ expect(i18n.t('simple_en-US', { ns: 'ns.common' })).to.be('ok_from_common_en-US');
+ expect(i18n.t('simple_en', { ns: 'ns.common' })).to.be('ok_from_common_en');
+ expect(i18n.t('simple_dev', { ns: 'ns.common' })).to.be('ok_from_common_dev');
+ });
+
+ });
+
+ describe('with reloading additional namespace', function () {
+
+ describe('without using localStorage', function () {
+ beforeEach(function (done) {
+ i18n.init(opts,
+ function (t) {
+ i18n.setDefaultNamespace('ns.special');
+ i18n.loadNamespaces(['ns.common', 'ns.special'], done);
+ });
+ });
+
+ it('it should provide loaded resources for translation', function () {
+ // default ns
+ expect(i18n.t('simple_en-US')).to.be('ok_from_special_en-US');
+ expect(i18n.t('simple_en')).to.be('ok_from_special_en');
+ expect(i18n.t('simple_dev')).to.be('ok_from_special_dev');
+
+ // ns prefix
+ expect(i18n.t('ns.common:simple_en-US')).to.be('ok_from_common_en-US');
+ expect(i18n.t('ns.common:simple_en')).to.be('ok_from_common_en');
+ expect(i18n.t('ns.common:simple_dev')).to.be('ok_from_common_dev');
+
+ // ns in options
+ expect(i18n.t('simple_en-US', { ns: 'ns.common' })).to.be('ok_from_common_en-US');
+ expect(i18n.t('simple_en', { ns: 'ns.common' })).to.be('ok_from_common_en');
+ expect(i18n.t('simple_dev', { ns: 'ns.common' })).to.be('ok_from_common_dev');
+ });
+
+ });
+
+ describe('with using localStorage', function () {
+
+ var spy;
+
+ before(function () {
+ window.localStorage.removeItem('res_en-US');
+ window.localStorage.removeItem('res_en');
+ window.localStorage.removeItem('res_dev');
+ });
+
+ beforeEach(function (done) {
+ spy = sinon.spy(i18n.sync, '_fetchOne');
+ i18n.init($.extend(opts, {
+ useLocalStorage: true
+ }), function (t) {
+ i18n.setDefaultNamespace('ns.special');
+ i18n.loadNamespaces(['ns.common', 'ns.special'], done);
+ });
+ });
+
+ afterEach(function () {
+ spy.restore();
+ });
+
+ it('it should load language', function () {
+ expect(spy.callCount).to.be(9); // en-US, en, de-DE, de, fr, dev * 3 namespaces (translate, common, special)
+ });
+
+ describe('on later reload of namespaces', function () {
+
+ beforeEach(function (done) {
+ spy.reset();
+ i18n.init($.extend(opts, {
+ useLocalStorage: true,
+ ns: 'translation'
+ }), function (t) {
+ i18n.setDefaultNamespace('ns.special');
+ i18n.loadNamespaces(['ns.common', 'ns.special'], done);
+ });
+ });
+
+ it('it should not reload language', function () {
+ expect(spy.callCount).to.be(0);
+ });
+
+ });
+
+ });
+
+ });
+
+ });
+
+ describe('using function provided in callback\'s argument', function () {
+
+ var cbT;
+
+ beforeEach(function (done) {
+ i18n.init(opts, function (t) { cbT = t; done(); });
+ });
+
+ it('it should provide loaded resources for translation', function () {
+ expect(cbT('simple_en-US')).to.be('ok_from_en-US');
+ expect(cbT('simple_en')).to.be('ok_from_en');
+ expect(cbT('simple_dev')).to.be('ok_from_dev');
+ });
+
+ });
+
+ describe('using localStorage', function () {
+
+ var spy;
+
+ before(function () {
+ window.localStorage.removeItem('res_en-US');
+ window.localStorage.removeItem('res_en');
+ window.localStorage.removeItem('res_dev');
+ });
+
+ beforeEach(function (done) {
+ spy = sinon.spy(i18n.sync, '_fetchOne');
+ i18n.init($.extend(opts, {
+ useLocalStorage: true
+ }), function (t) { done(); });
+ });
+
+ afterEach(function () {
+ spy.restore();
+ });
+
+ it('it should load language', function () {
+ expect(spy.callCount).to.be(3); // en-US, en, de-DE, de, fr, dev
+ });
+
+ describe('on later init', function () {
+
+ beforeEach(function (done) {
+ spy.reset();
+ i18n.init(function (t) { done(); });
+ });
+
+ it('it should not reload language', function () {
+ expect(spy.callCount).to.be(0); // de-DE, de, fr, dev
+ });
+
+ describe('on later init - after caching duration', function () {
+
+ beforeEach(function (done) {
+ spy.reset();
+
+ // exipred
+ var local = window.localStorage.getItem('res_en-US');
+ local = JSON.parse(local);
+ local.i18nStamp = 0;
+ window.localStorage.setItem('res_en-US', JSON.stringify(local));
+
+ i18n.init(function (t) { done(); });
+ });
+
+ it('it should reload language', function () {
+ expect(spy.callCount).to.be(1); // de-DE, de, fr, dev
+ });
+
+ });
+
+ });
+
+ });
+
+ describe('with lowercase flag', function () {
+
+ describe('default behaviour will uppercase specifc country part.', function () {
+
+ beforeEach(function () {
+ i18n.init($.extend(opts, {
+ lng: 'en-us',
+ resStore: {
+ 'en-US': { translation: { 'simple_en-US': 'ok_from_en-US' } }
+ }
+ }, function (t) { done(); }));
+ });
+
+ it('it should translate the uppercased lng value', function () {
+ expect(i18n.t('simple_en-US')).to.be('ok_from_en-US');
+ });
+
+ it('it should get uppercased set language', function () {
+ expect(i18n.lng()).to.be('en-US');
+ });
+
+ });
+
+ describe('overridden behaviour will accept lowercased country part.', function () {
+
+ beforeEach(function () {
+ i18n.init($.extend(opts, {
+ lng: 'en-us',
+ lowerCaseLng: true,
+ resStore: {
+ 'en-us': { translation: { 'simple_en-us': 'ok_from_en-us' } }
+ }
+ }, function (t) { done(); }));
+ });
+
+ it('it should translate the lowercase lng value', function () {
+ expect(i18n.t('simple_en-us')).to.be('ok_from_en-us');
+ });
+
+ it('it should get lowercased set language', function () {
+ expect(i18n.lng()).to.be('en-us');
+ });
+
+ });
+
+ });
+
+ });
+
+ });
+ describe('basic functionality', function () {
+
+ describe('setting language', function () {
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, {
+ resStore: {
+ 'en-US': { translation: { 'simpleTest': 'ok_from_en-US' } },
+ 'de-DE': { translation: { 'simpleTest': 'ok_from_de-DE' } }
+ }
+ }), function (t) { done(); });
+ });
+
+ it('it should provide resources for set language', function (done) {
+ expect(i18n.t('simpleTest')).to.be('ok_from_en-US');
+
+ i18n.setLng('de-DE', function (t) {
+ expect(t('simpleTest')).to.be('ok_from_de-DE');
+ done();
+ });
+
+ });
+
+ });
+
+ describe('preloading multiple languages', function () {
+
+ var spy;
+
+ beforeEach(function (done) {
+ spy = sinon.spy(i18n.sync, '_fetchOne');
+ i18n.init(opts, function (t) { done(); });
+ });
+
+ afterEach(function () {
+ spy.restore();
+ });
+
+ it('it should preload resources for languages', function (done) {
+ spy.reset();
+ i18n.preload('de-DE', function (t) {
+ expect(spy.callCount).to.be(5); // en-US, en, de-DE, de, dev
+ done();
+ });
+
+ });
+
+ });
+
+ describe('postprocessing tranlation', function () {
+
+ describe('having a postprocessor', function () {
+
+ before(function () {
+ i18n.addPostProcessor('myProcessor', function (val, key, opts) {
+ return 'ok_from_postprocessor';
+ });
+ });
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, {
+ resStore: {
+ 'en-US': { translation: { 'simpleTest': 'ok_from_en-US' } },
+ 'de-DE': { translation: { 'simpleTest': 'ok_from_de-DE' } }
+ }
+ }), function (t) { done(); });
+ });
+
+ it('it should postprocess the translation by passing in postProcess name to t function', function () {
+ expect(i18n.t('simpleTest', { postProcess: 'myProcessor' })).to.be('ok_from_postprocessor');
+ });
+
+ describe('or setting it as default on init', function () {
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, {
+ resStore: {
+ 'en-US': { translation: { 'simpleTest': 'ok_from_en-US' } },
+ 'de-DE': { translation: { 'simpleTest': 'ok_from_de-DE' } }
+ },
+ postProcess: 'myProcessor'
+ }), function (t) { done(); });
+ });
+
+ it('it should postprocess the translation by default', function () {
+ expect(i18n.t('simpleTest')).to.be('ok_from_postprocessor');
+ });
+
+ });
+
+ });
+
+ });
+
+ describe('post missing resources', function () {
+
+ describe('to fallback', function () {
+ var server, stub;
+
+ beforeEach(function (done) {
+ server = sinon.fakeServer.create();
+ stub = sinon.stub(i18n.functions, "ajax");
+
+ server.respondWith([200, { "Content-Type": "text/html", "Content-Length": 2 }, "OK"]);
+
+ i18n.init($.extend(opts, {
+ sendMissing: true,
+ resStore: {
+ 'en-US': { translation: {} },
+ 'en': { translation: {} },
+ 'dev': { translation: {} }
+ }
+ }), function (t) { done(); });
+ });
+
+ afterEach(function () {
+ server.restore();
+ stub.restore();
+ });
+
+ it('it should post missing resource to server', function () {
+ i18n.t('missing');
+ server.respond();
+ expect(stub.calledOnce).to.be(true);
+ });
+
+ });
+
+ describe('to all', function () {
+ var server, stub;
+
+ beforeEach(function (done) {
+ server = sinon.fakeServer.create();
+ stub = sinon.stub(i18n.functions, "ajax");
+
+ server.respondWith([200, { "Content-Type": "text/html", "Content-Length": 2 }, "OK"]);
+
+ i18n.init($.extend(opts, {
+ sendMissing: true,
+ sendMissingTo: 'all',
+ resStore: {
+ 'en-US': { translation: {} },
+ 'en': { translation: {} },
+ 'dev': { translation: {} }
+ }
+ }), function (t) { done(); });
+ });
+
+ afterEach(function () {
+ server.restore();
+ stub.restore();
+ });
+
+ it('it should post missing resource for all lng to server', function () {
+ i18n.t('missing');
+ server.respond();
+ expect(stub.calledThrice).to.be(true);
+ });
+
+ });
+
+ });
+
+ });
+ describe('translation functionality', function () {
+
+ describe('key with empty string value as valid option', function () {
+ var resStore = {
+ dev: { translation: { empty: '' } },
+ en: { translation: {} },
+ 'en-US': { translation: {} }
+ };
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, { resStore: resStore }),
+ function (t) { done(); });
+ });
+
+ it('it should translate correctly', function () {
+ expect(i18n.t('empty')).to.be('');
+ });
+ });
+
+ describe('resource string as array', function () {
+ var resStore = {
+ dev: { translation: { testarray: ["title", "text"] } },
+ en: { translation: {} },
+ 'en-US': { translation: {} }
+ };
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, { resStore: resStore }),
+ function (t) { done(); });
+ });
+
+ it('it should translate nested value', function () {
+ expect(i18n.t('testarray')).to.be('title\ntext');
+ });
+ });
+
+ describe('accessing nested values', function () {
+
+ beforeEach(function (done) {
+ i18n.init(opts, function (t) { done(); });
+ });
+
+ it('it should return nested string', function () {
+ expect(i18n.t('test.simple_en-US')).to.be('ok_from_en-US');
+ });
+
+ it('it should not fail silently on accessing a objectTree', function () {
+ expect(i18n.t('test')).to.be('key \'translation:test (en-US)\' returned a object instead of string.');
+ });
+
+ describe('optional return an objectTree for UI components,...', function () {
+
+ describe('with init flag', function () {
+
+ var resStore = {
+ dev: { translation: {} },
+ en: { translation: {} },
+ 'en-US': {
+ translation: {
+ test: { res: 'added __replace__' }
+ }
+ }
+ };
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, {
+ returnObjectTrees: true,
+ resStore: resStore
+ }
+ ), function (t) { done(); });
+ });
+
+ it('it should return objectTree applying options', function () {
+ expect(i18n.t('test', { replace: 'two' })).to.eql({ 'res': 'added two' });
+ });
+
+ });
+
+ describe('with flag in options', function () {
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, { returnObjectTrees: false }),
+ function (t) { done(); });
+ });
+
+ it('it should return objectTree', function () {
+ expect(i18n.t('test', { returnObjectTrees: true })).to.eql({ 'simple_en-US': 'ok_from_en-US' });
+ });
+
+ });
+
+ });
+
+ });
+
+ describe('resource nesting', function () {
+ var resStore = {
+ dev: { translation: { nesting1: '1 $t(nesting2)' } },
+ en: { translation: { nesting2: '2 $t(nesting3)' } },
+ 'en-US': { translation: { nesting3: '3' } }
+ };
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, { resStore: resStore }),
+ function (t) { done(); });
+ });
+
+ it('it should translate nested value', function () {
+ expect(i18n.t('nesting1')).to.be('1 2 3');
+ });
+
+ it('it should apply nested value on defaultValue', function () {
+ expect(i18n.t('nesting_default', { defaultValue: '0 $t(nesting1)' })).to.be('0 1 2 3');
+ });
+ });
+
+ describe('interpolation - replacing values inside a string', function () {
+
+ describe('default i18next way', function () {
+
+ var resStore = {
+ dev: { translation: {} },
+ en: { translation: {} },
+ 'en-US': {
+ translation: {
+ interpolationTest1: 'added __toAdd__',
+ interpolationTest2: 'added __toAdd__ __toAdd__ twice',
+ interpolationTest3: 'added __child.one__ __child.two__',
+ interpolationTest4: 'added __child.grandChild.three__'
+ }
+ }
+ };
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, { resStore: resStore }),
+ function (t) { done(); });
+ });
+
+ it('it should replace passed in key/values', function () {
+ expect(i18n.t('interpolationTest1', { toAdd: 'something' })).to.be('added something');
+ expect(i18n.t('interpolationTest2', { toAdd: 'something' })).to.be('added something something twice');
+ expect(i18n.t('interpolationTest3', { child: { one: '1', two: '2' } })).to.be('added 1 2');
+ expect(i18n.t('interpolationTest4', { child: { grandChild: { three: '3' } } })).to.be('added 3');
+ });
+
+ it('it should replace passed in key/values on defaultValue', function () {
+ expect(i18n.t('interpolationTest5', { defaultValue: 'added __toAdd__', toAdd: 'something' })).to.be('added something');
+ });
+
+ });
+
+ describe('default i18next way - different prefix/suffix', function () {
+
+ var resStore = {
+ dev: { translation: {} },
+ en: { translation: {} },
+ 'en-US': {
+ translation: {
+ interpolationTest1: 'added *toAdd*',
+ interpolationTest2: 'added *toAdd* *toAdd* twice',
+ interpolationTest3: 'added *child.one* *child.two*',
+ interpolationTest4: 'added *child.grandChild.three*'
+ }
+ }
+ };
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, {
+ resStore: resStore,
+ interpolationPrefix: '*',
+ interpolationSuffix: '*'
+ }), function (t) { done(); });
+ });
+
+ it('it should replace passed in key/values', function () {
+ expect(i18n.t('interpolationTest1', { toAdd: 'something' })).to.be('added something');
+ expect(i18n.t('interpolationTest2', { toAdd: 'something' })).to.be('added something something twice');
+ expect(i18n.t('interpolationTest3', { child: { one: '1', two: '2' } })).to.be('added 1 2');
+ expect(i18n.t('interpolationTest4', { child: { grandChild: { three: '3' } } })).to.be('added 3');
+ });
+
+ it('it should replace passed in key/values on defaultValue', function () {
+ expect(i18n.t('interpolationTest5', { defaultValue: 'added *toAdd*', toAdd: 'something' })).to.be('added something');
+ });
+
+ });
+
+ describe('using sprintf', function () {
+
+ var resStore = {
+ dev: { translation: {} },
+ en: { translation: {} },
+ 'en-US': {
+ translation: {
+ interpolationTest1: 'The first 4 letters of the english alphabet are: %s, %s, %s and %s',
+ interpolationTest2: 'Hello %(users[0].name)s, %(users[1].name)s and %(users[2].name)s'
+ }
+ }
+ };
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, { resStore: resStore }),
+ function (t) { done(); });
+ });
+
+ it('it should replace passed in key/values', function () {
+ expect(i18n.t('interpolationTest1', { postProcess: 'sprintf', sprintf: ['a', 'b', 'c', 'd'] })).to.be('The first 4 letters of the english alphabet are: a, b, c and d');
+ expect(i18n.t('interpolationTest2', { postProcess: 'sprintf', sprintf: { users: [{ name: 'Dolly' }, { name: 'Molly' }, { name: 'Polly' }] } })).to.be('Hello Dolly, Molly and Polly');
+ });
+
+ });
+
+ });
+
+ describe('plural usage', function () {
+
+ describe('basic usage - singular and plural form', function () {
+ var resStore = {
+ dev: {
+ 'ns.2': {
+ pluralTest: 'singular from ns.2',
+ pluralTest_plural: 'plural from ns.2',
+ pluralTestWithCount: '__count__ item from ns.2',
+ pluralTestWithCount_plural: '__count__ items from ns.2'
+ }
+ },
+ en: {},
+ 'en-US': {
+ 'ns.1': {
+ pluralTest: 'singular',
+ pluralTest_plural: 'plural',
+ pluralTestWithCount: '__count__ item',
+ pluralTestWithCount_plural: '__count__ items'
+ }
+ }
+ };
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, {
+ resStore: resStore,
+ ns: { namespaces: ['ns.1', 'ns.2'], defaultNs: 'ns.1' }
+ }),
+ function (t) { done(); });
+ });
+
+ it('it should provide correct plural or singular form', function () {
+ expect(i18n.t('pluralTest', { count: 0 })).to.be('plural');
+ expect(i18n.t('pluralTest', { count: 1 })).to.be('singular');
+ expect(i18n.t('pluralTest', { count: 2 })).to.be('plural');
+ expect(i18n.t('pluralTest', { count: 7 })).to.be('plural');
+
+ expect(i18n.t('pluralTestWithCount', { count: 0 })).to.be('0 items');
+ expect(i18n.t('pluralTestWithCount', { count: 1 })).to.be('1 item');
+ expect(i18n.t('pluralTestWithCount', { count: 7 })).to.be('7 items');
+ });
+
+ it('it should provide correct plural or singular form for second namespace', function () {
+ expect(i18n.t('ns.2:pluralTest', { count: 0 })).to.be('plural from ns.2');
+ expect(i18n.t('ns.2:pluralTest', { count: 1 })).to.be('singular from ns.2');
+ expect(i18n.t('ns.2:pluralTest', { count: 2 })).to.be('plural from ns.2');
+ expect(i18n.t('ns.2:pluralTest', { count: 7 })).to.be('plural from ns.2');
+
+ expect(i18n.t('ns.2:pluralTestWithCount', { count: 1 })).to.be('1 item from ns.2');
+ expect(i18n.t('ns.2:pluralTestWithCount', { count: 7 })).to.be('7 items from ns.2');
+ });
+ });
+
+ describe('basic usage 2 - singular and plural form in french', function () {
+ var resStore = {
+ dev: {
+ 'ns.2': {
+ pluralTest: 'singular from ns.2',
+ pluralTest_plural: 'plural from ns.2',
+ pluralTestWithCount: '__count__ item from ns.2',
+ pluralTestWithCount_plural: '__count__ items from ns.2'
+ }
+ },
+ en: {},
+ 'fr': {
+ 'ns.1': {
+ pluralTest: 'singular',
+ pluralTest_plural: 'plural',
+ pluralTestWithCount: '__count__ item',
+ pluralTestWithCount_plural: '__count__ items'
+ }
+ }
+ };
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, {
+ lng: 'fr',
+ resStore: resStore,
+ ns: { namespaces: ['ns.1', 'ns.2'], defaultNs: 'ns.1' }
+ }),
+ function (t) { done(); });
+ });
+
+ it('it should provide correct plural or singular form', function () {
+ expect(i18n.t('pluralTest', { count: 0 })).to.be('singular');
+ expect(i18n.t('pluralTest', { count: 1 })).to.be('singular');
+ expect(i18n.t('pluralTest', { count: 2 })).to.be('plural');
+ expect(i18n.t('pluralTest', { count: 7 })).to.be('plural');
+
+ expect(i18n.t('pluralTestWithCount', { count: 0 })).to.be('0 item');
+ expect(i18n.t('pluralTestWithCount', { count: 1 })).to.be('1 item');
+ expect(i18n.t('pluralTestWithCount', { count: 7 })).to.be('7 items');
+ });
+ });
+
+ describe('extended usage - multiple plural forms - ar', function () {
+ var resStore = {
+ dev: { translation: {} },
+ ar: {
+ translation: {
+ key: 'singular',
+ key_plural_0: 'zero',
+ key_plural_2: 'two',
+ key_plural_3: 'few',
+ key_plural_11: 'many',
+ key_plural_100: 'plural'
+ }
+ },
+ 'ar-??': { translation: {} }
+ };
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, { lng: 'ar', resStore: resStore }),
+ function (t) { done(); });
+ });
+
+ it('it should provide correct plural forms', function () {
+ expect(i18n.t('key', { count: 0 })).to.be('zero');
+ expect(i18n.t('key', { count: 1 })).to.be('singular');
+ expect(i18n.t('key', { count: 2 })).to.be('two');
+ expect(i18n.t('key', { count: 3 })).to.be('few');
+ expect(i18n.t('key', { count: 4 })).to.be('few');
+ expect(i18n.t('key', { count: 104 })).to.be('few');
+ expect(i18n.t('key', { count: 11 })).to.be('many');
+ expect(i18n.t('key', { count: 99 })).to.be('many');
+ expect(i18n.t('key', { count: 199 })).to.be('many');
+ expect(i18n.t('key', { count: 100 })).to.be('plural');
+ });
+ });
+
+ describe('extended usage - multiple plural forms - ru', function () {
+ var resStore = {
+ dev: { translation: {} },
+ ru: {
+ translation: {
+ key: '1,21,31',
+ key_plural_2: '2,3,4',
+ key_plural_5: '0,5,6'
+ }
+ },
+ 'ru-??': { translation: {} }
+ };
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, { lng: 'ru', resStore: resStore }),
+ function (t) { done(); });
+ });
+
+ it('it should provide correct plural forms', function () {
+ expect(i18n.t('key', { count: 0 })).to.be('0,5,6');
+ expect(i18n.t('key', { count: 1 })).to.be('1,21,31');
+ expect(i18n.t('key', { count: 2 })).to.be('2,3,4');
+ expect(i18n.t('key', { count: 3 })).to.be('2,3,4');
+ expect(i18n.t('key', { count: 4 })).to.be('2,3,4');
+ expect(i18n.t('key', { count: 104 })).to.be('2,3,4');
+ expect(i18n.t('key', { count: 11 })).to.be('0,5,6');
+ expect(i18n.t('key', { count: 24 })).to.be('2,3,4');
+ expect(i18n.t('key', { count: 25 })).to.be('0,5,6');
+ expect(i18n.t('key', { count: 99 })).to.be('0,5,6');
+ expect(i18n.t('key', { count: 199 })).to.be('0,5,6');
+ expect(i18n.t('key', { count: 100 })).to.be('0,5,6');
+ });
+ });
+
+ });
+
+ describe('context usage', function () {
+
+ describe('basic usage', function () {
+ var resStore = {
+ dev: {
+ 'ns.2': {
+ friend_context: 'A friend from ns2',
+ friend_context_male: 'A boyfriend from ns2',
+ friend_context_female: 'A girlfriend from ns2'
+ }
+ },
+ en: {
+ 'ns.1': {
+ friend_context: 'A friend',
+ friend_context_male: 'A boyfriend',
+ friend_context_female: 'A girlfriend'
+ }
+ },
+ 'en-US': { translation: {} }
+ };
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, {
+ resStore: resStore,
+ ns: { namespaces: ['ns.1', 'ns.2'], defaultNs: 'ns.1' }
+ }),
+ function (t) { done(); });
+ });
+
+ it('it should provide correct context form', function () {
+ expect(i18n.t('friend_context')).to.be('A friend');
+ expect(i18n.t('friend_context', { context: '' })).to.be('A friend');
+ expect(i18n.t('friend_context', { context: 'male' })).to.be('A boyfriend');
+ expect(i18n.t('friend_context', { context: 'female' })).to.be('A girlfriend');
+ });
+
+ it('it should provide correct context form for second namespace', function () {
+ expect(i18n.t('ns.2:friend_context')).to.be('A friend from ns2');
+ expect(i18n.t('ns.2:friend_context', { context: '' })).to.be('A friend from ns2');
+ expect(i18n.t('ns.2:friend_context', { context: 'male' })).to.be('A boyfriend from ns2');
+ expect(i18n.t('ns.2:friend_context', { context: 'female' })).to.be('A girlfriend from ns2');
+ });
+ });
+
+ describe('extended usage - in combination with plurals', function () {
+ var resStore = {
+ dev: { translation: {} },
+ en: {
+ translation: {
+ friend_context: '__count__ friend',
+ friend_context_male: '__count__ boyfriend',
+ friend_context_female: '__count__ girlfriend',
+ friend_context_plural: '__count__ friends',
+ friend_context_male_plural: '__count__ boyfriends',
+ friend_context_female_plural: '__count__ girlfriends'
+ }
+ },
+ 'en-US': { translation: {} }
+ };
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, { resStore: resStore }),
+ function (t) { done(); });
+ });
+
+ it('it should provide correct context with plural forms', function () {
+ expect(i18n.t('friend_context', { count: 1 })).to.be('1 friend');
+ expect(i18n.t('friend_context', { context: '', count: 1 })).to.be('1 friend');
+ expect(i18n.t('friend_context', { context: 'male', count: 1 })).to.be('1 boyfriend');
+ expect(i18n.t('friend_context', { context: 'female', count: 1 })).to.be('1 girlfriend');
+
+ expect(i18n.t('friend_context', { count: 10 })).to.be('10 friends');
+ expect(i18n.t('friend_context', { context: '', count: 10 })).to.be('10 friends');
+ expect(i18n.t('friend_context', { context: 'male', count: 10 })).to.be('10 boyfriends');
+ expect(i18n.t('friend_context', { context: 'female', count: 10 })).to.be('10 girlfriends');
+ });
+
+ });
+
+ });
+
+ describe('with passed in languages different from set one', function () {
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, {
+ preload: ['de-DE']
+ }),
+ function (t) { done(); });
+ });
+
+ it('it should provide translation for passed in language', function () {
+ expect(i18n.t('simple_de', { lng: 'de-DE' })).to.be('ok_from_de');
+ });
+
+ describe('with language not preloaded', function () {
+
+ it('it should provide translation for passed in language after loading file sync', function () {
+ expect(i18n.t('simple_fr', { lng: 'fr' })).to.be('ok_from_fr');
+ });
+
+ });
+
+ });
+
+ });
+
+ describe('jQuery integration / specials', function () {
+
+ describe('initialise - use deferrer instead of callback', function () {
+
+ describe('with passed in resource set', function () {
+
+ var resStore = {
+ dev: { translation: { 'simple_dev': 'ok_from_dev' } },
+ en: { translation: { 'simple_en': 'ok_from_en' } },
+ 'en-US': { translation: { 'simple_en-US': 'ok_from_en-US' } }
+ };
+
+ beforeEach(function (done) {
+ i18n.init($.extend(opts, { resStore: resStore })).done(function (t) { done(); });
+ });
+
+ it('it should provide passed in resources for translation', function () {
+ expect($.t('simple_en-US')).to.be('ok_from_en-US');
+ expect($.t('simple_en')).to.be('ok_from_en');
+ expect($.t('simple_dev')).to.be('ok_from_dev');
+ });
+
+ });
+
+ describe('loading from server', function () {
+
+ beforeEach(function (done) {
+ i18n.init(opts).done(function () { done(); });
+ });
+
+ it('it should provide loaded resources for translation', function () {
+ expect($.t('simple_en-US')).to.be('ok_from_en-US');
+ expect($.t('simple_en')).to.be('ok_from_en');
+ expect($.t('simple_dev')).to.be('ok_from_dev');
+ });
+
+ });
+
+ });
+
+ describe('use translation function shortcut $.t', function () {
+
+ beforeEach(function (done) {
+ i18n.init(opts, function (t) { done(); });
+ });
+
+ it('it should provide translation via $.t', function () {
+ expect($.t('simple_en-US')).to.be('ok_from_en-US');
+ expect($.t('simple_en')).to.be('ok_from_en');
+ expect($.t('simple_dev')).to.be('ok_from_dev');
+ });
+
+ });
+
+ describe('using bindings $([selector].i18n())', function () {
+
+ describe('basic - setting text', function () {
+
+ var resStore = {
+ dev: { translation: {} },
+ en: { translation: {} },
+ 'en-US': { translation: { 'simpleTest': 'ok_from_en-US' } }
+ };
+
+ beforeEach(function (done) {
+ setFixtures('
+
+');
+
+ i18n.init($.extend(opts, { resStore: resStore }),
+ function (t) { done(); });
+ });
+
+ it('it should set text of elements inside selector having data-i18n attribute', function () {
+ $('#container').i18n();
+ expect($('#testBtn').text()).to.be('ok_from_en-US');
+ });
+
+ it('it should set text of element itself if having data-i18n attribute', function () {
+ $('#testBtn').i18n();
+ expect($('#testBtn').text()).to.be('ok_from_en-US');
+ });
+
+ });
+
+ describe('extended - setting other attributes', function () {
+
+ var resStore = {
+ dev: { translation: {} },
+ en: { translation: {} },
+ 'en-US': { translation: { 'simpleTest': 'ok_from_en-US' } }
+ };
+
+ beforeEach(function (done) {
+ setFixtures('
+
+');
+
+ i18n.init($.extend(opts, { resStore: resStore }),
+ function (t) { done(); });
+ });
+
+ it('it should set text of elements inside selector having data-i18n attribute', function () {
+ $('#container').i18n();
+ expect($('#testBtn').text()).to.be('ok_from_en-US');
+ });
+
+ it('it should set attributes of elements inside selector having data-i18n attribute', function () {
+ $('#container').i18n();
+ expect($('#testBtn').attr('title')).to.be('ok_from_en-US');
+ });
+
+ });
+
+ describe('extended - pass in options', function () {
+
+ var resStore = {
+ dev: { translation: {} },
+ en: { translation: {} },
+ 'en-US': { translation: { 'simpleTest': '__replace__ ok_from_en-US' } }
+ };
+
+ beforeEach(function (done) {
+ setFixtures('
+
+');
+
+ i18n.init($.extend(opts, { resStore: resStore }),
+ function (t) { done(); });
+ });
+
+ it('it should set text with passed in options', function () {
+ $('#container').i18n({ replace: 'replaced' });
+ expect($('#testBtn').text()).to.be('replaced ok_from_en-US');
+ });
+
+ });
+
+ describe('extended - render inner html', function () {
+
+ var resStore = {
+ dev: { translation: {} },
+ en: { translation: {} },
+ 'en-US': { translation: { 'simpleTest': '
+test
+' } }
+ };
+
+ beforeEach(function (done) {
+ setFixtures('
+');
+
+ i18n.init($.extend(opts, { resStore: resStore }),
+ function (t) { done(); });
+ });
+
+ it('it should set inner html', function () {
+ $('#container').i18n();
+ expect($('#inner').html()).to.be('test');
+ });
+
+ });
+
+
+ describe('extended - read options from data attribute', function () {
+
+ var resStore = {
+ dev: { translation: {} },
+ en: { translation: {} },
+ 'en-US': { translation: { 'simpleTest': '__replace__ ok_from_en-US' } }
+ };
+
+ beforeEach(function (done) {
+ setFixtures('
+
+');
+
+ i18n.init($.extend(opts, {
+ resStore: resStore,
+ useDataAttrOptions: true
+ }),
+ function (t) {
+ $('#container').i18n({ replace: 'replaced' });
+ $('#testBtn').text('');
+ done();
+ });
+ });
+
+ it('it should set text with attributes options', function () {
+ $('#container').i18n(); // without option
+ expect($('#testBtn').text()).to.be('replaced ok_from_en-US');
+ });
+
+ });
+
+ });
+
+ });
+
+
+});
diff --git a/jquery/jquery-1.8.d.ts b/jquery/jquery-1.8.d.ts
index 3328c2082..4e617c961 100644
--- a/jquery/jquery-1.8.d.ts
+++ b/jquery/jquery-1.8.d.ts
@@ -59,6 +59,7 @@ interface JQueryAjaxSettings {
*/
interface JQueryXHR extends XMLHttpRequest, JQueryPromise {
overrideMimeType(mimeType: string);
+ abort(statusText: string): void;
}
/*
diff --git a/kolite/kolite-1.1.d.ts b/kolite/kolite-1.1.d.ts
new file mode 100644
index 000000000..c879b7871
--- /dev/null
+++ b/kolite/kolite-1.1.d.ts
@@ -0,0 +1,77 @@
+// Type definitions for KoLite 1.1
+// Project: https://github.com/CodeSeven/kolite
+// Definitions by: Boris Yankov
+// Definitions https://github.com/borisyankov/DefinitelyTyped
+
+
+///
+///
+
+
+// Activity /////////////////////////////////////////////
+
+interface KoLiteActivityOptions {
+ color?: any;
+ segments?: number;
+ space?: number;
+ length?: number;
+ width?: number;
+ speed?: number;
+ align?: string;
+ valign?: string;
+ padding?: number;
+}
+
+interface KoLiteActivity {
+ (options: KoLiteActivityOptions): JQuery;
+ defaults: KoLiteActivityOptions;
+ getOpacity(options: { steps?: number; segments?: number; opacity?: number; }, i: number): number;
+}
+
+interface KnockoutBindingHandlers {
+ activity: KnockoutBindingHandler;
+}
+
+interface JQuery {
+ activity: KoLiteActivity;
+ activityEx(isLoading: bool): JQuery;
+}
+
+
+// DirtyFlag /////////////////////////////////////////////
+
+interface DirtyFlag {
+ isDirty: KnockoutComputed;
+ new (objectToTrack: any, isInitiallyDirty?: bool, hashFunction?: () => any);
+ reset(): void;
+}
+
+interface KnockoutStatic {
+ DirtyFlag: DirtyFlag;
+}
+
+
+// Command /////////////////////////////////////////////
+
+interface KoliteCommand {
+ canExecute: KnockoutComputed;
+ execute(...args: any[]): any;
+}
+
+interface KoLiteCommandOptions {
+ execute?: any;
+ canExecute?: (isExecuting: bool) => any;
+}
+
+interface KnockoutStatic {
+ command(options: KoLiteCommandOptions): KoliteCommand;
+ asyncCommand(optons: KoLiteCommandOptions): KoliteCommand;
+}
+
+interface KnockoutUtils {
+ wrapAccessor(accessor): Function;
+}
+
+interface KnockoutBindingHandlers {
+ command: KnockoutBindingHandler;
+}
\ No newline at end of file
diff --git a/kolite/kolite-tests.ts b/kolite/kolite-tests.ts
new file mode 100644
index 000000000..4e1418211
--- /dev/null
+++ b/kolite/kolite-tests.ts
@@ -0,0 +1,197 @@
+///
+///
+///
+
+function test_asyncCommand() {
+ var saveCmd = ko.asyncCommand({
+ execute: function (complete) {
+ $.when().always(complete);
+ },
+ canExecute: function (isExecuting) {
+ return !isExecuting;
+ }
+ });
+ this.saveCommand = ko.asyncCommand({
+ execute: function (callback) {
+ $.ajax({
+ complete: callback,
+ data: { name: this.name() },
+ type: 'POST',
+ url: '/save/',
+
+ success: function (result) {
+ alert('Name saved:' + result)
+ }
+ })
+ },
+ canExecute: function (isExecuting) {
+ return !isExecuting && this.name()
+ }
+ });
+}
+
+function test_dirtyFlag() {
+ var viewModel;
+ viewModel.dirtyFlag = new ko.DirtyFlag(viewModel.model);
+ viewModel.dirtyFlag().isDirty();
+ viewModel.dirtyFlag().reset();
+
+ var self;
+ this.dirtyFlag = new ko.DirtyFlag(
+ self.firstName,
+ self.lastName);
+ var isDirty = ko.computed(function () {
+ });
+
+ var Person = function () {
+ var self = this;
+
+ self.id = ko.observable();
+ self.firstName = ko.observable().extend({ required: true });
+ self.lastName = ko.observable().extend({ required: true });
+ self.dirtyFlag = new ko.DirtyFlag([self.firstName, self.lastName]);
+
+ return self;
+ };
+}
+
+function test_full() {
+ (function (ko) {
+ ko.command = function (options) {
+ var
+ self = ko.observable(),
+ canExecuteDelegate = options.canExecute,
+ executeDelegate = options.execute;
+ self.canExecute = ko.computed(function () {
+ return canExecuteDelegate ? canExecuteDelegate() : true;
+ });
+ self.execute = function (arg1, arg2) {
+ if (!self.canExecute()) return;
+ executeDelegate.apply(this, [arg1, arg2]);
+ };
+ return self;
+ };
+
+ ko.asyncCommand = function (options) {
+ var
+ self = ko.observable(),
+ canExecuteDelegate = options.canExecute,
+ executeDelegate = options.execute,
+ completeCallback = function () {
+ self.isExecuting(false);
+ };
+ self.isExecuting = ko.observable();
+ self.canExecute = ko.computed(function () {
+ return canExecuteDelegate ? canExecuteDelegate(self.isExecuting()) : !self.isExecuting();
+ });
+ self.execute = function (arg1, arg2) {
+ if (!self.canExecute()) return;
+ var args = [];
+ if (executeDelegate.length >= 2) {
+ args.push(arg1);
+ }
+ if (executeDelegate.length >= 3) {
+ args.push(arg2);
+ }
+ args.push(completeCallback);
+ self.isExecuting(true);
+ executeDelegate.apply(this, args);
+ };
+ return self;
+ };
+ })(ko);
+ (function (ko) {
+ ko.utils.wrapAccessor = function (accessor) {
+ return function () {
+ return accessor;
+ };
+ };
+ ko.bindingHandlers.command = {
+ init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
+ var
+ value = valueAccessor(),
+ commands = value.execute ? { click: value } : value,
+ isBindingHandler = function (handler) {
+ return ko.bindingHandlers[handler] !== undefined;
+ },
+ initBindingHandlers = function () {
+ for (var command in commands) {
+ if (!isBindingHandler(command)) {
+ continue;
+ };
+ ko.bindingHandlers[command].init(
+ element,
+ ko.utils.wrapAccessor(commands[command].execute),
+ allBindingsAccessor,
+ viewModel
+ );
+ }
+ },
+ initEventHandlers = function () {
+ var events = {};
+ for (var command in commands) {
+ if (!isBindingHandler(command)) {
+ events[command] = commands[command].execute;
+ }
+ }
+ ko.bindingHandlers.event.init(
+ element,
+ ko.utils.wrapAccessor(events),
+ allBindingsAccessor,
+ viewModel);
+ };
+ initBindingHandlers();
+ initEventHandlers();
+ },
+ update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
+ var commands = valueAccessor();
+ var canExecute = commands.canExecute;
+ if (!canExecute) {
+ for (var command in commands) {
+ if (commands[command].canExecute) {
+ canExecute = commands[command].canExecute;
+ break;
+ }
+ }
+ }
+ if (!canExecute) {
+ return;
+ }
+ ko.bindingHandlers.enable.update(element, canExecute, allBindingsAccessor, viewModel);
+ }
+ };
+ })(ko);
+
+ var my: any = {};
+ my.TwitterService = function () {
+ var me = this,
+ twitterUrl = 'https://api.twitter.com/1/statuses/user_timeline/{name}.json?callback=?&count={count}'
+ me.getTweets = function (options) {
+ }
+ }
+ my.TweetsViewModel = function () {
+ var me = this,
+ service = new my.TwitterService()
+ me.name = ko.observable('hfjallemark');
+ me.tweets = ko.observableArray();
+ me.showKeyCodeCommand = ko.command({
+ execute: function (data, e) {
+ }
+ });
+ me.loadTweetsCommand = ko.asyncCommand({
+ execute: function (complete) {
+ service.getTweets({
+ always: complete,
+ count: 15,
+ name: me.name(),
+ done: function (result) {
+ me.tweets(result);
+ },
+ fail: function (options, status) {
+ }
+ })
+ }
+ })
+ }
+ ko.applyBindings(new my.TweetsViewModel());
+}
\ No newline at end of file