From 733161aef01772ee4830ba3ada05176ea65438bf Mon Sep 17 00:00:00 2001 From: Martijn van de Rijdt Date: Fri, 1 Apr 2016 12:13:29 -0600 Subject: [PATCH] fixed: split up test that are failing in phantomJS on Travis, #363 --- CHANGELOG.md | 2 +- Gruntfile.js | 2 +- package.json | 2 +- src/js/Form-model.js | 2 +- test/browser-karma.conf.js | 77 ++++++++++++ test/spec/formmodel.browser-spec.js | 175 ++++++++++++++++++++++++++++ test/spec/formmodel.spec.js | 173 --------------------------- 7 files changed, 256 insertions(+), 177 deletions(-) create mode 100644 test/browser-karma.conf.js create mode 100644 test/spec/formmodel.browser-spec.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 23bfad4ca..349ce2406 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ Change Log All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -[Unreleased] +[4.5.13] - 2016-04-01 --------------------- ##### Changed - Select minimal widget is now scrollable and won't stretch form. diff --git a/Gruntfile.js b/Gruntfile.js index a6455b13e..1ac349556 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -85,7 +85,7 @@ module.exports = function( grunt ) { browsers: [ 'PhantomJS' ] }, browsers: { - configFile: 'test/karma.conf.js', + configFile: 'test/browser-karma.conf.js', browsers: [ 'Chrome', 'ChromeCanary', 'Firefox', /*'Opera',*/ 'Safari' ] } }, diff --git a/package.json b/package.json index 47ae51972..e47d85a37 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "enketo-core", "description": "Extensible Enketo core containing the form logic engine and responsive form styling", "homepage": "https://enketo.org", - "version": "4.5.12", + "version": "4.5.13", "license": "Apache-2.0", "os": [ "darwin", diff --git a/src/js/Form-model.js b/src/js/Form-model.js index ba20acb31..e80ca5e50 100644 --- a/src/js/Form-model.js +++ b/src/js/Form-model.js @@ -93,7 +93,7 @@ define( function( require, exports, module ) { instanceDoc.appendChild( $.parseXML( instance.xmlStr ).firstChild ); } ); } catch ( e ) { - console.error( e ); + console.error( 'parseXML error' ); this.loadErrors.push( 'Error trying to parse XML ' + id + '. ' + e.message ); } diff --git a/test/browser-karma.conf.js b/test/browser-karma.conf.js new file mode 100644 index 000000000..043dffe43 --- /dev/null +++ b/test/browser-karma.conf.js @@ -0,0 +1,77 @@ +// Karma configuration +// Generated on Mon Mar 16 2015 13:42:33 GMT-0600 (MDT) + +module.exports = function( config ) { + config.set( { + + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: '..', + + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: [ 'browserify', 'jasmine' ], + + + // list of files / patterns to load in the browser + files: [ + 'test/mock/*.js', + 'test/spec/*spec.js', { + pattern: 'src/js/*.js', + included: false + }, { + pattern: 'src/widget/*/*.*', + included: false + }, { + pattern: 'config.json', + included: false + } + ], + + + // list of files to exclude + exclude: [], + + + // preprocess matching files before serving them to the browser + // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: { + 'test/**/*.js': [ 'browserify' ], + }, + + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: [ 'progress' ], + + + // web server port + port: 9876, + + + // enable / disable colors in the output (reporters and logs) + colors: true, + + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_INFO, + + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: false, + + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + browsers: [], + + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: false, + + browserify: {}, + } ); +}; diff --git a/test/spec/formmodel.browser-spec.js b/test/spec/formmodel.browser-spec.js new file mode 100644 index 000000000..deb91614c --- /dev/null +++ b/test/spec/formmodel.browser-spec.js @@ -0,0 +1,175 @@ +/* global describe, require, it */ +var Model = require( '../../src/js/Form-model' ); + +describe( 'merging an instance into the model', function() { + + describe( '', function() { + [ + // partial record, empty + [ '', '', '' ], + // record value overrides model (default) value + [ 'record', 'model', 'record' ], + // record value overrides model (default) value with an empty value + [ '', 'default', '' ], + // record value overrides model (default) value inside a repeat with an empty value + [ '', 'default1default2', + '' + ], + // preserve non-alphabetic document order of model + [ '', '', '' ], + // repeated nodes in record get added (including repeat childnodes that are missing from record) + [ 'record', 'model', + 'record' + ], + // repeated nodes in record get added in the right order + [ '', '', '' ], + // repeated groups with missing template nodes in record get added + [ '', '', '' ], + // unused model namespaces preserved: + [ 'record', '', 'record' ], + // used model namespaces preserved (though interestingly the result includes a duplicate namespace declaration - probably a minor bug in merge-xml-js) + [ 'record', '', + 'record' + ], + // namespaces used in both record and model (though now with triple equal namespace declarations..: + [ 'recorda', + '', + 'recorda' + ], + // record and model contain same node but in different namespace creates 2nd meta groups and 2 instanceID nodes! + [ 'a', + '', + 'a' + ], + // model has xml declaration and instance has not + [ '', '', + '' + ], + // record and instance have different default namespace + [ 'record', + '', + 'record' + ] + ].forEach( function( test ) { + var result, expected, + model = new Model( { + modelStr: test[ 1 ] + } ); + + model.init(); + model.mergeXml( test[ 0 ] ); + + result = ( new XMLSerializer() ).serializeToString( model.xml, 'text/xml' ).replace( /\n/g, '' ); + expected = test[ 2 ]; + + it( 'produces the expected result for instance: ' + test[ 0 ], function() { + expect( result ).toEqual( expected ); + } ); + } ); + } ); + + describe( 'when a deprecatedID node is not present in the form format', function() { + var model = new Model( { + modelStr: '', + instanceStr: '7c990ed9-8aab-42ba-84f5-bf23277154ad2012' + } ); + + var loadErrors = model.init(); + + it( 'outputs no load errors', function() { + expect( loadErrors.length ).toEqual( 0 ); + } ); + + it( 'adds a deprecatedID node', function() { + expect( model.node( '/thedata/meta/deprecatedID' ).get().length ).toEqual( 1 ); + } ); + + //this is an important test even though it may not seem to be... + it( 'includes the deprecatedID in the string to be submitted', function() { + expect( model.getStr().indexOf( '' ) ).not.toEqual( -1 ); + } ); + + it( 'gives the new deprecatedID node the old value of the instanceID node of the instance-to-edit', function() { + expect( model.node( '/thedata/meta/deprecatedID' ).getVal()[ 0 ] ).toEqual( '7c990ed9-8aab-42ba-84f5-bf23277154ad' ); + } ); + + it( 'empties the instanceID', function() { + expect( model.node( '/thedata/meta/instanceID' ).getVal()[ 0 ] ).toEqual( '' ); + } ); + } ); + + describe( 'when instanceID and deprecatedID nodes are already present in the form format', function() { + var model = new Model( { + modelStr: '', + instanceStr: '7c990ed9-8aab-42ba-84f5-bf23277154ad2012' + } ); + + var loadErrors = model.init(); + + it( 'outputs no load errors', function() { + expect( loadErrors.length ).toEqual( 0 ); + } ); + + it( 'does not NOT add another instanceID node', function() { + expect( model.node( '/thedata/meta/instanceID' ).get().length ).toEqual( 1 ); + } ); + + it( 'does not NOT add another deprecatedID node', function() { + expect( model.node( '/thedata/meta/deprecatedID' ).get().length ).toEqual( 1 ); + } ); + + it( 'gives the deprecatedID node the old value of the instanceID node of the instance-to-edit', function() { + expect( model.node( '/thedata/meta/deprecatedID' ).getVal()[ 0 ] ).toEqual( '7c990ed9-8aab-42ba-84f5-bf23277154ad' ); + } ); + } ); + + + describe( 'when the model contains templates', function() { + [ + // with improper template="" + [ '56', '0', '56' ], + // with proper jr:template="" and namespace definition + [ '56', '0', '56' ], + ].forEach( function( test ) { + var result, expected, + model = new Model( { + modelStr: test[ 1 ], + instanceStr: test[ 0 ] + } ); + + model.init(); + + result = ( new XMLSerializer() ).serializeToString( model.xml, 'text/xml' ); + expected = test[ 2 ]; + + it( 'the initialization will merge the repeat values correctly and remove the templates', function() { + expect( model.xml.querySelectorAll( 'a > r' ).length ).toEqual( 2 ); + expect( result ).toEqual( expected ); + } ); + } ); + } ); + + describe( 'returns load errors upon initialization', function() { + it( 'when the instance-to-edit contains nodes that are not present in the default instance', function() { + var model = new Model( { + modelStr: '', + instanceStr: '7c992012' + } ); + var loadErrors = model.init(); + + expect( loadErrors.length ).toEqual( 1 ); + expect( loadErrors[ 0 ] ).toEqual( 'Error trying to parse XML record. Different root nodes' ); + } ); + + it( 'when an instance-to-edit is provided with double instanceID nodes', function() { + var model = new Model( { + modelStr: '', + instanceStr: '7c99uhoh2012' + } ); + var loadErrors = model.init(); + + expect( loadErrors.length ).toEqual( 1 ); + expect( loadErrors[ 0 ] ).toEqual( 'Error trying to parse XML record. Invalid primary instance. Found 2 instanceID nodes but expected 1.' ); + } ); + } ); +} ); diff --git a/test/spec/formmodel.spec.js b/test/spec/formmodel.spec.js index fa6acc50d..415e80486 100644 --- a/test/spec/formmodel.spec.js +++ b/test/spec/formmodel.spec.js @@ -652,176 +652,3 @@ describe( 'Using XPath with default namespace', function() { } ); } ); - -describe( 'merging an instance into the model', function() { - - describe( '', function() { - [ - // partial record, empty - [ '', '', '' ], - // record value overrides model (default) value - [ 'record', 'model', 'record' ], - // record value overrides model (default) value with an empty value - [ '', 'default', '' ], - // record value overrides model (default) value inside a repeat with an empty value - [ '', 'default1default2', - '' - ], - // preserve non-alphabetic document order of model - [ '', '', '' ], - // repeated nodes in record get added (including repeat childnodes that are missing from record) - [ 'record', 'model', - 'record' - ], - // repeated nodes in record get added in the right order - [ '', '', '' ], - // repeated groups with missing template nodes in record get added - [ '', '', '' ], - // unused model namespaces preserved: - [ 'record', '', 'record' ], - // used model namespaces preserved (though interestingly the result includes a duplicate namespace declaration - probably a minor bug in merge-xml-js) - [ 'record', '', - 'record' - ], - // namespaces used in both record and model (though now with triple equal namespace declarations..: - [ 'recorda', - '', - 'recorda' - ], - // record and model contain same node but in different namespace creates 2nd meta groups and 2 instanceID nodes! - [ 'a', - '', - 'a' - ], - // model has xml declaration and instance has not - [ '', '', - '' - ], - // record and instance have different default namespace - [ 'record', - '', - 'record' - ] - ].forEach( function( test ) { - var result, expected, - model = new Model( { - modelStr: test[ 1 ] - } ); - - model.init(); - model.mergeXml( test[ 0 ] ); - - result = ( new XMLSerializer() ).serializeToString( model.xml, 'text/xml' ).replace( /\n/g, '' ); - expected = test[ 2 ]; - - it( 'produces the expected result for instance: ' + test[ 0 ], function() { - expect( result ).toEqual( expected ); - } ); - } ); - } ); - - describe( 'when a deprecatedID node is not present in the form format', function() { - var model = new Model( { - modelStr: '', - instanceStr: '7c990ed9-8aab-42ba-84f5-bf23277154ad2012' - } ); - - var loadErrors = model.init(); - - it( 'outputs no load errors', function() { - expect( loadErrors.length ).toEqual( 0 ); - } ); - - it( 'adds a deprecatedID node', function() { - expect( model.node( '/thedata/meta/deprecatedID' ).get().length ).toEqual( 1 ); - } ); - - //this is an important test even though it may not seem to be... - it( 'includes the deprecatedID in the string to be submitted', function() { - expect( model.getStr().indexOf( '' ) ).not.toEqual( -1 ); - } ); - - it( 'gives the new deprecatedID node the old value of the instanceID node of the instance-to-edit', function() { - expect( model.node( '/thedata/meta/deprecatedID' ).getVal()[ 0 ] ).toEqual( '7c990ed9-8aab-42ba-84f5-bf23277154ad' ); - } ); - - it( 'empties the instanceID', function() { - expect( model.node( '/thedata/meta/instanceID' ).getVal()[ 0 ] ).toEqual( '' ); - } ); - } ); - - describe( 'when instanceID and deprecatedID nodes are already present in the form format', function() { - var model = new Model( { - modelStr: '', - instanceStr: '7c990ed9-8aab-42ba-84f5-bf23277154ad2012' - } ); - - var loadErrors = model.init(); - - it( 'outputs no load errors', function() { - expect( loadErrors.length ).toEqual( 0 ); - } ); - - it( 'does not NOT add another instanceID node', function() { - expect( model.node( '/thedata/meta/instanceID' ).get().length ).toEqual( 1 ); - } ); - - it( 'does not NOT add another deprecatedID node', function() { - expect( model.node( '/thedata/meta/deprecatedID' ).get().length ).toEqual( 1 ); - } ); - - it( 'gives the deprecatedID node the old value of the instanceID node of the instance-to-edit', function() { - expect( model.node( '/thedata/meta/deprecatedID' ).getVal()[ 0 ] ).toEqual( '7c990ed9-8aab-42ba-84f5-bf23277154ad' ); - } ); - } ); - - - describe( 'when the model contains templates', function() { - [ - // with improper template="" - [ '56', '0', '56' ], - // with proper jr:template="" and namespace definition - [ '56', '0', '56' ], - ].forEach( function( test ) { - var result, expected, - model = new Model( { - modelStr: test[ 1 ], - instanceStr: test[ 0 ] - } ); - - model.init(); - - result = ( new XMLSerializer() ).serializeToString( model.xml, 'text/xml' ); - expected = test[ 2 ]; - - it( 'the initialization will merge the repeat values correctly and remove the templates', function() { - expect( model.xml.querySelectorAll( 'a > r' ).length ).toEqual( 2 ); - expect( result ).toEqual( expected ); - } ); - } ); - } ); - - describe( 'returns load errors upon initialization', function() { - it( 'when the instance-to-edit contains nodes that are not present in the default instance', function() { - var model = new Model( { - modelStr: '', - instanceStr: '7c992012' - } ); - var loadErrors = model.init(); - - expect( loadErrors.length ).toEqual( 1 ); - expect( loadErrors[ 0 ] ).toEqual( 'Error trying to parse XML record. Different root nodes' ); - } ); - - it( 'when an instance-to-edit is provided with double instanceID nodes', function() { - var model = new Model( { - modelStr: '', - instanceStr: '7c99uhoh2012' - } ); - var loadErrors = model.init(); - - expect( loadErrors.length ).toEqual( 1 ); - expect( loadErrors[ 0 ] ).toEqual( 'Error trying to parse XML record. Invalid primary instance. Found 2 instanceID nodes but expected 1.' ); - } ); - } ); -} );