Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial import from 'jquery/qunit.git:addons/composite'.

  • Loading branch information...
commit b3cbf6752a8acb9f836931f51e69ecaf23d1c420 0 parents
@JamesMGreene authored
8 .gitignore
@@ -0,0 +1,8 @@
+.project
+*~
+*.diff
+*.patch
+.DS_Store
+.settings
+node_modules
+dist/
1  .jshintignore
@@ -0,0 +1 @@
+node_modules/
24 .jshintrc
@@ -0,0 +1,24 @@
+{
+ "browser": true,
+ "curly": true,
+ "eqnull": true,
+ "eqeqeq": true,
+ "expr": true,
+ "evil": true,
+ "jquery": true,
+ "latedef": true,
+ "noarg": true,
+ "onevar": true,
+ "smarttabs": true,
+ "trailing": true,
+ "undef": true,
+ "predef": [
+ "module",
+ "test",
+ "asyncTest",
+ "expect",
+ "start",
+ "stop",
+ "QUnit"
+ ]
+}
8 .mailmap
@@ -0,0 +1,8 @@
+Wesley Walser <waw325@gmail.com> <wwalser@atlassian.com>
+Wesley Walser <waw325@gmail.com>
+Jörn Zaefferer <joern.zaefferer@gmail.com>
+Jake Archibald <jaffathecake@gmail.com>
+Jonas Ulrich <jochenulrich@t-online.de>
+Timo Tijhof <krinklemail@gmail.com>
+James M. Greene <james.m.greene@gmail.com>
+Matthew Mirande <itsbusticated@gmail.com>
5 .travis.yml
@@ -0,0 +1,5 @@
+language: node_js
+node_js:
+ - "0.8"
+before_script:
+ - npm install -g grunt-cli
7 AUTHORS.txt
@@ -0,0 +1,7 @@
+Wesley Walser <waw325@gmail.com>
+Jörn Zaefferer <joern.zaefferer@gmail.com>
+Jake Archibald <jaffathecake@gmail.com>
+Jonas Ulrich <jochenulrich@t-online.de>
+Timo Tijhof <krinklemail@gmail.com>
+James M. Greene <james.m.greene@gmail.com>
+Matthew Mirande <itsbusticated@gmail.com>
39 Gruntfile.js
@@ -0,0 +1,39 @@
+/*jshint node:true */
+module.exports = function( grunt ) {
+
+grunt.loadNpmTasks( 'grunt-contrib-jshint' );
+grunt.loadNpmTasks( 'grunt-contrib-connect' );
+grunt.loadNpmTasks( 'grunt-contrib-qunit' );
+grunt.loadNpmTasks( 'grunt-git-authors' );
+
+var localPort = 8000;
+
+grunt.initConfig({
+ jshint: {
+ options: {
+ jshintrc: '.jshintrc'
+ },
+ main: [ '*.js' ],
+ test: [ 'test/**/*.js' ]
+ },
+ connect: {
+ server: {
+ options: {
+ port: localPort
+ }
+ }
+ },
+ qunit: {
+ file: [ 'test/index.html' ],
+ http: {
+ options: {
+ urls: [ 'http://localhost:' + localPort + '/test/index.html' ]
+ }
+ }
+ }
+});
+
+grunt.registerTask('test', ['jshint', 'connect', 'qunit']);
+grunt.registerTask('default', ['test']);
+
+};
44 README.md
@@ -0,0 +1,44 @@
+[![Build Status](https://travis-ci.org/jquery/qunit-composite.png)](https://travis-ci.org/jquery/qunit-composite)
+
+# Composite test suite runner for QUnit
+
+Composite is a QUnit plugin that, when handed an array of files, will
+open each of those files inside of an iframe, run the tests, and
+display the results as a single suite of QUnit tests.
+
+The "Rerun" link next to each suite allows you to quickly rerun that suite,
+outside the composite runner.
+
+If you want to see what assertion failed in a long list of assertions,
+just use the regular "Hide passed tests" checkbox.
+
+## Usage
+
+Load QUnit itself as usual _plus_ `qunit-composite.css` and `qunit-composite.js`,
+then specify the test suites to load using `QUnit.testSuites`:
+
+```js
+QUnit.testSuites([
+ "example-test-1.html",
+ "example-test-2.html",
+ // optionally provide a name and path
+ { name: "Example Test 3", path: "example-test-3.html" }
+]);
+```
+
+Optionally, give the composed module a name (defaults to "Composition #1"):
+
+```
+QUnit.testSuites( "Example tests", [
+ "example-test-1.html",
+ "example-test-2.html"
+]);
+```
+
+## Notes
+ - Although it is possible to do so, we do not recommend mixing QUnit Composite suites (`QUnit.testSuites`) on the same page
+ as regular tests and modules (`QUnit.test`/`test`, `QUnit.module`/`module`).
+ - The QUnit Composite plugin can be used for testing suites on the "file://" protocol **unless** any of the referenced suites
+ are outside of the test page's directory (e.g. `../otherTest.html`) due to web security restrictions. You can work around this
+ restriction by running them in Google Chrome or [PhantomJS](http://phantomjs.org), _with web security disabled_ &mdash; or,
+ of course, by not referencing suites outside of the current test page's directory.
39 package.json
@@ -0,0 +1,39 @@
+{
+ "name": "qunit-composite",
+ "title": "QUnit Composite plugin",
+ "description": "Run multiple QUnit test suite pages.",
+ "version": "1.0.0",
+ "author": {
+ "name": "jQuery Foundation and other contributors",
+ "url": "https://github.com/jquery/qunit/blob/master/AUTHORS.txt"
+ },
+ "homepage": "https://github.com/jquery/qunit-composite",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/jquery/qunit-composite.git"
+ },
+ "bugs": {
+ "url": "https://github.com/jquery/qunit-composite/issues"
+ },
+ "license": {
+ "name": "MIT",
+ "url": "http://www.opensource.org/licenses/mit-license.php"
+ },
+ "keywords": [
+ "testing",
+ "unit",
+ "jquery"
+ ],
+ "main": "qunit-composite.js",
+ "scripts": {
+ "test": "grunt test"
+ },
+ "devDependencies": {
+ "grunt": "~0.4.0",
+ "grunt-contrib-jshint": "~0.2.0",
+ "grunt-contrib-connect": "~0.2.0",
+ "grunt-contrib-qunit": "~0.2.0",
+ "grunt-git-authors": "~1.2.0",
+ "qunitjs": "1.x"
+ }
+}
13 qunit-composite.css
@@ -0,0 +1,13 @@
+.qunit-composite-suite {
+ position: fixed;
+ bottom: 0;
+ left: 0;
+
+ margin: 0;
+ padding: 0;
+ border-width: 1px 0 0;
+ height: 45%;
+ width: 100%;
+
+ background: #fff;
+}
158 qunit-composite.js
@@ -0,0 +1,158 @@
+(function( QUnit ) {
+var iframe, hasBound, addClass,
+ modules = 1,
+ executingComposite = false;
+
+// TODO: Kill this fallback method once QUnit 1.12 is released
+addClass = typeof QUnit.addClass === "function" ?
+ QUnit.addClass :
+ (function() {
+ var hasClass = typeof QUnit.hasClass === "function" ?
+ QUnit.hasClass :
+ function hasClass( elem, name ) {
+ return ( " " + elem.className + " " ).indexOf( " " + name + " " ) > -1;
+ };
+ return function addClass( elem, name ) {
+ if ( !hasClass( elem, name ) ) {
+ elem.className += ( elem.className ? " " : "" ) + name;
+ }
+ };
+ })();
+
+function runSuite( suite ) {
+ var path;
+
+ if ( QUnit.is( "object", suite ) ) {
+ path = suite.path;
+ suite = suite.name;
+ } else {
+ path = suite;
+ }
+
+ QUnit.asyncTest( suite, function() {
+ iframe.setAttribute( "src", path );
+ // QUnit.start is called from the child iframe's QUnit.done hook.
+ });
+}
+
+function initIframe() {
+ var iframeWin,
+ body = document.body;
+
+ function onIframeLoad() {
+ var moduleName, testName,
+ count = 0;
+
+ if ( !iframe.src ) {
+ return;
+ }
+
+ iframeWin.QUnit.moduleStart(function( data ) {
+ // Capture module name for messages
+ moduleName = data.name;
+ });
+
+ iframeWin.QUnit.testStart(function( data ) {
+ // Capture test name for messages
+ testName = data.name;
+ });
+ iframeWin.QUnit.testDone(function() {
+ testName = undefined;
+ });
+
+ iframeWin.QUnit.log(function( data ) {
+ if (testName === undefined) {
+ return;
+ }
+ // Pass all test details through to the main page
+ var message = ( moduleName ? moduleName + ": " : "" ) + testName + ": " + ( data.message || ( data.result ? "okay" : "failed" ) );
+ expect( ++count );
+ QUnit.push( data.result, data.actual, data.expected, message );
+ });
+
+ // Continue the outer test when the iframe's test is done
+ iframeWin.QUnit.done( QUnit.start );
+ }
+
+ iframe = document.createElement( "iframe" );
+ iframe.className = "qunit-composite-suite";
+ body.appendChild( iframe );
+
+ QUnit.addEvent( iframe, "load", onIframeLoad );
+
+ iframeWin = iframe.contentWindow;
+}
+
+/**
+ * @param {string} [name] Module name to group these test suites.
+ * @param {Array} suites List of suites where each suite
+ * may either be a string (path to the html test page),
+ * or an object with a path and name property.
+ */
+QUnit.testSuites = function( name, suites ) {
+ var i, suitesLen;
+
+ if ( arguments.length === 1 ) {
+ suites = name;
+ name = "Composition #" + modules++;
+ }
+ suitesLen = suites.length;
+
+ if ( !hasBound ) {
+ hasBound = true;
+ QUnit.begin( initIframe );
+
+ // TODO: Would be better to use something like QUnit.once( 'moduleDone' )
+ // after the last test suite.
+ QUnit.moduleDone( function () {
+ executingComposite = false;
+ } );
+
+ QUnit.done(function() {
+ iframe.style.display = "none";
+ });
+ }
+
+ QUnit.module( name, {
+ setup: function () {
+ executingComposite = true;
+ }
+ });
+
+ for ( i = 0; i < suitesLen; i++ ) {
+ runSuite( suites[ i ] );
+ }
+};
+
+QUnit.testDone(function() {
+ if ( !executingComposite ) {
+ return;
+ }
+
+ var i, len,
+ current = QUnit.id( this.config.current.id ),
+ children = current.children,
+ src = iframe.src;
+
+ QUnit.addEvent( current, "dblclick", function( e ) {
+ var target = e && e.target ? e.target : window.event.srcElement;
+ if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) {
+ target = target.parentNode;
+ }
+ if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
+ window.location = src;
+ }
+ });
+
+ // Undo QUnit's auto-expansion for bad tests
+ for ( i = 0, len = children.length; i < len; i++ ) {
+ if ( children[ i ].nodeName.toLowerCase() === "ol" ) {
+ addClass( children[ i ], "qunit-collapsed" );
+ }
+ }
+
+ // Update Rerun link to point to the standalone test suite page
+ current.getElementsByTagName( "a" )[ 0 ].href = src;
+});
+
+})( QUnit );
24 test/index.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>QUnit Composite Test Suite</title>
+ <link rel="stylesheet" href="../node_modules/qunitjs/qunit/qunit.css">
+ <link rel="stylesheet" href="../qunit-composite.css">
+ <script src="../node_modules/qunitjs/qunit/qunit.js"></script>
+ <script src="../qunit-composite.js"></script>
+ <script>
+ QUnit.testSuites([
+ "../node_modules/qunitjs/test/index.html",
+ "../node_modules/qunitjs/addons/canvas/canvas.html",
+ "../node_modules/qunitjs/addons/close-enough/close-enough.html",
+ { name: "step tests", path: "../node_modules/qunitjs/addons/step/step.html" }
+ ]);
+ </script>
+</head>
+<body>
+ <div id="qunit"></div>
+ <div id="qunit-fixture">
+</div>
+</body>
+</html>
Please sign in to comment.
Something went wrong with that request. Please try again.