Ferdbold has uploaded a new change for review.

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

Change subject: Added unit testing for ext.graph.visualEditor
......................................................................

Added unit testing for ext.graph.visualEditor

* Basic unit test suites for ve.dm.MWGraphNode and ve.dm.MWGraphModel

Change-Id: I5de80394a99a552942d5454d89765d9f2b5f76bd
---
M .jshintrc
M Graph.hooks.php
M extension.json
A modules/ve-graph/tests/ext.graph.visualEditor.test.js
M modules/ve-graph/ve.dm.MWGraphNode.js
5 files changed, 416 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Graph 
refs/changes/61/219261/1

diff --git a/.jshintrc b/.jshintrc
index c198255..d11f205 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -21,6 +21,7 @@
                "mediaWiki": false,
                "OO": false,
                "ve": false,
-               "vg": false
+               "vg": false,
+               "QUnit": false
        }
 }
diff --git a/Graph.hooks.php b/Graph.hooks.php
index 69fbe54..4d8941b 100644
--- a/Graph.hooks.php
+++ b/Graph.hooks.php
@@ -53,4 +53,26 @@
 
                return true;
        }
+
+       /**
+        * Register the unit testing module for the ext.graph.visualEditor 
module
+        *
+        * @param array $testModules The array of registered test modules
+        * @param ResourceLoader $resourceLoader The reference to the resource 
laoder
+        * @return true
+        */
+       public static function onResourceLoaderTestModules( array 
&$testModules, ResourceLoader &$resourceLoader ) {
+               $testModules['qunit']['ext.graph.visualEditor.test'] = array(
+                       'scripts' => array(
+                               
'modules/ve-graph/tests/ext.graph.visualEditor.test.js'
+                       ),
+                       'dependencies' => array(
+                               'ext.graph.visualEditor'
+                       ),
+                       'localBasePath' => __DIR__,
+                       'remoteExtPath' => 'Graph'
+               );
+
+               return true;
+       }
 }
diff --git a/extension.json b/extension.json
index 7ee5283..70ff40a 100644
--- a/extension.json
+++ b/extension.json
@@ -63,6 +63,9 @@
                ],
                "ResourceLoaderRegisterModules": [
                        "GraphHooks::onResourceLoaderRegisterModules"
+               ],
+               "ResourceLoaderTestModules": [
+                       "GraphHooks::onResourceLoaderTestModules"
                ]
        },
        "VisualEditorPluginModules": [
diff --git a/modules/ve-graph/tests/ext.graph.visualEditor.test.js 
b/modules/ve-graph/tests/ext.graph.visualEditor.test.js
new file mode 100644
index 0000000..2565583
--- /dev/null
+++ b/modules/ve-graph/tests/ext.graph.visualEditor.test.js
@@ -0,0 +1,384 @@
+/*!
+ * VisualEditor MWGraphNode tests.
+ */
+
+QUnit.module( 'ext.graph.visualEditor' );
+
+/* Sample specs */
+
+var sampleSpecs = {
+       areaGraph: {
+               width: 500,
+               height: 200,
+               padding: {
+                       top: 10,
+                       left: 30,
+                       bottom: 30,
+                       right: 10
+               },
+               data: [
+                       {
+                               name: 'table',
+                               values: [
+                                       {
+                                               x: 0,
+                                               y: 28
+                                       },
+                                       {
+                                               x: 1,
+                                               y: 43
+                                       },
+                                       {
+                                               x: 2,
+                                               y: 81
+                                       },
+                                       {
+                                               x: 3,
+                                               y: 19
+                                       }
+                               ]
+                       }
+               ],
+               scales: [
+                       {
+                               name: 'x',
+                               type: 'linear',
+                               range: 'width',
+                               zero: false,
+                               domain: {
+                                       data: 'table',
+                                       field: 'data.x'
+                               }
+                       },
+                       {
+                               name: 'y',
+                               type: 'linear',
+                               range: 'height',
+                               nice: true,
+                               domain: {
+                                       data: 'table',
+                                       field: 'data.y'
+                               }
+                       }
+               ],
+               axes: [
+                       {
+                               type: 'x',
+                               scale: 'x'
+                       },
+                       {
+                               type: 'y',
+                               scale: 'y'
+                       }
+               ],
+               marks: [
+                       {
+                               type: 'area',
+                               from: {
+                                       data: 'table'
+                               },
+                               properties: {
+                                       enter: {
+                                               interpolate: {
+                                                       value: 'monotone'
+                                               },
+                                               x: {
+                                                       scale: 'x',
+                                                       field: 'data.x'
+                                               },
+                                               y: {
+                                                       scale: 'y',
+                                                       field: 'data.y'
+                                               },
+                                               y2: {
+                                                       scale: 'y',
+                                                       value: 0
+                                               },
+                                               fill: {
+                                                       value: 'steelblue'
+                                               }
+                                       }
+                               }
+                       }
+               ]
+       },
+
+       stackedAreaGraph: {
+           width: 500,
+           height: 200,
+           padding: {
+               top: 10,
+               left: 30,
+               bottom: 30,
+               right: 10
+           },
+           data: [
+               {
+                   name: 'table',
+                   values: [
+                       {
+                           x: 0,
+                           y: 28,
+                           c: 0
+                       },
+                       {
+                           x: 0,
+                           y: 55,
+                           c: 1
+                       },
+                       {
+                           x: 1,
+                           y: 43,
+                           c: 0
+                       },
+                       {
+                           x: 1,
+                           y: 91,
+                           c: 1
+                       },
+                       {
+                           x: 2,
+                           y: 81,
+                           c: 0
+                       },
+                       {
+                           x: 2,
+                           y: 53,
+                           c: 1
+                       },
+                       {
+                           x: 3,
+                           y: 19,
+                           c: 0
+                       },
+                       {
+                           x: 3,
+                           y: 87,
+                           c: 1
+                       },
+                       {
+                           x: 4,
+                           y: 52,
+                           c: 0
+                       },
+                       {
+                           x: 4,
+                           y: 48,
+                           c: 1
+                       },
+                       {
+                           x: 5,
+                           y: 24,
+                           c: 0
+                       },
+                       {
+                           x: 5,
+                           y: 49,
+                           c: 1
+                       },
+                       {
+                           x: 6,
+                           y: 87,
+                           c: 0
+                       },
+                       {
+                           x: 6,
+                           y: 66,
+                           c: 1
+                       },
+                       {
+                           x: 7,
+                           y: 17,
+                           c: 0
+                       },
+                       {
+                           x: 7,
+                           y: 27,
+                           c: 1
+                       },
+                       {
+                           x: 8,
+                           y: 68,
+                           c: 0
+                       },
+                       {
+                           x: 8,
+                           y: 16,
+                           c: 1
+                       },
+                       {
+                           x: 9,
+                           y: 49,
+                           c: 0
+                       },
+                       {
+                           x: 9,
+                           y: 15,
+                           c: 1
+                       }
+                   ]
+               },
+               {
+                   name: 'stats',
+                   source: 'table',
+                   transform: [
+                       {
+                           type: 'facet',
+                           keys: [
+                               'data.x'
+                           ]
+                       },
+                       {
+                           type: 'stats',
+                           value: 'data.y'
+                       }
+                   ]
+               }
+           ],
+           scales: [
+               {
+                   name: 'x',
+                   type: 'linear',
+                   range: 'width',
+                   zero: false,
+                   domain: {
+                       data: 'table',
+                       field: 'data.x'
+                   }
+               },
+               {
+                   name: 'y',
+                   type: 'linear',
+                   range: 'height',
+                   nice: true,
+                   domain: {
+                       data: 'stats',
+                       field: 'sum'
+                   }
+               },
+               {
+                   name: 'color',
+                   type: 'ordinal',
+                   range: 'category10'
+               }
+           ],
+           axes: [
+               {
+                   type: 'x',
+                   scale: 'x'
+               },
+               {
+                   type: 'y',
+                   scale: 'y'
+               }
+           ],
+           marks: [
+               {
+                   type: 'group',
+                   from: {
+                       data: 'table',
+                       transform: [
+                           {
+                               type: 'facet',
+                               keys: [
+                                   'data.c'
+                               ]
+                           },
+                           {
+                               type: 'stack',
+                               point: 'data.x',
+                               height: 'data.y'
+                           }
+                       ]
+                   },
+                   marks: [
+                       {
+                           type: 'area',
+                           properties: {
+                               enter: {
+                                   interpolate: {
+                                       value: 'monotone'
+                                   },
+                                   x: {
+                                       scale: 'x',
+                                       field: 'data.x'
+                                   },
+                                   y: {
+                                       scale: 'y',
+                                       field: 'y'
+                                   },
+                                   y2: {
+                                       scale: 'y',
+                                       field: 'y2'
+                                   },
+                                   fill: {
+                                       scale: 'color',
+                                       field: 'data.c'
+                                   }
+                               },
+                               update: {
+                                   fillOpacity: {
+                                       value: 1
+                                   }
+                               },
+                               hover: {
+                                   fillOpacity: {
+                                       value: 0.5
+                                   }
+                               }
+                           }
+                       }
+                   ]
+               }
+           ]
+       }
+};
+
+
+
+/* Tests */
+
+QUnit.test( 've.dm.MWGraphNode', 5, function ( assert ) {
+       var node = new ve.dm.MWGraphNode(),
+               specString = JSON.stringify( sampleSpecs.areaGraph );
+
+       assert.deepEqual( node.getSpec(), null, 'MWGraphNode spec is 
initialized to null' );
+
+       node.setSpecFromString( specString );
+       assert.deepEqual( node.getSpec(), sampleSpecs.areaGraph, 'Basic valid 
spec is parsed' );
+
+       node.setSpecFromString( '{}' );
+       assert.deepEqual( node.getSpec(), null, 'Empty spec string results in a 
null spec' );
+
+       node.setSpecFromString( 'invalid JSON string' );
+       assert.deepEqual( node.getSpec(), null, 'Setting an invalid resets the 
spec to null' );
+
+       node.updateSpec( sampleSpecs.areaGraph );
+       assert.deepEqual( node.getSpec(), sampleSpecs.areaGraph, 'Updating the 
spec through object extension' );
+} );
+
+// FIXME: The parser here still treats <graph> tags as alien inline nodes,
+// while the actual VE environment recognizes the tag correctly.
+// This test is unusable until then.
+/* QUnit.test( 've.ce.MWGraphNode', 2, function ( assert ) {
+       var view = ve.test.utils.createSurfaceViewFromHtml(
+                       '<graph></graph>'
+               ),
+               documentNode = view.getDocument().getDocumentNode(),
+               node = documentNode.children[0].children[0];
+
+       assert.equal( node.type, 'mwGraph', '<graph> tags are properly 
recognized as a graph node' );
+
+       assert.equal( $( node.$element[0] ).text(), ve.msg( 'graph-ve-no-spec' 
), 'A null spec displays an error message' );
+} ); */
+
+QUnit.test( 've.dm.MWGraphModel', 1, function ( assert ) {
+       var model = new ve.dm.MWGraphModel( sampleSpecs.areaGraph );
+
+       model.setSpecFromString( JSON.stringify( sampleSpecs.stackedAreaGraph ) 
);
+       assert.equal( model.hasBeenChanged(), true, 'Model recognizes changes 
to spec' );
+} );
+
+// TODO: ve.ce.MWGraphNode (see FIXME notice above)
+// TODO: ve.ui.MWGraphDialog
+// TODO: ve.ui.MWGraphDialogTool
diff --git a/modules/ve-graph/ve.dm.MWGraphNode.js 
b/modules/ve-graph/ve.dm.MWGraphNode.js
index 2202a85..7313ecd 100644
--- a/modules/ve-graph/ve.dm.MWGraphNode.js
+++ b/modules/ve-graph/ve.dm.MWGraphNode.js
@@ -58,11 +58,15 @@
 /**
  * Parses a spec string and returns its object representation.
  *
- * @param {string} str The spec string to validate
+ * @param {string} str The spec string to validate. If the string is null or 
represents an empty object, the spec will be null.
  * @return {Object|null} The object specification if the parsing was 
successful, null otherwise
  */
 ve.dm.MWGraphNode.static.parseSpecString = function ( str ) {
        try {
+               // Passing an empty spec sets the spec to null.
+               if ( str === '{}' ) {
+                       return null;
+               }
                return JSON.parse( str );
        } catch ( err ) {
                return null;

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I5de80394a99a552942d5454d89765d9f2b5f76bd
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Graph
Gerrit-Branch: master
Gerrit-Owner: Ferdbold <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to