diff --git a/core/modules/views/tests/js/test/base.js b/core/modules/views/tests/js/test/base.js new file mode 100644 index 0000000..33f6ec9 --- /dev/null +++ b/core/modules/views/tests/js/test/base.js @@ -0,0 +1,27 @@ +var chai = require('chai'); +var assert = chai.assert; +var sinon = require('sinon'); + +$ = sinon.stub(); +$.withArgs(sinon.match.any).returns(sinon.stub({on: function() {} })); + +var Drupal = {}; +Drupal.behaviors = {}; +document = null; +drupalSettings = {}; + +var execfile = require("execfile.js"); +var context = execfile("../../js/base.js", { jQuery: $, Drupal: Drupal, document: document, drupalSettings: drupalSettings}); + +describe('base', function() { + describe('parseQueryString', function() { + it('parse empty string', function() { + var result = context.Drupal.Views.parseQueryString(''); + assert.deepEqual({}, result); + }); + it('parse simple query string', function() { + var result = context.Drupal.Views.parseQueryString('foo=bar'); + assert.deepEqual({foo: 'bar'}, result); + }); + }); +}); diff --git a/core/scripts/run-js-tests.sh b/core/scripts/run-js-tests.sh new file mode 100755 index 0000000..916bffc --- /dev/null +++ b/core/scripts/run-js-tests.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +function HELP { + echo -e "Help for run-js-tests.sh"\\n + echo -e "Run core tests: core/scripts/run-js-tests.sh core/tests/js/test" + echo -e "Run specific modules: core/scripts/run-js-tests.sh core/modules/views/tests/js/test" + exit 1 +} + +NUMARGS=$# +if [ $NUMARGS -eq 0 ]; then + HELP +fi + +DRUPAL_ROOT=$(pwd) +export NODE_PATH=${NODE_PATH}:${DRUPAL_ROOT}/core/tests/js/node_modules:${DRUPAL_ROOT}/core/tests/js + +PARAMS=("$@") +PARAMS[0]=${DRUPAL_ROOT}/${PARAMS[0]} +cd ${PARAMS[0]}/../ + +if [ "$1" == "--help" ]; then + PARAMS=(--help) +fi + +# devtool --break ${DRUPAL_ROOT}/core/tests/js/node_modules/mocha/bin/mocha -qc -- ${PARAMS[@]} +${DRUPAL_ROOT}/core/tests/js/node_modules/mocha/bin/mocha ${PARAMS[@]} diff --git a/core/tests/Drupal/Tests/MochaJsTestDiscovery.php b/core/tests/Drupal/Tests/MochaJsTestDiscovery.php new file mode 100644 index 0000000..4d6cac1 --- /dev/null +++ b/core/tests/Drupal/Tests/MochaJsTestDiscovery.php @@ -0,0 +1,36 @@ +root = $root; + $this->sitePath = $site_path; + } + + public function getTestClasses() { + $extension_discovery = new ExtensionDiscovery($this->root, TRUE, [], $this->sitePath); + + $extensions = ['core' => new Extension($this->root, 'core', 'core/core.info.yml')]; + $extensions += $extension_discovery->scan('module', TRUE); + $extensions += $extension_discovery->scan('theme', TRUE); + $extensions += $extension_discovery->scan('profile', TRUE); + + $js_tests = []; + foreach ($extensions as $extension) { + if (file_exists($this->root . '/' . $extension->getPath() . '/tests/js')) { + $js_tests['js--mocha-' . $extension->getName()] = TRUE; + }; + } + return $js_tests; + } + +} diff --git a/core/tests/Drupal/Tests/MochaJsTestDiscoveryTest.php b/core/tests/Drupal/Tests/MochaJsTestDiscoveryTest.php new file mode 100644 index 0000000..7c72cb5 --- /dev/null +++ b/core/tests/Drupal/Tests/MochaJsTestDiscoveryTest.php @@ -0,0 +1,69 @@ + [ + 'test.js' => '', + ], + 'modules' => [ + 'module_a' => [ + 'module_a.info.yml' => $module_a, + 'tests' => [ + 'js' => [ + 'test.js' => '', + ], + ], + ], + 'module_b' => [ + 'module_b.info.yml' => $module_b, + ], + ], + 'themes' => [ + 'theme_a' => [ + 'theme_a.info.yml' => $theme_a, + 'tests' => [ + 'js' => [ + 'test.js' => '', + ], + ], + ], + ], + ]); + + $js_test_discovery = new MochaJsTestDiscovery('vfs://drupal', 'sites/default'); + $result = $js_test_discovery->getTestClasses(); + $expected = [ + 'js--mocha-core' => TRUE, + 'js--mocha-module_a' => TRUE, + 'js--mocha-theme_a' => TRUE, + ]; + $this->assertEquals($expected, $result); + } + +} diff --git a/core/tests/README.md b/core/tests/README.md index dfd1154..8da9bd2 100644 --- a/core/tests/README.md +++ b/core/tests/README.md @@ -2,6 +2,8 @@ ## Functional tests +First you need to install phantomjs on your system, see http://phantomjs.org/download.html. + * Start PhantomJS: ``` phantomjs --ssl-protocol=any --ignore-ssl-errors=true ./vendor/jcalderonzumba/gastonjs/src/Client/main.js 8510 1024 768 2>&1 >> /dev/null & @@ -13,3 +15,24 @@ ./vendor/bin/phpunit -c core --testsuite functional ./vendor/bin/phpunit -c core --testsuite functional-javascript ``` + +## Unit testing + +### PHP + +./vendor/bin/phpunit -c core --testsuite unit + +### Javascript + +First you need to install the dependencies using npm, see (Installing NPM)$https://docs.npmjs.com/getting-started/installing-node]. + +``` +cd core/tests/js +npm install +``` + +Once you have installed it, you can run the tests using + +``` +node_modules/mocha/bin/mocha +``` diff --git a/core/tests/js/execfile.js b/core/tests/js/execfile.js new file mode 100644 index 0000000..7af1b8b --- /dev/null +++ b/core/tests/js/execfile.js @@ -0,0 +1,8 @@ +var vm = require("vm"); +var fs = require("fs"); +module.exports = function(path, context) { + context = context || {}; + var data = fs.readFileSync(path); + vm.runInNewContext(data, context, path); + return context; +} diff --git a/core/tests/js/npm-shrinkwrap.json b/core/tests/js/npm-shrinkwrap.json new file mode 100644 index 0000000..e611279 --- /dev/null +++ b/core/tests/js/npm-shrinkwrap.json @@ -0,0 +1,185 @@ +{ + "name": "js", + "version": "1.0.0", + "dependencies": { + "assertion-error": { + "version": "1.0.1", + "from": "assertion-error@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.1.tgz" + }, + "chai": { + "version": "3.5.0", + "from": "chai@>=3.5.0 <4.0.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz" + }, + "charenc": { + "version": "0.0.1", + "from": "charenc@>=0.0.1 <0.1.0", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.1.tgz" + }, + "commander": { + "version": "2.3.0", + "from": "commander@2.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz" + }, + "crypt": { + "version": "0.0.1", + "from": "crypt@>=0.0.1 <0.1.0", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.1.tgz" + }, + "debug": { + "version": "2.2.0", + "from": "debug@2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz" + }, + "deep-eql": { + "version": "0.1.3", + "from": "deep-eql@>=0.1.3 <0.2.0", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "dependencies": { + "type-detect": { + "version": "0.1.1", + "from": "type-detect@0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz" + } + } + }, + "diff": { + "version": "1.4.0", + "from": "diff@1.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz" + }, + "escape-string-regexp": { + "version": "1.0.2", + "from": "escape-string-regexp@1.0.2", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz" + }, + "formatio": { + "version": "1.1.1", + "from": "formatio@1.1.1", + "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.1.1.tgz" + }, + "glob": { + "version": "3.2.3", + "from": "glob@3.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.3.tgz" + }, + "graceful-fs": { + "version": "2.0.3", + "from": "graceful-fs@>=2.0.0 <2.1.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz" + }, + "growl": { + "version": "1.8.1", + "from": "growl@1.8.1", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.8.1.tgz" + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "is-buffer": { + "version": "1.1.3", + "from": "is-buffer@>=1.1.1 <1.2.0", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.3.tgz" + }, + "jade": { + "version": "0.26.3", + "from": "jade@0.26.3", + "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", + "dependencies": { + "commander": { + "version": "0.6.1", + "from": "commander@0.6.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz" + }, + "mkdirp": { + "version": "0.3.0", + "from": "mkdirp@0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz" + } + } + }, + "lolex": { + "version": "1.3.2", + "from": "lolex@1.3.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.3.2.tgz" + }, + "lru-cache": { + "version": "2.7.3", + "from": "lru-cache@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz" + }, + "md5": { + "version": "2.1.0", + "from": "md5@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.1.0.tgz" + }, + "minimatch": { + "version": "0.2.14", + "from": "minimatch@>=0.2.11 <0.3.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz" + }, + "minimist": { + "version": "0.0.8", + "from": "minimist@0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" + }, + "mkdirp": { + "version": "0.5.1", + "from": "mkdirp@0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz" + }, + "mocha": { + "version": "2.4.5", + "from": "mocha@>=2.4.5 <3.0.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.4.5.tgz" + }, + "mocha-junit-reporter": { + "version": "1.11.1", + "from": "mocha-junit-reporter@latest", + "resolved": "https://registry.npmjs.org/mocha-junit-reporter/-/mocha-junit-reporter-1.11.1.tgz" + }, + "ms": { + "version": "0.7.1", + "from": "ms@0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz" + }, + "samsam": { + "version": "1.1.2", + "from": "samsam@1.1.2", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.1.2.tgz" + }, + "sigmund": { + "version": "1.0.1", + "from": "sigmund@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz" + }, + "sinon": { + "version": "1.17.3", + "from": "sinon@>=1.17.3 <2.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-1.17.3.tgz" + }, + "supports-color": { + "version": "1.2.0", + "from": "supports-color@1.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz" + }, + "type-detect": { + "version": "1.0.0", + "from": "type-detect@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz" + }, + "util": { + "version": "0.10.3", + "from": "util@>=0.10.3 <1.0.0", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz" + }, + "xml": { + "version": "1.0.1", + "from": "xml@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz" + } + } +} diff --git a/core/tests/js/package.json b/core/tests/js/package.json new file mode 100644 index 0000000..26e6fa3 --- /dev/null +++ b/core/tests/js/package.json @@ -0,0 +1,17 @@ +{ + "name": "js", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "chai": "^3.5.0", + "mocha": "^2.4.5", + "mocha-junit-reporter": "^1.11.1", + "sinon": "^1.17.3" + } +} diff --git a/core/tests/js/test/states.js b/core/tests/js/test/states.js new file mode 100644 index 0000000..0a6618d --- /dev/null +++ b/core/tests/js/test/states.js @@ -0,0 +1,25 @@ +var execfile = require("execfile"); +var sinon = require('sinon'); +var chai = require('chai'); +var assert = chai.assert; + +var Drupal = {}; +Drupal.behaviors = {}; +document = null; + +$ = sinon.stub(); +$.withArgs(sinon.match.any).returns(sinon.stub({on: function() {} })); + +var context = execfile("../../misc/states.js", { jQuery: $, Drupal: Drupal, document: document}); + +describe('states', function() { + describe('states.Dependent.comparisons.Function', function () { + it('it compares', function() { + var states = context.Drupal.states; + assert.isOk(states.Dependent.comparisons.Function(function(a) { + return a == 'hello'; + }, 'hello')); + }); + }); +}); + diff --git a/example.gitignore b/example.gitignore index d1e35ac..00683c7 100644 --- a/example.gitignore +++ b/example.gitignore @@ -14,6 +14,9 @@ # Core's dependencies are managed with Composer. vendor +# Ignore javascript test dependencies. +node_modules + # Ignore configuration files that may contain sensitive information. sites/*/settings*.php sites/*/services*.yml