Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

added i18next TypeScript declarations source file + tests

Added the 'i18next.d.ts' file and test files.

The test files are included because I will also create a pull request
for the DefinitelyTyped repo by Boris Yankov
(https://github.com/borisyankov/DefinitelyTyped).

The jQuery / Mocha and Sinon *.d.ts files aren't my work and some seem
to be incomplete, but are only included because the original test page
(http://i18next.com/pages/test.html) uses them and they do the job.
  • Loading branch information...
commit 2532915360435e1b35ead244421cf9f3ddae5247 1 parent d0adbc8
@mdocter mdocter authored
View
127 typescript/i18next.d.ts
@@ -0,0 +1,127 @@
+/// <reference path="lib/jquery.d.ts" />
+
+// Type definitions for i18next (v1.5.10 incl. jQuery)
+// Project: http://i18next.com
+// Sources: https://github.com/jamuhl/i18next/
+// Definitions by: Maarten Docter <https://github.com/mdocter> - 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;
View
758 typescript/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;
View
44 typescript/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);
View
33 typescript/lib/sinon.d.ts
@@ -0,0 +1,33 @@
+/// <reference path="jquery.d.ts" />
+
+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;
+}
View
1,359 typescript/tests/i18next.d.tests.ts
@@ -0,0 +1,1359 @@
+/// <reference path="../lib/sinon.d.ts" />
+/// <reference path="../lib/mocha.d.ts" />
+/// <reference path="../lib/jquery.d.ts" />
+/// <reference path="../i18next.d.ts" />
+
+// 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(<any[]>[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(<any[]>[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(<any[]>[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');
+ });
+
+ });
+
+ });
+
+ });
+
+
+});
Please sign in to comment.
Something went wrong with that request. Please try again.