Daniel Werner has submitted this change and it was merged. Change subject: (bug 44683) Implementing missing equals() and toJSON() methods ......................................................................
(bug 44683) Implementing missing equals() and toJSON() methods This change set implements some equals() and toJSON() methods for wb.Reference, wb.Claim and wb.Statement not yet implemented but required for implementing the setClaim API method. - patch set 4: rebase - patch set 6: Optimized QUnit tests Change-Id: I0e1d341549e253bfb411bc61960bbd57ad569c84 --- M lib/WikibaseLib.hooks.php M lib/resources/wikibase.datamodel/wikibase.Claim.js M lib/resources/wikibase.datamodel/wikibase.Reference.js M lib/resources/wikibase.datamodel/wikibase.Statement.js M lib/tests/qunit/wikibase.datamodel/Wikibase.claim.tests.js M lib/tests/qunit/wikibase.datamodel/Wikibase.reference.tests.js A lib/tests/qunit/wikibase.datamodel/wikibase.Statement.tests.js 7 files changed, 464 insertions(+), 14 deletions(-) Approvals: Daniel Werner: Verified; Looks good to me, approved jenkins-bot: Checked diff --git a/lib/WikibaseLib.hooks.php b/lib/WikibaseLib.hooks.php index e6198f4..5ab0a72 100644 --- a/lib/WikibaseLib.hooks.php +++ b/lib/WikibaseLib.hooks.php @@ -129,6 +129,7 @@ 'tests/qunit/wikibase.datamodel/Wikibase.reference.tests.js', 'tests/qunit/wikibase.datamodel/Wikibase.snak.tests.js', 'tests/qunit/wikibase.datamodel/Wikibase.SnakList.tests.js', + 'tests/qunit/wikibase.datamodel/wikibase.Statement.tests.js', 'tests/qunit/wikibase.datamodel/datamodel.Entity.tests.js', 'tests/qunit/wikibase.datamodel/datamodel.Item.tests.js', 'tests/qunit/wikibase.datamodel/datamodel.Property.tests.js', diff --git a/lib/resources/wikibase.datamodel/wikibase.Claim.js b/lib/resources/wikibase.datamodel/wikibase.Claim.js index a28d618..6c542ac 100644 --- a/lib/resources/wikibase.datamodel/wikibase.Claim.js +++ b/lib/resources/wikibase.datamodel/wikibase.Claim.js @@ -31,8 +31,7 @@ _mainSnak: null, /** - * @type wb.Snak[] - * @todo think about implementing a SnakList rather than having an Array here + * @type {wb.SnakList} */ _qualifiers: null, @@ -111,6 +110,29 @@ && this._mainSnak.equals( claim.getMainSnak() ) && this._qualifiers.equals( claim.getQualifiers() ) ); + }, + + /** + * Returns a JSON structure representing this claim. + * @since 0.4 + * + * @return {Object} + */ + toJSON: function() { + var json = { + type: wb.Claim.TYPE, + mainsnak: this._mainSnak.toJSON() + }; + + if ( this._guid ) { + json.id = this._guid; + } + + if ( this._qualifiers ) { + json.qualifiers = this._qualifiers.toJSON(); + } + + return json; } }; @@ -129,9 +151,7 @@ isStatement = json.type === 'statement'; if ( json.qualifiers !== undefined ) { - $.each( json.qualifiers, function( i, qualifier ) { - qualifiers.addSnak( wb.Snak.newFromJSON( qualifier ) ); - } ); + qualifiers = wb.SnakList.newFromJSON( json.qualifiers ); } if ( isStatement && json.references !== undefined ) { @@ -149,4 +169,11 @@ return new wb.Claim( mainSnak, qualifiers, guid ); }; +/** + * String to identify if the object is a statement or a claim. + * @since 0.4 + * @type {string} + */ +wb.Claim.TYPE = 'claim'; + }( wikibase, jQuery ) ); diff --git a/lib/resources/wikibase.datamodel/wikibase.Reference.js b/lib/resources/wikibase.datamodel/wikibase.Reference.js index cf71051..8d3f34d 100644 --- a/lib/resources/wikibase.datamodel/wikibase.Reference.js +++ b/lib/resources/wikibase.datamodel/wikibase.Reference.js @@ -65,7 +65,37 @@ */ setSnaks: function( snaks ) { this._snaks = new wb.SnakList( snaks ); + }, + + /** + * Will return whether a given reference equals this one. This will compare the reference's + * snaks only and not involve checking the hash. + * + * @param {wb.Reference} reference + * @return {boolean} + */ + equals: function( reference ) { + return ( this._snaks.equals( reference.getSnaks() ) ); + }, + + /** + * Returns a JSON structure representing this reference. + * @since 0.4 + * + * @return {Object} + */ + toJSON: function() { + var json = { + snaks: this._snaks.toJSON() + }; + + if ( this._hash ) { + json.hash = this._hash; + } + + return json; } + }; wb.Reference.newFromJSON = function( json ) { diff --git a/lib/resources/wikibase.datamodel/wikibase.Statement.js b/lib/resources/wikibase.datamodel/wikibase.Statement.js index ff8db7d..8ce88a5 100644 --- a/lib/resources/wikibase.datamodel/wikibase.Statement.js +++ b/lib/resources/wikibase.datamodel/wikibase.Statement.js @@ -11,7 +11,7 @@ constructor = function( mainSnak, qualifiers, references, rank, guid ) { PARENT.call( this, mainSnak, qualifiers, guid ); this.setReferences( references || [] ); - this.setRank( rank === undefined ? this.RANK.NORMAL : rank ); + this.setRank( rank === undefined ? wb.Statement.RANK.NORMAL : rank ); }; /** @@ -23,15 +23,14 @@ * * @param {wb.Snak} mainSnak * @param {wb.Snak[]} [qualifiers] - * @param {Array} [references] An array of arrays of Snaks or empty array + * @param {wb.Reference[]} [references] An array of references or an empty array * @param {Number} [rank] * @param {String|null} [guid] The Global Unique Identifier of this Statement. Can be omitted or null * if this is a new Statement, not yet stored in the database and associated with some entity. */ wb.Statement = wb.utilities.inherit( 'WbStatement', PARENT, constructor, { /** - * @type Array - * @todo determine whether we should rather model a Reference object for this + * @type {wb.Reference[]} * @todo think about implementing a ReferenceList/ClaimList rather than having an Array here */ _references: null, @@ -43,10 +42,10 @@ _rank: null, /** - * Returns all of the statements references. + * Returns all of the statement's references. * * sufficient - * @return {Array} An array of arrays of Snaks or an empty array. + * @return {wb.Reference[]|null} An array of references or an empty array. */ getReferences: function() { return this._references; @@ -55,7 +54,7 @@ /** * Overwrites the current set of the statements references. * - * @param {Array} references An array of arrays of Snaks or an empty array. + * @param {wb.Reference[]} references An array of references or an empty array. */ setReferences: function( references ) { if( !$.isArray( references ) ) { @@ -87,7 +86,78 @@ } } throw new Error( 'Can not set unknown Statement rank "' + rank + '"' ); + }, + + /** + * Returns whether this statement is equal to another statement. + * @see wb.Claim.equals + * @since 0.4 + * + * @param {wb.Statement} statement + * @return {boolean} + */ + equals: function( statement ) { + if ( this === statement ) { + return true; + } else if ( + !( statement instanceof wb.Statement ) + || !PARENT.prototype.equals.call( this, statement ) + || this._references.length !== statement.getReferences().length + || this._rank !== statement.getRank() + ) { + return false; + } + + // Check if references are equal: + var equals = true; + $.each( this._references, function( myI, myReference ) { + var found = false; + $.each( statement.getReferences(), function( yourI, yourReference ) { + if ( myReference.equals( yourReference ) ) { + found = true; + return false; + } + } ); + if ( !found ) { + equals = false; + return false; + } + } ); + + return equals; + }, + + /** + * Returns a JSON structure representing this statement. + * @since 0.4 + * + * @return {Object} + */ + toJSON: function() { + var self = this, + json = PARENT.prototype.toJSON.call( this ); + + json.type = wb.Statement.TYPE; + + if ( this._references && this._references.length > 0 ) { + json.references = []; + $.each( this._references, function( i, reference ) { + json.references.push( reference.toJSON() ); + } ); + } + + if ( this._rank ) { + $.each( wb.Statement.RANK, function ( rank, i ) { + if ( self._rank === i ) { + json.rank = rank.toLowerCase(); + return false; + } + } ); + } + + return json; } + } ); /** @@ -100,4 +170,9 @@ DEPRECATED: 0 }; +/** + * @see wb.Claim.TYPE + */ +wb.Statement.TYPE = 'statement'; + }( wikibase, jQuery ) ); diff --git a/lib/tests/qunit/wikibase.datamodel/Wikibase.claim.tests.js b/lib/tests/qunit/wikibase.datamodel/Wikibase.claim.tests.js index c390294..259525e 100644 --- a/lib/tests/qunit/wikibase.datamodel/Wikibase.claim.tests.js +++ b/lib/tests/qunit/wikibase.datamodel/Wikibase.claim.tests.js @@ -7,12 +7,13 @@ * * @licence GNU GPL v2+ * @author Jeroen De Dauw < jeroended...@gmail.com > + * @author H. Snater < mediaw...@snater.com > */ ( function( wb, dv, $, QUnit ) { 'use strict'; - QUnit.module( 'wikibase.datamodel.claim.js', QUnit.newMwEnvironment() ); + QUnit.module( 'wikibase.datamodel.Claim', QUnit.newWbEnvironment() ); QUnit.test( 'constructor', function( assert ) { var argumentLists = [ @@ -77,4 +78,89 @@ } ); } ); + QUnit.test( 'toJSON()', function( assert ) { + var claim = new wb.Claim( new wb.PropertyValueSnak( 42, new dv.StringValue( '~=[,,_,,]:3' ) ) ); + + assert.ok( + claim.equals( wb.Claim.newFromJSON( claim.toJSON() ) ), + 'Exported simple claim to JSON.' + ); + + claim = new wb.Claim( + new wb.PropertyNoValueSnak( 42 ), + new wb.SnakList( + [ + new wb.PropertyNoValueSnak( 9001 ), + new wb.PropertySomeValueSnak( 42 ), + new wb.PropertyValueSnak( 23, new dv.StringValue( '~=[,,_,,]:3' ) ) + ] + ) + ); + + assert.ok( + claim.equals( wb.Claim.newFromJSON( claim.toJSON() ) ), + 'Exported complex claim to JSON.' + ); + } ); + + QUnit.test( 'equals()', function( assert ) { + var claims = [ + new wb.Claim( new wb.PropertyValueSnak( 42, new dv.StringValue( 'string' ) ) ), + new wb.Claim( + new wb.PropertyValueSnak( 42, new dv.StringValue( 'string' ) ), + new wb.SnakList( + [ + new wb.PropertyValueSnak( 2, new dv.StringValue( 'some string' ) ), + new wb.PropertySomeValueSnak( 9001 ) + ] + ) + ), + new wb.Claim( new wb.PropertyValueSnak( 42, new dv.StringValue( 'other string' ) ) ), + new wb.Claim( new wb.PropertySomeValueSnak( 9001 ) ), + new wb.Claim( + new wb.PropertyValueSnak( 42, new dv.StringValue( 'string' ) ), + new wb.SnakList( + [ + new wb.PropertyValueSnak( 43, new dv.StringValue( 'some string' ) ), + new wb.PropertySomeValueSnak( 9001 ) + ] + ) + ) + ]; + + // Compare claims: + $.each( claims, function( i, claim ) { + var clonedClaim = wb.Claim.newFromJSON( claim.toJSON() ); + + // Check if "cloned" claim is equal: + assert.ok( + claim.equals( clonedClaim ), + 'Verified claim "' + i + '" on equality.' + ); + + // Compare to all other claims: + $.each( claims, function( j, otherClaim ) { + if ( j !== i ) { + assert.ok( + !claim.equals( otherClaim ), + 'Claim "' + i + '" is not equal to claim "'+ j + '".' + ); + } + } ); + + } ); + + // Compare claim to statement: + var claim = new wb.Claim( new wb.PropertyValueSnak( 42, new dv.StringValue( 'string' ) ) ), + statement = new wb.Statement( + new wb.PropertyValueSnak( 42, new dv.StringValue( 'string' ) ) + ); + + assert.ok( + claim.equals( statement ), + 'Claim equals statement that received the same initialization parameters.' + ); + + } ); + }( wikibase, dataValues, jQuery, QUnit ) ); diff --git a/lib/tests/qunit/wikibase.datamodel/Wikibase.reference.tests.js b/lib/tests/qunit/wikibase.datamodel/Wikibase.reference.tests.js index b7f662a..741ed9b 100644 --- a/lib/tests/qunit/wikibase.datamodel/Wikibase.reference.tests.js +++ b/lib/tests/qunit/wikibase.datamodel/Wikibase.reference.tests.js @@ -8,12 +8,13 @@ * @licence GNU GPL v2+ * @author Jeroen De Dauw < jeroended...@gmail.com > * @author Daniel Werner < daniel.wer...@wikimedia.de > + * @author H. Snater < mediaw...@snater.com > */ ( function( wb, dv, $, QUnit, undefined ) { 'use strict'; - QUnit.module( 'wikibase.datamodel.reference.js', QUnit.newMwEnvironment() ); + QUnit.module( 'wikibase.datamodel.Reference', QUnit.newWbEnvironment() ); var snakLists = [ new wb.SnakList( [ @@ -73,4 +74,67 @@ ); } ); + QUnit.test( 'toJSON()', function( assert ) { + var reference = new wb.Reference( + new wb.SnakList( + [ + new wb.PropertyValueSnak( 42, new dv.StringValue( 'string' ) ), + new wb.PropertySomeValueSnak( 9001 ) + ] + ), + 'hash12390213' + ); + + assert.ok( + reference.equals( wb.Reference.newFromJSON( reference.toJSON() ) ), + 'Exported reference to JSON.' + ); + } ); + + QUnit.test( 'equals()', function( assert ) { + var references = [ + new wb.Reference(), + new wb.Reference( + new wb.SnakList( + [ + new wb.PropertyValueSnak( 42, new dv.StringValue( 'string' ) ), + new wb.PropertySomeValueSnak( 9001 ) + ] + ), + 'hash12390213' + ), + new wb.Reference( + new wb.SnakList( + [ + new wb.PropertyValueSnak( 345, new dv.StringValue( 'string' ) ), + new wb.PropertySomeValueSnak( 9001 ) + ] + ) + ) + ]; + + // Compare references: + $.each( references, function( i, reference ) { + var clonedReference = wb.Reference.newFromJSON( reference.toJSON() ); + + // Check if "cloned" reference is equal: + assert.ok( + reference.equals( clonedReference ), + 'Verified reference "' + i + '" on equality.' + ); + + // Compare to all other references: + $.each( references, function( j, otherReference ) { + if ( j !== i ) { + assert.ok( + !reference.equals( otherReference ), + 'Reference "' + i + '" is not equal to reference "'+ j + '".' + ); + } + } ); + + } ); + + } ); + }( wikibase, dataValues, jQuery, QUnit ) ); diff --git a/lib/tests/qunit/wikibase.datamodel/wikibase.Statement.tests.js b/lib/tests/qunit/wikibase.datamodel/wikibase.Statement.tests.js new file mode 100644 index 0000000..e55378e --- /dev/null +++ b/lib/tests/qunit/wikibase.datamodel/wikibase.Statement.tests.js @@ -0,0 +1,167 @@ +/** + * QUnit tests for wikibase.Statement + * @see https://www.mediawiki.org/wiki/Extension:Wikibase + * + * @since 0.4 + * @ingroup WikibaseLib + * + * @licence GNU GPL v2+ + * @author H. Snater < mediaw...@snater.com > + */ + +( function( wb, dv, $, QUnit ) { + 'use strict'; + + QUnit.module( 'wikibase.datamodel.Statement', QUnit.newWbEnvironment() ); + + QUnit.test( 'toJSON', function( assert ) { + var statement = new wb.Statement( new wb.PropertyNoValueSnak( 42 ) ); + + assert.ok( + statement.equals( wb.Claim.newFromJSON( statement.toJSON() ) ), + 'Exported simple statement to JSON.' + ); + + statement = new wb.Statement( + new wb.PropertyValueSnak( 23, new dv.StringValue( '~=[,,_,,]:3' ) ), + new wb.SnakList( + [ + new wb.PropertyNoValueSnak( 9001 ), + new wb.PropertySomeValueSnak( 42 ) + ] + ), + [ + new wb.Reference( + new wb.SnakList( + [ + new wb.PropertyValueSnak( 3, new dv.StringValue( 'string' ) ), + new wb.PropertySomeValueSnak( 245 ) + ] + ) + ), + new wb.Reference( + new wb.SnakList( + [ + new wb.PropertyValueSnak( 856, new dv.StringValue( 'another string' ) ), + new wb.PropertySomeValueSnak( 97 ) + ] + ) + ) + ], + wb.Statement.RANK.PREFERRED + ); + + assert.ok( + statement.equals( wb.Claim.newFromJSON( statement.toJSON() ) ), + 'Exported complex statement to JSON.' + ); + + } ); + + QUnit.test( 'equals()', function( assert ) { + var statements = [ + new wb.Statement( new wb.PropertyValueSnak( 42, new dv.StringValue( 'string' ) ) ), + new wb.Statement( + new wb.PropertyValueSnak( 42, new dv.StringValue( 'string' ) ), + new wb.SnakList( + [ + new wb.PropertyValueSnak( 2, new dv.StringValue( 'some string' ) ), + new wb.PropertySomeValueSnak( 9001 ) + ] + ), + [ + new wb.Reference( + new wb.SnakList( + [ + new wb.PropertyValueSnak( 3, new dv.StringValue( 'string' ) ), + new wb.PropertySomeValueSnak( 245 ) + ] + ) + ), + new wb.Reference( + new wb.SnakList( + [ + new wb.PropertyValueSnak( 856, new dv.StringValue( 'another string' ) ), + new wb.PropertySomeValueSnak( 97 ) + ] + ) + ) + ], + wb.Statement.RANK.PREFERRED + ), + new wb.Statement( new wb.PropertyValueSnak( 41, new dv.StringValue( 'string' ) ) ), + new wb.Statement( + new wb.PropertyValueSnak( 42, new dv.StringValue( 'string' ) ), + new wb.SnakList( + [ + new wb.PropertyValueSnak( 2, new dv.StringValue( 'some string' ) ), + new wb.PropertySomeValueSnak( 9001 ) + ] + ) + ), + new wb.Statement( + new wb.PropertyValueSnak( 42, new dv.StringValue( 'string' ) ), + new wb.SnakList( + [ + new wb.PropertyValueSnak( 2, new dv.StringValue( 'some string' ) ), + new wb.PropertySomeValueSnak( 9001 ) + ] + ), + [ + new wb.Reference( + new wb.SnakList( + [ + new wb.PropertyValueSnak( 3, new dv.StringValue( 'string' ) ), + new wb.PropertySomeValueSnak( 245 ) + ] + ) + ), + new wb.Reference( + new wb.SnakList( + [ + new wb.PropertyValueSnak( 123, new dv.StringValue( 'another string' ) ), + new wb.PropertySomeValueSnak( 97 ) + ] + ) + ) + ], + wb.Statement.RANK.PREFERRED + ) + ]; + + // Compare statements: + $.each( statements, function( i, statement ) { + var clonedStatement = wb.Claim.newFromJSON( statement.toJSON() ); + + // Check if "cloned" statement is equal: + assert.ok( + statement.equals( clonedStatement ), + 'Verified statement "' + i + '" on equality.' + ); + + // Compare to all other statements: + $.each( statements, function( j, otherStatement ) { + if ( j !== i ) { + assert.ok( + !statement.equals( otherStatement ), + 'Statement "' + i + '" is not equal to statement "'+ j + '".' + ); + } + } ); + + } ); + + // Compare claim to statement: + var claim = new wb.Claim( new wb.PropertyValueSnak( 42, new dv.StringValue( 'string' ) ) ), + statement = new wb.Statement( + new wb.PropertyValueSnak( 42, new dv.StringValue( 'string' ) ) + ); + + assert.ok( + !statement.equals( claim ), + 'Statement does not equal claim that received the same initialization parameters.' + ); + + } ); + +}( wikibase, dataValues, jQuery, QUnit ) ); -- To view, visit https://gerrit.wikimedia.org/r/53325 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I0e1d341549e253bfb411bc61960bbd57ad569c84 Gerrit-PatchSet: 6 Gerrit-Project: mediawiki/extensions/Wikibase Gerrit-Branch: master Gerrit-Owner: Henning Snater <henning.sna...@wikimedia.de> Gerrit-Reviewer: Daniel Werner <daniel.wer...@wikimedia.de> Gerrit-Reviewer: jenkins-bot _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits