Henning Snater has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/177517

Change subject: Added type checks to wikibase.api.RepoApi functions
......................................................................

Added type checks to wikibase.api.RepoApi functions

Actually reflecting parameter documentation in the code instead of relying on 
the back-end handling.
This resolves some wrong documentation as well.
Added tests testing the minimum of parameters required by each function.

Change-Id: I4d043f5cc43852970a489014bc5c106592ccfdc3
---
A .jshintignore
M README.md
M src/RepoApi.js
M tests/RepoApi.tests.js
4 files changed, 445 insertions(+), 94 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/WikibaseJavaScriptApi 
refs/changes/17/177517/1

diff --git a/.jshintignore b/.jshintignore
new file mode 100644
index 0000000..711939d
--- /dev/null
+++ b/.jshintignore
@@ -0,0 +1 @@
+./tests
\ No newline at end of file
diff --git a/README.md b/README.md
index f2f54c4..0069924 100644
--- a/README.md
+++ b/README.md
@@ -8,10 +8,11 @@
 * Updated code documentation to be able to generate documentation using JSDuck.
 * `wikibase.api.RepoApi` QUnit tests have been rewritten to not execute actual 
API requests anymore.
 * Added `wikibase.api.RepoApi` QUnit tests for functions not yet tested.
+* Added type checks to `wikibase.api.RepoApi` functions to actually reflect 
parameter documentation in the code instead of relying on the back-end handling.
 
 ### Bugfixes
 * An empty `Entity` may be created by omitting the `data` parameter on 
`wikibase.api.RepoApi.createEntity()` again.
-* `wikibase.api.RepoApi` always submits `normalize` parameter if it is 
specified explicitly (before, `false` resolved to `undefined`).
+* `wikibase.api.RepoApi` functions explicitly submit default parameters if not 
set otherwise.
 
 ### 1.0.1 (2014-11-28)
 
diff --git a/src/RepoApi.js b/src/RepoApi.js
index 6306dce..7d1f97b 100644
--- a/src/RepoApi.js
+++ b/src/RepoApi.js
@@ -53,8 +53,14 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
         */
        createEntity: function( type, data ) {
+               if( typeof type !== 'string' || data && typeof data !== 
'object' ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
                var params = {
                        action: 'wbeditentity',
                        'new': type,
@@ -67,10 +73,10 @@
         * Edits an `Entity`.
         * @see wikibase.api.RepoApi._post
         *
-        * @param {String} id `Entity` id.
-        * @param {Number} baseRevId Revision id the edit shall be performed on.
-        * @param {Object} data The `Entity`'s structure.
-        * @param {Boolean} [clear=false] Whether to clear whole entity before 
editing.
+        * @param {string} id `Entity` id.
+        * @param {number} baseRevId Revision id the edit shall be performed on.
+        * @param {Object} [data] The `Entity`'s structure.
+        * @param {boolean} [clear] Whether to clear whole entity before 
editing.
         * @return {Object} jQuery.Promise
         * @return {Function} return.done
         * @return {*} return.done.result
@@ -78,17 +84,28 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
         */
        editEntity: function( id, baseRevId, data, clear ) {
+               if(
+                       typeof id !== 'string'
+                       || typeof baseRevId !== 'number'
+                       || typeof data !== 'object'
+                       || data && typeof data !== 'object'
+               ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
                var params = {
                        action: 'wbeditentity',
                        id: id,
                        baserevid: baseRevId,
-                       data: JSON.stringify( data )
+                       data: JSON.stringify( data || {} )
                };
 
-               if ( clear ) {
-                       params.clear = true;
+               if( typeof clear === 'boolean' ) {
+                       params.clear = clear;
                }
 
                return this._post( params );
@@ -109,8 +126,19 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
         */
        formatValue: function( dataValue, options, dataType, outputFormat ) {
+               if(
+                       typeof dataValue !== 'object'
+                       || options && typeof options !== 'object'
+                       || dataType && typeof dataType !== 'string'
+                       || outputFormat && typeof outputFormat !== 'string'
+               ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
                var params = {
                        action: 'wbformatvalue',
                        datavalue:  JSON.stringify( dataValue ),
@@ -139,8 +167,8 @@
         *        property/ies values should be retrieved in. `null` returns 
values in all languages.
         * @param {string|string[]|null} [sort=null] Key(s) of property/ies to 
sort on. `null` will
         *        result in unsorted output.
-        * @param {string|null} [dir=null] Sort direction, may be 'ascending' 
or 'descending'.
-        *        `null` resolves to 'ascending'.
+        * @param {string|null} [dir] Sort direction, may be 'ascending' or 
'descending'.
+        *        Anything but 'descending' resolves to 'ascending'.
         * @return {Object} jQuery.Promise
         * @return {Function} return.done
         * @return {*} return.done.result
@@ -148,15 +176,27 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
         */
        getEntities: function( ids, props, languages, sort, dir ) {
+               if(
+                       ( typeof ids !== 'string' && !$.isArray( ids ) )
+                       || props && ( typeof props !== 'string' && !$.isArray( 
props ) )
+                       || languages && ( typeof languages !== 'string' && 
!$.isArray( languages ) )
+                       || sort && ( typeof sort !== 'string' && !$.isArray( 
sort ) )
+                       || dir && typeof dir !== 'string'
+               ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
                var params = {
                        action: 'wbgetentities',
                        ids: this._normalizeParam( ids ),
                        props: this._normalizeParam( props ),
                        languages: this._normalizeParam( languages ),
                        sort: this._normalizeParam( sort ),
-                       dir: dir || undefined
+                       dir: dir === 'descending' ? 'descending' : 'ascending'
                };
 
                return this._api.get( params );
@@ -176,8 +216,8 @@
         *        property/ies values should be retrieved in. `null` returns 
values in all languages.
         * @param {string|string[]|null} [sort=null] Key(s) of property/ies to 
sort on. `null` will
         *        result in unsorted output.
-        * @param {string|null} [dir=null] Sort direction, may be 'ascending' 
or 'descending'.
-        *        `null` resolves to 'ascending'.
+        * @param {string|null} [dir] Sort direction, may be 'ascending' or 
'descending'.
+        *        Anything but 'descending' resolves to 'ascending'.
         * @param {boolean} [normalize] Whether to normalize titles server side
         * @return {Object} jQuery.Promise
         * @return {Function} return.done
@@ -186,8 +226,25 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
+        * @throws {Error} if both, `sites` and `titles`, are passed as 
`array`s.
         */
        getEntitiesByPage: function( sites, titles, props, languages, sort, 
dir, normalize ) {
+               if(
+                       ( typeof sites !== 'string' && !$.isArray( sites ) )
+                       || ( typeof titles !== 'string' && !$.isArray( titles ) 
)
+                       || props && ( typeof props !== 'string' && !$.isArray( 
props ) )
+                       || languages && ( typeof languages !== 'string' && 
!$.isArray( languages ) )
+                       || sort && ( typeof sort !== 'string' && !$.isArray( 
sort ) )
+               ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
+               if( $.isArray( sites ) && $.isArray( titles ) ) {
+                       throw new Error( 'sites and titles may not be passed as 
arrays at the same time' );
+               }
+
                var params = {
                        action: 'wbgetentities',
                        sites: this._normalizeParam( sites ),
@@ -195,7 +252,7 @@
                        props: this._normalizeParam( props ),
                        languages: this._normalizeParam( languages ),
                        sort: this._normalizeParam( sort ),
-                       dir: dir || undefined,
+                       dir: dir === 'descending' ? 'descending' : 'ascending',
                        normalize: typeof normalize === 'boolean' ? normalize : 
undefined
                };
 
@@ -216,8 +273,18 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
         */
        parseValue: function( parser, values, options ) {
+               if(
+                       typeof parser !== 'string'
+                       || !$.isArray( values )
+                       || options && typeof options !== 'object'
+               ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
                var params = {
                        action: 'wbparsevalue',
                        parser: parser,
@@ -234,8 +301,8 @@
         * @param {string} search Text to search for.
         * @param {string} language Language code of the language to search in.
         * @param {string} type `Entity` type to search for.
-        * @param {number} limit Maximum number of results to return.
-        * @param {number} offset Offset where to continue returning the search 
results.
+        * @param {number} [limit] Maximum number of results to return.
+        * @param {number} [offset] Offset where to continue returning the 
search results.
         * @return {Object} jQuery.Promise
         * @return {Function} return.done
         * @return {*} return.done.result
@@ -243,15 +310,25 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
         */
        searchEntities: function( search, language, type, limit, offset ) {
+               if(
+                       typeof search !== 'string'
+                       || typeof language !== 'string'
+                       || typeof type !== 'string'
+               ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
                var params = {
                        action: 'wbsearchentities',
                        search: search,
                        language: language,
                        type: type,
-                       limit: limit || undefined,
-                       'continue': offset || undefined
+                       limit: typeof limit === 'number' ? limit : undefined,
+                       'continue': typeof offset === 'number' ? offset : 
undefined
                };
 
                return this._api.get( params );
@@ -272,8 +349,19 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
         */
        setLabel: function( id, baseRevId, label, language ) {
+               if(
+                       typeof id !== 'string'
+                       || typeof baseRevId !== 'number'
+                       || typeof label !== 'string'
+                       || typeof language !== 'string'
+               ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
                var params = {
                        action: 'wbsetlabel',
                        id: id,
@@ -281,6 +369,7 @@
                        language: language,
                        baserevid: baseRevId
                };
+
                return this._post( params );
        },
 
@@ -299,8 +388,19 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
         */
        setDescription: function( id, baseRevId, description, language ) {
+               if(
+                       typeof id !== 'string'
+                       || typeof baseRevId !== 'number'
+                       || typeof description !== 'string'
+                       || typeof language !== 'string'
+               ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
                var params = {
                        action: 'wbsetdescription',
                        id: id,
@@ -308,6 +408,7 @@
                        language: language,
                        baserevid: baseRevId
                };
+
                return this._post( params );
        },
 
@@ -328,18 +429,29 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
         */
        setAliases: function( id, baseRevId, add, remove, language ) {
-               add = this._normalizeParam( add );
-               remove = this._normalizeParam( remove );
+               if(
+                       typeof id !== 'string'
+                       || typeof baseRevId !== 'number'
+                       || !$.isArray( add )
+                       || !$.isArray( remove )
+                       || typeof language !== 'string'
+               ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
                var params = {
                        action: 'wbsetaliases',
                        id: id,
-                       add: add,
-                       remove: remove,
+                       add: this._normalizeParam( add ),
+                       remove: this._normalizeParam( remove ),
                        language: language,
                        baserevid: baseRevId
                };
+
                return this._post( params );
        },
 
@@ -358,15 +470,21 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
         */
        setClaim: function( claim, baseRevId, index ) {
+               if( typeof claim !== 'object' || typeof baseRevId !== 'number' 
) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
                var params = {
                        action: 'wbsetclaim',
                        claim: JSON.stringify( claim ),
                        baserevid: baseRevId
                };
 
-               if( index !== undefined ) {
+               if( typeof index === 'number' ) {
                        params.index = index;
                }
 
@@ -380,7 +498,7 @@
         * @param {string} entityId `Entity` id.
         * @param {number} baseRevId Revision id the edit shall be performed on.
         * @param {string} snakType The type of the `Snak` (see 
`wikibase.datamodel.Snak.TYPE`).
-        * @param {string} property Id of the `Snak`'s `Property`.
+        * @param {string} propertyId Id of the `Snak`'s `Property`.
         * @param {Object|string} [value] `DataValue` serialization that needs 
to be provided when the
         *        specified `Snak` type requires a value.
         * @return {Object} jQuery.Promise
@@ -390,17 +508,29 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
         */
-       createClaim: function( entityId, baseRevId, snakType, property, value ) 
{
+       createClaim: function( entityId, baseRevId, snakType, propertyId, value 
) {
+               if(
+                       typeof entityId !== 'string'
+                       || typeof baseRevId !== 'number'
+                       || typeof snakType !== 'string'
+                       || typeof propertyId !== 'string'
+                       || value && typeof value !== 'string' && typeof value 
!== 'object'
+               ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
                var params = {
                        action: 'wbcreateclaim',
                        entity: entityId,
                        baserevid: baseRevId,
                        snaktype: snakType,
-                       property: property
+                       property: propertyId
                };
 
-               if ( value ) {
+               if( value ) {
                        params.value = JSON.stringify( value );
                }
 
@@ -420,13 +550,27 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
         */
        removeClaim: function( claimGuid, claimRevisionId ) {
-               return this._post( {
+               if(
+                       typeof claimGuid !== 'string'
+                       || claimRevisionId && typeof claimRevisionId !== 
'number'
+               ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
+               var params = {
                        action: 'wbremoveclaims',
-                       claim: claimGuid,
-                       baserevid: claimRevisionId
-               } );
+                       claim: claimGuid
+               };
+
+               if( claimRevisionId ) {
+                       params.baserevid = claimRevisionId;
+               }
+
+               return this._post( params );
        },
 
        /**
@@ -434,7 +578,7 @@
         * providing a `Claim` GUID.
         * @see wikibase.api.RepoApi._post
         *
-        * @param {string|null} entityId `Entity` id.
+        * @param {string|null} entityId `Entity` id. May be `null` if 
`claimGuid` is specified.
         * @param {string} [propertyId] Only return `Claim`s featuring this 
`Property`.
         * @param {string} [claimGuid] GUID of the `Claim` to return. Either 
`claimGuid` or `entityID`
         *        has to be provided.
@@ -447,8 +591,25 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
+        * @throws {Error} if neither `entityId` nor `claimGuid` is provided.
         */
        getClaims: function( entityId, propertyId, claimGuid, rank, props ) {
+               if(
+                       entityId && typeof entityId !== 'string'
+                       || propertyId && typeof propertyId !== 'string'
+                       || claimGuid && typeof claimGuid !== 'string'
+                       || rank && typeof rank !== 'string'
+                       || props && typeof props !== 'string'
+               ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
+               if( !entityId && !claimGuid ) {
+                       throw new Error( 'Either entity id or claim GUID needs 
to be provided.' );
+               }
+
                var params = {
                        action: 'wbgetclaims',
                        entity: entityId,
@@ -468,7 +629,7 @@
         * @param {string} claimGuid The GUID of the `Claim` to be changed.
         * @param {number} baseRevId Revision id the edit shall be performed on.
         * @param {string} snakType The type of the `Snak` (see 
`wikibase.datamodel.Snak.TYPE`).
-        * @param {string} property Id of the `Snak`'s `Property`.
+        * @param {string} propertyId Id of the `Snak`'s `Property`.
         * @param {Object|string} [value] `DataValue` serialization that needs 
to be provided when the
         *        specified `Snak` type requires a value.
         * @return {Object} jQuery.Promise
@@ -478,8 +639,20 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
         */
-       setClaimValue: function( claimGuid, baseRevId, snakType, property, 
value ) {
+       setClaimValue: function( claimGuid, baseRevId, snakType, propertyId, 
value ) {
+               if(
+                       typeof claimGuid !== 'string'
+                       || typeof baseRevId !== 'number'
+                       || typeof snakType !== 'string'
+                       || typeof propertyId !== 'string'
+                       || value && typeof value !== 'string' && typeof value 
!== 'object'
+               ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
                var params = {
                        action: 'wbsetclaimvalue',
                        claim: claimGuid,
@@ -487,7 +660,7 @@
                        snaktype: snakType,
                        // NOTE: currently 'wbsetclaimvalue' API allows to 
change snak type but not property,
                        //  set it anyhow. The abstracted API won't propagate 
the API warning we will get here.
-                       property: property
+                       property: propertyId
                };
 
                if ( value ) {
@@ -505,8 +678,9 @@
         *        should be added to or changed of.
         * @param {Object} snaks `snak` portion of a serialized `Reference`.
         * @param {number} baseRevId Revision id the edit shall be performed on.
-        * @param {string} [referenceHash] A hash of the reference that should 
be updated.
+        * @param {string|number} [referenceHash] A hash of the reference that 
should be updated.
         *        If not provided, a new reference is created.
+        *        Assumed to be `index` if of type `number`.
         * @param {number} [index] The `Reference` index. Only needs to be 
specified if the
         *        `Reference`'s index within the list of all `Reference`s of 
the parent `Statement`
         *        shall be changed or when the `Reference` should be inserted 
at a specific position.
@@ -517,19 +691,31 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
         */
        setReference: function( statementGuid, snaks, baseRevId, referenceHash, 
index ) {
+               if( index === undefined && typeof referenceHash === 'number' ) {
+                       index = referenceHash;
+                       referenceHash = undefined;
+               }
+
+               if(
+                       typeof statementGuid !== 'string'
+                       || typeof snaks !== 'object'
+                       || typeof baseRevId !== 'number'
+                       || referenceHash && typeof referenceHash !== 'string'
+                       || index && typeof index !== 'number'
+               ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
                var params = {
                        action: 'wbsetreference',
                        statement: statementGuid,
                        snaks: JSON.stringify( snaks ),
                        baserevid: baseRevId
                };
-
-               if( index === undefined && typeof referenceHash === 'number' ) {
-                       index = referenceHash;
-                       referenceHash = undefined;
-               }
 
                if( referenceHash ) {
                        params.reference = referenceHash;
@@ -558,8 +744,18 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
         */
        removeReferences: function( statementGuid, referenceHashes, baseRevId ) 
{
+               if(
+                       typeof statementGuid !== 'string'
+                       || typeof referenceHashes !== 'string' && !$.isArray( 
referenceHashes )
+                       || typeof baseRevId !== 'number'
+               ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
                var params = {
                        action: 'wbremovereferences',
                        statement: statementGuid,
@@ -586,8 +782,20 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
         */
        setSitelink: function( id, baseRevId, site, title, badges ) {
+               if(
+                       typeof id !== 'string'
+                       || typeof baseRevId !== 'number'
+                       || typeof site !== 'string'
+                       || typeof title !== 'string'
+                       || badges && typeof badges !== 'string' && !$.isArray( 
badges )
+               ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
                var params = {
                        action: 'wbsetsitelink',
                        id: id,
@@ -607,8 +815,8 @@
         * Sets a site link for an item via the API.
         * @see wikibase.api.RepoApi._post
         *
-        * @param {string} [fromId] `Entity` id to merge from.
-        * @param {string} [toId] `Entity` id to merge to.
+        * @param {string} fromId `Entity` id to merge from.
+        * @param {string} toId `Entity` id to merge to.
         * @param {string[]|string} [ignoreConflicts] Elements of the `Item` to 
ignore conflicts for.
         * @param {string} [summary] Summary for the edit.
         * @return {Object} jQuery.Promise
@@ -618,19 +826,32 @@
         * @return {Function} return.fail
         * @return {string} return.fail.code
         * @return {*} return.fail.error
+        *
+        * @throws {Error} if a parameter is not specified properly.
         */
        mergeItems: function( fromId, toId, ignoreConflicts, summary ) {
+               if(
+                       typeof fromId !== 'string'
+                       || typeof toId !== 'string'
+                       || ignoreConflicts
+                               && typeof ignoreConflicts !== 'string'
+                               && !$.isArray( ignoreConflicts )
+                       || summary && typeof summary !== 'string'
+               ) {
+                       throw new Error( 'Parameter not specified properly' );
+               }
+
                var params = {
                        action: 'wbmergeitems',
                        fromid: fromId,
                        toid: toId
                };
 
-               if ( ignoreConflicts ) {
+               if( ignoreConflicts ) {
                        params.ignoreconflicts = this._normalizeParam( 
ignoreConflicts );
                }
 
-               if ( summary ) {
+               if( summary ) {
                        params.summary = summary;
                }
 
diff --git a/tests/RepoApi.tests.js b/tests/RepoApi.tests.js
index 6578d0f..cb0a196 100644
--- a/tests/RepoApi.tests.js
+++ b/tests/RepoApi.tests.js
@@ -55,9 +55,7 @@
        var mock = mockApi();
 
        mock.api.createEntity( 'item' );
-       mock.api.createEntity( 'property', {
-               datatype: 'string'
-       } );
+       mock.api.createEntity( 'property', { 'I am': 'data' } );
 
        assert.ok( mock.spy.calledTwice, 'Triggered API calls.' );
 
@@ -81,25 +79,18 @@
 
        assert.equal(
                getParam( mock.spy, 'data', 1 ),
-               JSON.stringify( { datatype: 'string' } ),
-               'Verified submitting "datatype" field.'
+               JSON.stringify( { 'I am': 'data' } ),
+               'Verified submitting "data" field.'
        );
 } );
 
 QUnit.test( 'editEntity()', function( assert ) {
-       var mock = mockApi(),
-               data = {
-                       labels: {
-                               de: {
-                                       language: 'de',
-                                       value: 'label'
-                               }
-                       }
-               };
+       var mock = mockApi();
 
-       mock.api.editEntity( 'entity id', 12345, data );
+       mock.api.editEntity( 'entity id', 12345, { 'I am': 'entity data' }, 
true );
+       mock.api.editEntity( 'entity id', 12345, {} );
 
-       assert.ok( mock.spy.calledOnce, 'Triggered API call.' );
+       assert.ok( mock.spy.calledTwice, 'Triggered API call.' );
 
        assert.equal(
                getParam( mock.spy, 'action' ),
@@ -109,20 +100,27 @@
 
        assert.equal( getParam( mock.spy, 'id' ), 'entity id' );
        assert.equal( getParam( mock.spy, 'baserevid' ), 12345 );
-       assert.equal( getParam( mock.spy, 'data' ), JSON.stringify( data ) );
+       assert.equal( getParam( mock.spy, 'data' ), JSON.stringify( { 'I am': 
'entity data' } ) );
+       assert.equal( getParam( mock.spy, 'clear' ), true );
+
+       assert.equal( getParam( mock.spy, 'id', 1 ), 'entity id' );
+       assert.equal( getParam( mock.spy, 'baserevid', 1 ), 12345 );
+       assert.equal( getParam( mock.spy, 'data', 1 ), JSON.stringify( {} ) );
+       assert.strictEqual( getParam( mock.spy, 'clear', 1 ), undefined );
 } );
 
 QUnit.test( 'formatValue()', function( assert ) {
        var mock = mockApi( 'get' );
 
        mock.api.formatValue(
-               { datavalue: 'serialization' },
-               { option: 'option value'},
+               { 'I am': 'DataValue serialization' },
+               { option: 'option value' },
                'data type id',
                'output format'
        );
+       mock.api.formatValue( { 'I am': 'DataValue serialization' } );
 
-       assert.ok( mock.spy.calledOnce, 'Triggered API call.' );
+       assert.ok( mock.spy.calledTwice, 'Triggered API call.' );
 
        assert.equal(
                getParam( mock.spy, 'action' ),
@@ -132,11 +130,19 @@
 
        assert.equal(
                getParam( mock.spy, 'datavalue' ),
-               JSON.stringify( { datavalue: 'serialization' } )
+               JSON.stringify( { 'I am': 'DataValue serialization' } )
        );
-       assert.equal( getParam( mock.spy, 'options' ), JSON.stringify( { 
option: 'option value'} ) );
+       assert.equal( getParam( mock.spy, 'options' ), JSON.stringify( { 
option: 'option value' } ) );
        assert.equal( getParam( mock.spy, 'datatype' ), 'data type id' );
        assert.equal( getParam( mock.spy, 'generate' ), 'output format' );
+
+       assert.equal(
+               getParam( mock.spy, 'datavalue', 1 ),
+               JSON.stringify( { 'I am': 'DataValue serialization' } )
+       );
+       assert.equal( getParam( mock.spy, 'options', 1 ), JSON.stringify( {} ) 
);
+       assert.strictEqual( getParam( mock.spy, 'datatype', 1 ), undefined );
+       assert.strictEqual( getParam( mock.spy, 'generate', 1 ), undefined );
 } );
 
 QUnit.test( 'getEntities()', function( assert ) {
@@ -147,7 +153,7 @@
                ['property1', 'property2'],
                ['language code 1', 'language code 2'],
                ['sort property 1', 'sort property 2'],
-               'sort direction'
+               'ascending'
        );
 
        mock.api.getEntities(
@@ -155,10 +161,12 @@
                'property',
                'language code',
                'sort property',
-               'sort direction'
+               'descending'
        );
 
-       assert.ok( mock.spy.calledTwice, 'Triggered API calls.' );
+       mock.api.getEntities( 'entity id' );
+
+       assert.ok( mock.spy.calledThrice, 'Triggered API calls.' );
 
        assert.equal(
                getParam( mock.spy, 'action' ),
@@ -170,13 +178,19 @@
        assert.equal( getParam( mock.spy, 'props' ), 'property1|property2' );
        assert.equal( getParam( mock.spy, 'languages' ), 'language code 
1|language code 2' );
        assert.equal( getParam( mock.spy, 'sort' ), 'sort property 1|sort 
property 2' );
-       assert.equal( getParam( mock.spy, 'dir' ), 'sort direction' );
+       assert.equal( getParam( mock.spy, 'dir' ), 'ascending' );
 
        assert.equal( getParam( mock.spy, 'ids', 1 ), 'entity id' );
        assert.equal( getParam( mock.spy, 'props', 1 ), 'property' );
        assert.equal( getParam( mock.spy, 'languages', 1 ), 'language code' );
        assert.equal( getParam( mock.spy, 'sort', 1 ), 'sort property' );
-       assert.equal( getParam( mock.spy, 'dir', 1 ), 'sort direction' );
+       assert.equal( getParam( mock.spy, 'dir', 1 ), 'descending' );
+
+       assert.equal( getParam( mock.spy, 'ids', 2 ), 'entity id' );
+       assert.strictEqual( getParam( mock.spy, 'props', 2 ), undefined );
+       assert.strictEqual( getParam( mock.spy, 'languages', 2 ), undefined );
+       assert.strictEqual( getParam( mock.spy, 'sort', 2 ), undefined );
+       assert.equal( getParam( mock.spy, 'dir', 2 ), 'ascending' );
 } );
 
 QUnit.test( 'getEntitiesByPage()', function( assert ) {
@@ -184,11 +198,21 @@
 
        mock.api.getEntitiesByPage(
                ['site id 1', 'site id 2'],
+               'title',
+               ['property1', 'property2'],
+               ['language code 1', 'language code 2'],
+               ['sort property 1', 'sort property 2'],
+               'ascending',
+               true
+       );
+
+       mock.api.getEntitiesByPage(
+               'site id',
                ['title1', 'title2'],
                ['property1', 'property2'],
                ['language code 1', 'language code 2'],
                ['sort property 1', 'sort property 2'],
-               'sort direction',
+               'ascending',
                true
        );
 
@@ -198,11 +222,15 @@
                'property',
                'language code',
                'sort property',
-               'sort direction',
+               'descending',
                false
        );
 
-       assert.ok( mock.spy.calledTwice, 'Triggered API calls.' );
+       mock.api.getEntitiesByPage( 'site id', 'title' );
+       mock.api.getEntitiesByPage( ['site id'], 'title' );
+       mock.api.getEntitiesByPage( 'site id', ['title'] );
+
+       assert.equal( mock.spy.callCount, 6, 'Triggered API calls.' );
 
        assert.equal(
                getParam( mock.spy, 'action' ),
@@ -211,20 +239,52 @@
        );
 
        assert.equal( getParam( mock.spy, 'sites' ), 'site id 1|site id 2' );
-       assert.equal( getParam( mock.spy, 'titles' ), 'title1|title2' );
+       assert.equal( getParam( mock.spy, 'titles' ), 'title' );
        assert.equal( getParam( mock.spy, 'props' ), 'property1|property2' );
        assert.equal( getParam( mock.spy, 'languages' ), 'language code 
1|language code 2' );
        assert.equal( getParam( mock.spy, 'sort' ), 'sort property 1|sort 
property 2' );
-       assert.equal( getParam( mock.spy, 'dir' ), 'sort direction' );
+       assert.equal( getParam( mock.spy, 'dir' ), 'ascending' );
        assert.strictEqual( getParam( mock.spy, 'normalize' ), true );
 
        assert.equal( getParam( mock.spy, 'sites', 1 ), 'site id' );
-       assert.equal( getParam( mock.spy, 'titles', 1 ), 'title' );
-       assert.equal( getParam( mock.spy, 'props', 1 ), 'property' );
-       assert.equal( getParam( mock.spy, 'languages', 1 ), 'language code' );
-       assert.equal( getParam( mock.spy, 'sort', 1 ), 'sort property' );
-       assert.equal( getParam( mock.spy, 'dir', 1 ), 'sort direction' );
-       assert.strictEqual( getParam( mock.spy, 'normalize', 1 ), false );
+       assert.equal( getParam( mock.spy, 'titles', 1 ), 'title1|title2' );
+       assert.equal( getParam( mock.spy, 'props', 1 ), 'property1|property2' );
+       assert.equal( getParam( mock.spy, 'languages' ), 'language code 
1|language code 2' );
+       assert.equal( getParam( mock.spy, 'sort' ), 'sort property 1|sort 
property 2' );
+       assert.equal( getParam( mock.spy, 'dir', 1 ), 'ascending' );
+       assert.strictEqual( getParam( mock.spy, 'normalize', 1 ), true );
+
+       assert.equal( getParam( mock.spy, 'sites', 2 ), 'site id' );
+       assert.equal( getParam( mock.spy, 'titles', 2 ), 'title' );
+       assert.equal( getParam( mock.spy, 'props', 2 ), 'property' );
+       assert.equal( getParam( mock.spy, 'languages', 2 ), 'language code' );
+       assert.equal( getParam( mock.spy, 'sort', 2 ), 'sort property' );
+       assert.equal( getParam( mock.spy, 'dir', 2 ), 'descending' );
+       assert.strictEqual( getParam( mock.spy, 'normalize', 2 ), false );
+
+       assert.equal( getParam( mock.spy, 'sites', 3 ), 'site id' );
+       assert.equal( getParam( mock.spy, 'titles', 3 ), 'title' );
+       assert.strictEqual( getParam( mock.spy, 'props', 3 ), undefined );
+       assert.strictEqual( getParam( mock.spy, 'languages', 3 ), undefined );
+       assert.strictEqual( getParam( mock.spy, 'sort', 3 ), undefined );
+       assert.strictEqual( getParam( mock.spy, 'dir', 3 ), 'ascending' );
+       assert.strictEqual( getParam( mock.spy, 'normalize', 3 ), undefined );
+
+       assert.equal( getParam( mock.spy, 'sites', 4 ), 'site id' );
+       assert.equal( getParam( mock.spy, 'titles', 4 ), 'title' );
+       assert.strictEqual( getParam( mock.spy, 'props', 4 ), undefined );
+       assert.strictEqual( getParam( mock.spy, 'languages', 4 ), undefined );
+       assert.strictEqual( getParam( mock.spy, 'sort', 4 ), undefined );
+       assert.strictEqual( getParam( mock.spy, 'dir', 4 ), 'ascending' );
+       assert.strictEqual( getParam( mock.spy, 'normalize', 4 ), undefined );
+
+       assert.equal( getParam( mock.spy, 'sites', 5 ), 'site id' );
+       assert.equal( getParam( mock.spy, 'titles', 5 ), 'title' );
+       assert.strictEqual( getParam( mock.spy, 'props', 5 ), undefined );
+       assert.strictEqual( getParam( mock.spy, 'languages', 5 ), undefined );
+       assert.strictEqual( getParam( mock.spy, 'sort', 5 ), undefined );
+       assert.strictEqual( getParam( mock.spy, 'dir', 5 ), 'ascending' );
+       assert.strictEqual( getParam( mock.spy, 'normalize', 5 ), undefined );
 } );
 
 QUnit.test( 'parseValue()', function( assert ) {
@@ -235,8 +295,9 @@
                ['serialization1', 'serialization2'],
                { option: 'option value'}
        );
+       mock.api.parseValue( 'parser id', ['serialization'] );
 
-       assert.ok( mock.spy.calledOnce, 'Triggered API call.' );
+       assert.ok( mock.spy.calledTwice, 'Triggered API call.' );
 
        assert.equal(
                getParam( mock.spy, 'action' ),
@@ -247,14 +308,19 @@
        assert.equal( getParam( mock.spy, 'parser' ), 'parser id' );
        assert.equal( getParam( mock.spy, 'values' ), 
'serialization1|serialization2');
        assert.equal( getParam( mock.spy, 'options' ), JSON.stringify( { 
option: 'option value'} ) );
+
+       assert.equal( getParam( mock.spy, 'parser', 1 ), 'parser id' );
+       assert.equal( getParam( mock.spy, 'values', 1 ), 'serialization');
+       assert.strictEqual( getParam( mock.spy, 'options', 1 ), undefined );
 } );
 
 QUnit.test( 'searchEntities()', function( assert ) {
        var mock = mockApi( 'get' );
 
        mock.api.searchEntities( 'label', 'language code', 'entity type', 10, 5 
);
+       mock.api.searchEntities( 'label', 'language code', 'entity type' );
 
-       assert.ok( mock.spy.calledOnce, 'Triggered API call.' );
+       assert.ok( mock.spy.calledTwice, 'Triggered API call.' );
 
        assert.equal(
                getParam( mock.spy, 'action' ),
@@ -267,6 +333,12 @@
        assert.equal( getParam( mock.spy, 'type' ), 'entity type' );
        assert.equal( getParam( mock.spy, 'limit' ), 10 );
        assert.equal( getParam( mock.spy, 'continue' ), 5 );
+
+       assert.equal( getParam( mock.spy, 'search', 1 ), 'label' );
+       assert.equal( getParam( mock.spy, 'language', 1 ), 'language code' );
+       assert.equal( getParam( mock.spy, 'type', 1 ), 'entity type' );
+       assert.strictEqual( getParam( mock.spy, 'limit', 1 ), undefined );
+       assert.strictEqual( getParam( mock.spy, 'continue', 1 ), undefined );
 } );
 
 QUnit.test( 'setLabel(), setDescription()', function( assert ) {
@@ -318,8 +390,9 @@
        var mock = mockApi();
 
        mock.api.setClaim( { 'I am': 'a Claim serialization' }, 12345, 67890 );
+       mock.api.setClaim( { 'I am': 'a Claim serialization' }, 12345 );
 
-       assert.ok( mock.spy.calledOnce, 'Triggered API call.' );
+       assert.ok( mock.spy.calledTwice, 'Triggered API call.' );
 
        assert.equal(
                getParam( mock.spy, 'action' ),
@@ -333,14 +406,22 @@
        );
        assert.equal( getParam( mock.spy, 'baserevid' ), 12345 );
        assert.equal( getParam( mock.spy, 'index' ), 67890 );
+
+       assert.equal(
+               getParam( mock.spy, 'claim', 1 ),
+               JSON.stringify( { 'I am': 'a Claim serialization' } )
+       );
+       assert.equal( getParam( mock.spy, 'baserevid', 1 ), 12345 );
+       assert.strictEqual( getParam( mock.spy, 'index', 1 ), undefined );
 } );
 
 QUnit.test( 'createClaim()', function( assert ) {
        var mock = mockApi();
 
        mock.api.createClaim( 'entity id', 12345, 'snak type', 'property id', 
'snak value' );
+       mock.api.createClaim( 'entity id', 12345, 'snak type', 'property id' );
 
-       assert.ok( mock.spy.calledOnce, 'Triggered API call.' );
+       assert.ok( mock.spy.calledTwice, 'Triggered API call.' );
 
        assert.equal(
                getParam( mock.spy, 'action' ),
@@ -353,14 +434,21 @@
        assert.equal( getParam( mock.spy, 'snaktype' ), 'snak type' );
        assert.equal( getParam( mock.spy, 'property' ), 'property id' );
        assert.equal( getParam( mock.spy, 'value' ), JSON.stringify( 'snak 
value' ) );
+
+       assert.equal( getParam( mock.spy, 'entity', 1 ), 'entity id' );
+       assert.equal( getParam( mock.spy, 'baserevid', 1 ), 12345 );
+       assert.equal( getParam( mock.spy, 'snaktype', 1 ), 'snak type' );
+       assert.equal( getParam( mock.spy, 'property', 1 ), 'property id' );
+       assert.strictEqual( getParam( mock.spy, 'value', 1 ), undefined );
 } );
 
 QUnit.test( 'removeClaim()', function( assert ) {
        var mock = mockApi();
 
        mock.api.removeClaim( 'claim GUID', 12345 );
+       mock.api.removeClaim( 'claim GUID' );
 
-       assert.ok( mock.spy.calledOnce, 'Triggered API call.' );
+       assert.ok( mock.spy.calledTwice, 'Triggered API call.' );
 
        assert.equal(
                getParam( mock.spy, 'action' ),
@@ -370,14 +458,18 @@
 
        assert.equal( getParam( mock.spy, 'claim' ), 'claim GUID' );
        assert.equal( getParam( mock.spy, 'baserevid' ), 12345 );
+
+       assert.equal( getParam( mock.spy, 'claim', 1 ), 'claim GUID' );
+       assert.strictEqual( getParam( mock.spy, 'baserevid', 1 ), undefined );
 } );
 
 QUnit.test( 'getClaims()', function( assert ) {
        var mock = mockApi( 'get' );
 
        mock.api.getClaims( 'entity id', 'property id', 'claim GUID', 'rank', 
'claim props' );
+       mock.api.getClaims( 'entity id' );
 
-       assert.ok( mock.spy.calledOnce, 'Triggered API call.' );
+       assert.ok( mock.spy.calledTwice, 'Triggered API call.' );
 
        assert.equal(
                getParam( mock.spy, 'action' ),
@@ -390,14 +482,21 @@
        assert.equal( getParam( mock.spy, 'claim' ), 'claim GUID' );
        assert.equal( getParam( mock.spy, 'rank' ), 'rank' );
        assert.equal( getParam( mock.spy, 'props' ), 'claim props' );
+
+       assert.equal( getParam( mock.spy, 'entity', 1 ), 'entity id' );
+       assert.strictEqual( getParam( mock.spy, 'property', 1 ), undefined );
+       assert.strictEqual( getParam( mock.spy, 'claim', 1 ), undefined );
+       assert.strictEqual( getParam( mock.spy, 'rank', 1 ), undefined );
+       assert.strictEqual( getParam( mock.spy, 'props', 1 ), undefined );
 } );
 
 QUnit.test( 'setClaimValue()', function( assert ) {
        var mock = mockApi();
 
        mock.api.setClaimValue( 'claim GUID', 12345, 'snak type', 'property 
id', 'snak value' );
+       mock.api.setClaimValue( 'claim GUID', 12345, 'snak type', 'property id' 
);
 
-       assert.ok( mock.spy.calledOnce, 'Triggered API call.' );
+       assert.ok( mock.spy.calledTwice, 'Triggered API call.' );
 
        assert.equal(
                getParam( mock.spy, 'action' ),
@@ -410,6 +509,12 @@
        assert.equal( getParam( mock.spy, 'snaktype' ), 'snak type' );
        assert.equal( getParam( mock.spy, 'property' ), 'property id' );
        assert.equal( getParam( mock.spy, 'value' ), JSON.stringify( 'snak 
value' ) );
+
+       assert.equal( getParam( mock.spy, 'claim', 1 ), 'claim GUID' );
+       assert.equal( getParam( mock.spy, 'baserevid', 1 ), 12345 );
+       assert.equal( getParam( mock.spy, 'snaktype', 1 ), 'snak type' );
+       assert.equal( getParam( mock.spy, 'property', 1 ), 'property id' );
+       assert.strictEqual( getParam( mock.spy, 'value', 1 ), undefined );
 } );
 
 QUnit.test( 'setReference()', function( assert ) {
@@ -422,8 +527,9 @@
                'reference hash',
                67890
        );
+       mock.api.setReference( 'statement GUID', {'I am': 'serialized Snaks'}, 
12345 );
 
-       assert.ok( mock.spy.calledOnce, 'Triggered API call.' );
+       assert.ok( mock.spy.calledTwice, 'Triggered API call.' );
 
        assert.equal(
                getParam( mock.spy, 'action' ),
@@ -436,6 +542,15 @@
        assert.equal( getParam( mock.spy, 'baserevid' ), 12345 );
        assert.equal( getParam( mock.spy, 'reference' ), 'reference hash' );
        assert.equal( getParam( mock.spy, 'index' ), 67890 );
+
+       assert.equal( getParam( mock.spy, 'statement', 1 ), 'statement GUID' );
+       assert.equal(
+               getParam( mock.spy, 'snaks', 1 ),
+               JSON.stringify( {'I am': 'serialized Snaks'} )
+       );
+       assert.equal( getParam( mock.spy, 'baserevid', 1 ), 12345 );
+       assert.strictEqual( getParam( mock.spy, 'reference', 1 ), undefined );
+       assert.strictEqual( getParam( mock.spy, 'index', 1 ), undefined );
 } );
 
 QUnit.test( 'removeReferences()', function( assert ) {
@@ -461,14 +576,15 @@
        assert.equal( getParam( mock.spy, 'baserevid', 1 ), 12345 );
 } );
 
-QUnit.test( 'setSiteLink()', function( assert ) {
+QUnit.test( 'setSitelink()', function( assert ) {
        var mock = mockApi();
 
        mock.api.setSitelink(
                'entity id', 12345, 'site id', 'page name', ['entity id of 
badge1', 'entity id of badge 2']
        );
+       mock.api.setSitelink( 'entity id', 12345, 'site id', 'page name' );
 
-       assert.ok( mock.spy.calledOnce, 'Triggered API call.' );
+       assert.ok( mock.spy.calledTwice, 'Triggered API call.' );
 
        assert.equal(
                getParam( mock.spy, 'action' ),
@@ -481,6 +597,12 @@
        assert.equal( getParam( mock.spy, 'linksite' ), 'site id' );
        assert.equal( getParam( mock.spy, 'linktitle' ), 'page name' );
        assert.equal( getParam( mock.spy, 'badges' ), 'entity id of 
badge1|entity id of badge 2' );
+
+       assert.equal( getParam( mock.spy, 'id', 1 ), 'entity id' );
+       assert.equal( getParam( mock.spy, 'baserevid', 1 ), 12345 );
+       assert.equal( getParam( mock.spy, 'linksite', 1 ), 'site id' );
+       assert.equal( getParam( mock.spy, 'linktitle', 1 ), 'page name' );
+       assert.strictEqual( getParam( mock.spy, 'badges', 1 ), undefined );
 } );
 
 QUnit.test( 'mergeItems()', function( assert ) {
@@ -498,8 +620,9 @@
                'property to ignore conflict for',
                'edit summary'
        );
+       mock.api.mergeItems( 'entity id from', 'entity id to' );
 
-       assert.ok( mock.spy.calledTwice, 'Triggered API calls.' );
+       assert.ok( mock.spy.calledThrice, 'Triggered API calls.' );
 
        assert.equal(
                getParam( mock.spy, 'action' ),
@@ -522,6 +645,11 @@
                'property to ignore conflict for'
        );
        assert.equal( getParam( mock.spy, 'summary', 1 ), 'edit summary' );
+
+       assert.equal( getParam( mock.spy, 'fromid', 2 ), 'entity id from' );
+       assert.equal( getParam( mock.spy, 'toid', 2 ), 'entity id to' );
+       assert.strictEqual( getParam( mock.spy, 'ignoreconflicts', 2 ), 
undefined );
+       assert.strictEqual( getParam( mock.spy, 'summary', 2 ), undefined );
 } );
 
 }( mediaWiki, wikibase, QUnit, sinon ) );

-- 
To view, visit https://gerrit.wikimedia.org/r/177517
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I4d043f5cc43852970a489014bc5c106592ccfdc3
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/WikibaseJavaScriptApi
Gerrit-Branch: master
Gerrit-Owner: Henning Snater <henning.sna...@wikimedia.de>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to