├── .gitignore ├── .npmignore ├── .travis.yml ├── CNAME ├── CONTRIBUTING.md ├── Gruntfile.js ├── HISTORY.md ├── LICENSE ├── README.md ├── bower.json ├── dist ├── .gitattributes ├── jasmine │ ├── blanket_jasmine.js │ └── blanket_jasmine.min.js ├── mocha │ ├── blanket_mocha.js │ └── blanket_mocha.min.js └── qunit │ ├── .gitattributes │ ├── blanket.js │ └── blanket.min.js ├── docs ├── advanced_browser.md ├── compatibility_and_features.md ├── getting_started_browser.md ├── getting_started_node.md ├── intermediate_browser.md ├── intermediate_node.md ├── intermediate_node_2.md ├── options.md └── special_features.md ├── package.json ├── src ├── adapters │ ├── jasmine-2.x-blanket.js │ ├── jasmine-blanket.js │ ├── mocha-blanket.js │ ├── usage-blanket.js │ └── yui-blanket.js ├── blanket.js ├── blanketRequire.js ├── blanket_browser.js ├── config.js ├── index.js ├── loaders │ └── blanket_cs.js ├── node-loaders │ ├── cjsx.js │ ├── coffee-script.js │ ├── dynamic-loader.js │ ├── iced-coffee-script.js │ └── simple-node-loader.js ├── qunit │ ├── noautorun.js │ ├── qunit.js │ └── reporter.js └── reporters │ ├── lcov_reporter.js │ └── simple_json_reporter.js ├── tasks └── blanketTests.js ├── test ├── backbone-koans │ ├── css │ │ └── todos.css │ ├── es5-sham.js │ ├── es5-shim.js │ ├── filter_function.html │ ├── images │ │ └── destroy.png │ ├── index.html │ ├── js │ │ ├── ext │ │ │ ├── backbone.js │ │ │ ├── backbone.localStorage.js │ │ │ ├── jquery.js │ │ │ ├── sinon-1.3.1.js │ │ │ ├── sinon-qunit-1.0.0.js │ │ │ ├── template.js │ │ │ └── underscore.js │ │ ├── koans │ │ │ ├── aboutApps.js │ │ │ ├── aboutCollections.js │ │ │ ├── aboutEvents.js │ │ │ ├── aboutModels.js │ │ │ └── aboutViews.js │ │ └── todos.js │ └── templates │ │ ├── app.html │ │ ├── item.html │ │ └── stats.html ├── bootstrap │ ├── .jshintrc │ ├── bootstrap-affix.js │ ├── bootstrap-alert.js │ ├── bootstrap-button.js │ ├── bootstrap-carousel.js │ ├── bootstrap-collapse.js │ ├── bootstrap-dropdown.js │ ├── bootstrap-modal.js │ ├── bootstrap-popover.js │ ├── bootstrap-scrollspy.js │ ├── bootstrap-tab.js │ ├── bootstrap-tooltip.js │ ├── bootstrap-transition.js │ ├── bootstrap-typeahead.js │ └── tests │ │ ├── index.html │ │ ├── index_with_worker.html │ │ ├── phantom.js │ │ ├── server.js │ │ ├── unit │ │ ├── bootstrap-affix.js │ │ ├── bootstrap-alert.js │ │ ├── bootstrap-button.js │ │ ├── bootstrap-carousel.js │ │ ├── bootstrap-collapse.js │ │ ├── bootstrap-dropdown.js │ │ ├── bootstrap-modal.js │ │ ├── bootstrap-phantom.js │ │ ├── bootstrap-popover.js │ │ ├── bootstrap-scrollspy.js │ │ ├── bootstrap-tab.js │ │ ├── bootstrap-tooltip.js │ │ ├── bootstrap-transition.js │ │ └── bootstrap-typeahead.js │ │ └── vendor │ │ ├── jquery.js │ │ ├── qunit.css │ │ └── qunit.js ├── branchTracking │ ├── branch_runner.html │ ├── branch_sample.js │ └── branch_test.js ├── coffee_script │ ├── index.html │ ├── sample.coffee │ └── test.js ├── commonjs │ ├── commonjs_bundle.js │ ├── runner.html │ ├── source_testing_url_module.js │ ├── source_to_cover.js │ ├── testlib.js │ └── testlib_test.js ├── custom-reporter │ ├── index.html │ ├── lcov.html │ ├── lcov_test.js │ ├── sample.js │ └── test.js ├── helpers │ ├── console_runner.js │ ├── phantom_jasmine_runner.js │ ├── phantom_mocha_runner.js │ ├── phantom_qunit_old_runner.js │ └── phantom_qunit_runner.js ├── ignore_script_error │ ├── runner.html │ ├── script_error.js │ └── script_error_test.js ├── jasmine-custom-build │ ├── SpecRunner.html │ ├── SpecRunner_data_adapter.html │ ├── require.html │ ├── source │ │ ├── Player.js │ │ └── Song.js │ └── spec │ │ ├── PlayerSpec.js │ │ ├── SongSpec.js │ │ ├── SpecHelper.js │ │ ├── require_PlayerSpec.js │ │ └── require_SongSpec.js ├── jasmine-requirejs │ ├── code │ │ ├── all.tests.jasmine.js │ │ ├── base │ │ │ └── core.js │ │ ├── tests │ │ │ ├── base │ │ │ │ └── base.jasmine.test.js │ │ │ └── ui │ │ │ │ └── ui.jasmine.test.js │ │ └── ui │ │ │ └── screen.js │ └── runner.html ├── jasmine │ ├── SpecRunner.html │ ├── SpecRunner_data_adapter.html │ ├── SpecRunner_data_adapter_array.html │ ├── SpecRunner_data_adapter_regex.html │ ├── source │ │ ├── Player.js │ │ └── Song.js │ └── spec │ │ ├── PlayerSpec.js │ │ ├── SongSpec.js │ │ └── SpecHelper.js ├── jquery-usage │ ├── css │ │ └── todos.css │ ├── images │ │ └── destroy.png │ ├── index.html │ ├── js │ │ ├── ext │ │ │ ├── backbone.js │ │ │ ├── backbone.localStorage.js │ │ │ ├── jquery.js │ │ │ ├── sinon-1.3.1.js │ │ │ ├── sinon-qunit-1.0.0.js │ │ │ ├── template.js │ │ │ └── underscore.js │ │ ├── koans │ │ │ ├── aboutApps.js │ │ │ ├── aboutCollections.js │ │ │ ├── aboutEvents.js │ │ │ ├── aboutModels.js │ │ │ └── aboutViews.js │ │ └── todos.js │ └── templates │ │ ├── app.html │ │ ├── item.html │ │ └── stats.html ├── lib-tests │ ├── blanket_test.js │ └── runner.html ├── mocha-browser │ ├── adapter.html │ ├── adapter.js │ ├── array.js │ ├── duration.js │ ├── globals.js │ ├── index.html │ ├── large.html │ ├── large.js │ ├── opts.html │ ├── opts.js │ ├── src │ │ └── aSource.js │ └── timeout.js ├── performance │ ├── blanket_performance_test.js │ └── performance_runner.html ├── qunit-start-stop │ ├── runner.html │ ├── stop_start_test.js │ └── test_script.js ├── requirejs │ ├── chutzpah.html │ ├── code │ │ ├── all.tests.qunit.js │ │ ├── base │ │ │ └── core.js │ │ ├── tests │ │ │ ├── base │ │ │ │ └── base.qunit.test.js │ │ │ └── ui │ │ │ │ └── ui.qunit.test.js │ │ └── ui │ │ │ └── screen.js │ ├── require_runner.html │ ├── require_sample.js │ └── require_test.js ├── test-node │ ├── fixture │ │ ├── blockinjection_test_file.js │ │ ├── blockinjection_test_file_instrumented.js │ │ ├── branch_complex_test_file.js │ │ ├── branch_complex_test_file_instrumented.js │ │ ├── branch_test_file.js │ │ ├── branch_test_file_instrumented.js │ │ ├── comment_test_file.js │ │ ├── comment_test_file_instrumented.js │ │ ├── core_fixtures.js │ │ ├── multi_line_branch_test_file.js │ │ ├── multi_line_branch_test_file_instrumented.js │ │ ├── shebang_test_file.js │ │ ├── shebang_test_file_instrumented.js │ │ ├── simple_test_file.js.js │ │ ├── simple_test_file_instrumented.js.js │ │ ├── simple_test_file_instrumented_full.js.js │ │ ├── src │ │ │ ├── sample.coffee │ │ │ ├── sampleCjsx.cjsx │ │ │ ├── sourceA.js │ │ │ ├── sourceB.js │ │ │ └── sourceC.js │ │ └── test │ │ │ └── testA.js │ ├── testrunner.js │ ├── testrunner_cjsx.js │ ├── testrunner_cs.js │ └── tests │ │ ├── blanket_core.js │ │ ├── cjsx │ │ └── test.coffee │ │ ├── coffee-script │ │ └── test.coffee │ │ ├── instrumentation_test.js │ │ └── nested_test.js ├── testconfigs.json ├── usage │ ├── backbone.js │ ├── backbone.localStorage.js │ ├── index.html │ ├── test_fcn.js │ ├── testpage.html │ ├── todos.css │ ├── todos.js │ └── underscore.js ├── vendor │ ├── coffee-script.js │ ├── cs.js │ ├── jasmine-html.js │ ├── jasmine.css │ ├── jasmine.js │ ├── jquery.js │ ├── mocha.css │ ├── mocha.js │ ├── qunit.css │ ├── qunit.js │ ├── qunit_old.css │ └── qunit_old.js └── yui │ ├── runner.html │ ├── test_module_yui.js │ └── test_module_yui_test.js └── testserver.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .tmp/ 3 | coverage.html 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .tmp/ 2 | docs 3 | .travis.yml 4 | coverage.html 5 | CONTRIBUTING.md 6 | HISTORY.md 7 | component.json 8 | tasks 9 | test 10 | testserver.js 11 | Gruntfile.js -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | - "0.12" 5 | - "iojs" 6 | before_install: 7 | - npm update -g npm 8 | before_script: 9 | - npm install -g grunt-cli 10 | 11 | branches: 12 | only: 13 | - master 14 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | blanketjs.org 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Development takes place on the `master` branch. Please run `grunt` to rebuild the dist and run tests. 2 | 3 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | May 1-13 - 1.1.4 2 | Loaded reverting for grunt-blanket, branch tracking reporter fixed, coverage on-the-go (displaying coverage results while a single page is being used). 3 | 4 | Apr 28-13 - 1.1.3 5 | YUI support added with custom adapter (and some wrapping code). CompoundJS support appears to be outside the scope of project. 6 | 7 | Apr 15-13 - 1.1.2 8 | Instrumentation cacheing, and LCOV reporter, and passing options to custom reporters. 9 | 10 | Apr 2-13 - 1.1.1 11 | CommonJS support, based on Browserify. Disable require loader when coverage is disabled (in QUnit). 12 | 13 | Mar 22-13 - 1.1.0 14 | Custom variable data attribute to use whatever variable you want for coverage tracking. 15 | 16 | Mar 22-13 - 1.0.9 17 | Blanket is not run on require in node now. Update to component version for bower. Branch tracking reporting fix. Preserve filenames in Node. 18 | 19 | Mar 14-13 - 1.0.8 20 | Improvement to branch tracking 21 | 22 | Mar 11-13 - 1.0.7 23 | Moving repo to alex-seville/blanket. 24 | 25 | Feb 12-13 - 1.0.6 26 | Added debug setting to track program flow. Minor fixes on both browser and node side. 27 | 28 | Feb 8-13 - 1.0.5 29 | Node version will avoid instrumenting anything not in the current directory using `onlyCwd: true` in the package.json file. 30 | 31 | Feb 7-13 - 1.0.4 32 | Node version can use the same input attributes as client side version, branchTracking reporting for client, use string, regex or array as filter for node, loading issue fixes for requirejs+blanket. 33 | 34 | Jan 23-13 - 1.0.3 35 | Dependencies fixed for node. Various other fixes. 36 | 37 | Jan 13-13 - 1.0.2 38 | Branch tracking, Jasmine/RequireJS compatibility fixes, data-cover-never, data-cover-timeout attributes added, fixed bug in mocha adapter, fixed instrumentation of labelled statements, local uploader to deal with CORS issues. 39 | 40 | Dec 31-12 - 1.0.1 41 | User guides, minification fixes, coffeescript/custom loader support for browser & node, replaced getters/setters with blanket.options. 42 | 43 | Dec 14-12 - 1.0.0 44 | Added to Bower, fixed relative paths issues, added noConflict, refactored core code, added Twitter Bootstrap example. 45 | 46 | Dec-8-12 - 0.9.9 47 | Moved Makefile into grunt and reorganized files. Fixed instrumenting of comments in node. 48 | 49 | Dec-3-12 - 0.9.8 50 | Fixes to instrumentation, fix for escaped characters in node. Added adapters and Jasmine example. 51 | 52 | Nov-26-12 - 0.9.7 53 | Custom reporters. Better organization of tests. 54 | 55 | Nov-24-12 - 0.9.6 56 | Better line counts, more tests, normalizing slashes for windows, require loader uses module._compile to properly pass the exports, added Makefile for CI, various other fixes. 57 | 58 | Nov-19-12 - 0.9.4 59 | Major refactoring, QUnit tests run with phantomjs, both node and browser tests are covered by blanket on travis-ci. Compatibility with existing requirejs instance. 60 | 61 | Nov-8-12 - 0.9.2 62 | Bug fixes to instrumentation and node require loader. 63 | 64 | Nov-4-12 - 0.9.1 65 | Works seamlessly with mocha (in node) and uses built in mocha reporters for coverage. 66 | 67 | Oct-29-12 - 0.9.0 68 | Initial release of blanket.js. Works with qunit, but coverage output is not complete. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | Copyright (c) 2013 Alex Seville 3 | 4 | Permission is hereby granted, free of charge, to any person 5 | obtaining a copy of this software and associated documentation 6 | files (the "Software"), to deal in the Software without 7 | restriction, including without limitation the rights to use, 8 | copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the 10 | Software is furnished to do so, subject to the following 11 | conditions: 12 | 13 | * The software may not be used by individuals, corporations, governments, or other groups for systems or activities that actively and knowingly endanger, harm, or otherwise threaten the physical, mental, economic, or general well-being of other individuals or groups in violation of the [United Nations Universal Declaration of Human Rights](https://www.un.org/en/universal-declaration-human-rights/). 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | OTHER DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blanket", 3 | "version": "1.1.7", 4 | "main": [ 5 | "./dist/qunit/blanket.js" 6 | ], 7 | "homepage": "https://github.com/alex-seville/blanket", 8 | "authors": [ 9 | "Alex-Seville " 10 | ], 11 | "description": "blanket.js is a simple code coverage library for javascript", 12 | "moduleType": [ 13 | "amd", 14 | "globals", 15 | "node" 16 | ], 17 | "keywords": [ 18 | "code-coverage", 19 | "coverage", 20 | "unit", 21 | "test" 22 | ], 23 | "license": "MIT", 24 | "ignore": [ 25 | "**/.*", 26 | "node_modules", 27 | "bower_components", 28 | "test", 29 | "tests" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /dist/.gitattributes: -------------------------------------------------------------------------------- 1 | *.js merge=union 2 | -------------------------------------------------------------------------------- /dist/qunit/.gitattributes: -------------------------------------------------------------------------------- 1 | *.js merge=union 2 | -------------------------------------------------------------------------------- /docs/getting_started_browser.md: -------------------------------------------------------------------------------- 1 | # Getting Started Guide (browser version) 2 | 3 | This guide details using Blanket.js with a simple QUnit test runner in the browser. 4 | 5 | To begin you will need: 6 | * an existing QUnit test runner (including the QUnit script) 7 | * source files 8 | * QUnit tests for those source files 9 | 10 | 11 | 1. Download [Blanket.js](https://raw.github.com/alex-seville/blanket/master/dist/qunit/blanket.min.js) or `bower install blanket` 12 | 13 | 2. Reference the script in the testrunner HTML file (after, not before, `qunit.js`) as follows: 14 | ``` 15 | 16 | ``` 17 | 18 | 3. Add a `data-cover` attribute to any source script tags you want covered: 19 | ``` 20 | 21 | ``` 22 | 23 | 4. Open the test runner in the browser. The coverage details will be appended below the test results. 24 | 25 | 26 | 27 | **What if I encounter difficulties?** 28 | Add the `data-cover-flags` attribute to your Blanket script tag with the value "debug" to enable debugging mode. 29 | 30 | ``` 31 | 32 | ``` 33 | 34 | This will provide logging for everything that Blanket is doing and should help identify any misconfigurations or incompatibilities. 35 | -------------------------------------------------------------------------------- /docs/getting_started_node.md: -------------------------------------------------------------------------------- 1 | # Getting Started Guide (nodejs version) 2 | 3 | This guide details using Blanket.js with a simple mocha test setup in NodeJS. 4 | 5 | To begin you will need: 6 | * an existing mocha tests (including the mocha module, `npm install mocha -g`) 7 | * source files 8 | 9 | 1. Install Blanket: `npm install blanket` 10 | 11 | 2. Add the following to your package.json file: 12 | 13 | ```json 14 | { 15 | "config": { 16 | "blanket": { 17 | "pattern": 18 | } 19 | } 20 | } 21 | ``` 22 | 23 | If you omit this from your package.json, Blanket will default to "src". 24 | 25 | Alternatively, you may use `data-cover-never` to specify paths that should **not* be included, like so: 26 | 27 | ```json 28 | { 29 | "config": { 30 | "blanket": { 31 | "pattern": [ "" ], 32 | "data-cover-never": [ "node_modules", "tests" ] 33 | } 34 | } 35 | } 36 | ``` 37 | 38 | You may use an array of strings/ regexes instead of a single string/ regex. 39 | 40 | 3. Add Blanket as a require to your mocha command: 41 | 42 | ```mocha --require blanket``` 43 | 44 | 4. Use the built-in html-cov reporter in mocha to display coverage results: 45 | 46 | ```mocha --require blanket -R html-cov > coverage.html``` 47 | 48 | -------------------------------------------------------------------------------- /docs/intermediate_browser.md: -------------------------------------------------------------------------------- 1 | # Intermediate Guide (browser version) 2 | 3 | This guide details using Blanket.js with a custom adapter to run Blanket with a test runner other than QUnit (ex. Jasmine), and covers some of the configuration options available. 4 | 5 | It is assumed that you have already read the Getting Started guide. 6 | 7 | To begin you will need: 8 | * an existing test runner (including the test library script) 9 | * source files 10 | * tests for those source files 11 | 12 | NOTE: PhantomJS and other third-party JS runtimes may not support synchronous XHR requests. If this is the case you cannot use the `data-cover-adapter` or `data-cover-reporter` attribute. You will need to include a separate script tag for the reporter/adapter directly below the Blanket script tag. 13 | 14 | 15 | 1. Download [Blanket.js](https://raw.github.com/alex-seville/blanket/master/dist/qunit/blanket.min.js) or `bower install blanket` 16 | 17 | 2. Download a Blanket adapter for your test runner. Currently there are adapters for [Jasmine](https://raw.github.com/alex-seville/blanket/master/src/adapters/jasmine-blanket.js) and (browser based) [Mocha](https://raw.github.com/alex-seville/blanket/master/src/adapters/mocha-blanket.js). 18 | 19 | 3. Reference the script and adapter in the testrunner HTML file as follows: 20 | `````` 21 | 22 | 4. Add a `data-cover-only` attribute to avoid having to add `data-cover` to each script you want covered. You can pass the filter value as a string to match, an array of filename, or a regular expression (add a double slash to the start, i.e. `data-cover-only="//.*/"`): 23 | `````` 25 | 26 | 5. Add a `data-cover-modulepattern` attribute to have the reporter generate total coverage statistics for each module in your application. (*Currently only supported using QUnit reporter.*) This is useful for tracking code coverage across multiple teams that work on different modules. Modules are determined by the regular expression pattern you pass via this attribute. The regular expression is expected to have one pattern matching section in parenthesis, which will be captured as the module name. For example, let's say that the files in your blanket report look like this: 27 | 28 | ``` 29 | ./core/src/js/MainView.js 30 | ./core/src/js/NavBar.js 31 | ./gallery/src/js/GalleryView.js 32 | ./cart/src/js/Cart.js 33 | ``` 34 | 35 | In this case, we want the module to be recognized as the characters in between the first two slashes, such that we end up with modules `core`, `gallery`, and `cart`. To achieve this, specify an attribute like so: `data-cover-modulepattern="\.\/(.*?)\/"` 36 | 37 | This regular expression says, look for a period, followed by a slash, followed by any number of characters up until the next slash (which we store as a matched pattern). For more info on regular expressions, see the [MDN RegEx guide](https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Regular_Expressions). 38 | 39 | 6. Open the test runner in the browser. The coverage details will be appended below the test results. 40 | 41 | 7. If you will always be using the adapter, consider making a [custom build](https://github.com/alex-seville/blanket/blob/master/README.md#roll-your-own) of blanket (i.e. `dist/jasmine/blanket_jasmine.js`). 42 | -------------------------------------------------------------------------------- /docs/intermediate_node.md: -------------------------------------------------------------------------------- 1 | # Intermediate Guide (nodejs version) 2 | 3 | This guide details using Blanket.js with a mocha testrunner, and the travis-cov reporter in NodeJS. 4 | 5 | It is assumed you have already read the Getting Started guide. 6 | 7 | To begin you will need: 8 | * an existing mocha tests/test runner (including the mocha module, `npm install mocha -g`) 9 | * source files 10 | 11 | 1. Install Blanket: `npm install blanket` 12 | 13 | 2. Add the following to top of your test runner file: 14 | 15 | ``` 16 | var blanket = require("blanket")({ 17 | /* options are passed as an argument object to the require statement */ 18 | "pattern": "/source/" 19 | }); 20 | ``` 21 | 22 | ... where `/source/` matches partially or fully the directory where the source files to be instrumented are stored. 23 | You can also provide an array of regular expression. 24 | 25 | 3. Omitting the object argument will default to "src". Additionally, any value provided there will override values set in the package.json file. 26 | 27 | 4. Since we've explicit referenced blanket we don't need to require it in the mocha command. 28 | 29 | 5. Install the travis-cov reporter: `npm install travis-cov` 30 | 31 | 6. We will set the coverage threshold in the package.json file. The following will set the coverage threshold at 70%. Any tests falling below 70% will fail, and (when run on travis-ci) will cause the build to fail: 32 | 33 | ` "config": { 34 | "travis-cov": { 35 | "threshold": 70 36 | } 37 | }` 38 | 39 | 7. Use the travis-cov reporter to display coverage percentage: 40 | 41 | ```mocha -R travis-cov``` 42 | 43 | -------------------------------------------------------------------------------- /docs/intermediate_node_2.md: -------------------------------------------------------------------------------- 1 | # Intermediate Guide (nodejs version) 2 | 3 | This guide details using Blanket.js with a locally installed mocha testrunner with their built-in html-cov reporter 4 | in NodeJS by using configuration options in package.json. This is useful for running coverage on remote continuous 5 | integration services like CircleCI or TravisCI. 6 | 7 | It is assumed you have already read the Getting Started guide. 8 | 9 | 1. Install Mocha locally: `npm install mocha --save-dev` 10 | 11 | 1. Install Blanket: `npm install blanket --save-dev` 12 | 13 | 2. Install mocha-multi so we can use two reporters at once. One reporter is the result of the tests, and the other is 14 | for coverage. `npm install mocha-multi --save-dev` 15 | 16 | 3. In your package.json file, add the following: 17 | 18 | ```json 19 | "scripts": { 20 | "start": "node app.js", 21 | "test": "multi='dot=- html-cov=coverage.html' ./node_modules/mocha/bin/mocha -r blanket --reporter mocha-multi --no-colors" 22 | }, 23 | "config": { 24 | "blanket": { 25 | "pattern": "//\/[\\w-]+\\.js$/", 26 | "data-cover-never": [ 27 | "node_modules", 28 | "public" 29 | ], 30 | "data-cover-reporter-options": { 31 | "shortnames": true 32 | } 33 | } 34 | }, 35 | ``` 36 | 37 | In this example, we're not unit testing the node_modules or the public directories, and we're only reporting coverage 38 | for files that only have letters or dashes in their names. This would show coverage for `index.js`, but not `index.test.js`. 39 | 40 | The short names option would only report the file's name, and not its complete path. 41 | 42 | 4. Run `npm test`. It will report the results of the unit tests, and create coverage.html in your project's root. 43 | 44 | -------------------------------------------------------------------------------- /docs/special_features.md: -------------------------------------------------------------------------------- 1 | # Special Features Guide (browser version) 2 | 3 | This guide details special features available in Blanket.js, including: branch tracking, and the local uploader. 4 | 5 | 6 | ## Branch Tracking 7 | 8 | Enabling branch tracking allows you to determine if there are branches in your code that are not followed. 9 | 10 | For example: 11 | 12 | ``` 13 | function fcn(x){ 14 | return = x > 5 ? 1 : 2; 15 | } 16 | ``` 17 | 18 | If your test only calls fcn(6), then the code that is executed when x < 5 is never executed. This could leave logic blocks untested. 19 | 20 | To enable branch tracking use the `data-cover-flags` attribute on the blanket source script reference tag in the test runner: 21 | 22 | `` 23 | 24 | The default reporter will highlight untouched branches in yellow. 25 | 26 | 27 | ## Local Uploader 28 | 29 | If blanket is run locally (with file:// protocol), the loading of source files for instrumentation may fail. Some browsers may throw a cross origin resource sharing error. 30 | 31 | The current workarounds are to [start Chrome with flags](http://askubuntu.com/questions/160245/making-google-chrome-option-allow-file-access-from-files-permanent), use a local server (testserver.js is included for this purpose, and serve is also a good option - `npm install serve -g`), or use a browser that supports cross domain local browser requests (some version of Safari). 32 | 33 | The local uploader is a feature that allows you to manually select the source folders or files to allow them to be instrumented (despite the CORS issues). 34 | 35 | The local uploader uses the HTML5 file upload API to read the files locally and then pass them to blanket for instrumentation. 36 | 37 | This feature is for demonstration purposes and should be abandoned in favour of one of the workarounds mentioned above. 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blanket", 3 | "description": "seamless js code coverage", 4 | "version": "1.2.3", 5 | "homepage": "https://github.com/alex-seville/blanket", 6 | "author": { 7 | "name": "Alex-Seville", 8 | "email": "hi@alexanderseville.com", 9 | "url": "http://blanketjs.org" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git://github.com/alex-seville/blanket.git" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/alex-seville/blanket/issues" 17 | }, 18 | "license": "MIT", 19 | "main": "src/index.js", 20 | "engines": { 21 | "node": ">=0.10.7" 22 | }, 23 | "dependencies": { 24 | "acorn": "^1.0.3", 25 | "falafel": "~1.2.0", 26 | "foreach": "^2.0.5", 27 | "isarray": "0.0.1", 28 | "object-keys": "^1.0.6", 29 | "xtend": "~4.0.0" 30 | }, 31 | "devDependencies": { 32 | "async": "~1.4.0", 33 | "coffee-react": "^4.0.0", 34 | "coffee-script": "~1.9.3", 35 | "grunt": "~0.4.5", 36 | "grunt-cli": "^0.1.13", 37 | "grunt-contrib-clean": "~0.6.0", 38 | "grunt-contrib-concat": "~0.5.1", 39 | "grunt-contrib-jshint": "~0.11.2", 40 | "grunt-contrib-uglify": "~0.9.1", 41 | "load-grunt-tasks": "~3.2.0", 42 | "mocha": "~2.2.5", 43 | "phantomjs": "1.9.17", 44 | "requirejs": "~2.1.19", 45 | "react": "^0.13.3", 46 | "travis-cov": "*", 47 | "uglify-save-license": "~0.4.1" 48 | }, 49 | "scripts": { 50 | "build": "grunt build", 51 | "test": "grunt --verbose blanketTest" 52 | }, 53 | "config": { 54 | "blanket": { 55 | "pattern": "test", 56 | "data-cover-flags": { 57 | "debug": false 58 | }, 59 | "loader": "./node-loaders/coffee-script", 60 | "data-cover-reporter-options": { 61 | "shortnames": true 62 | } 63 | }, 64 | "travis-cov": { 65 | "threshold": 70, 66 | "removeKey": "branchFcn" 67 | } 68 | }, 69 | "keywords": [ 70 | "coverage" 71 | ] 72 | } 73 | -------------------------------------------------------------------------------- /src/adapters/jasmine-2.x-blanket.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | if (! jasmine) { 4 | throw new Exception("jasmine library does not exist in global namespace!"); 5 | } 6 | 7 | function elapsed(startTime, endTime) { 8 | return (endTime - startTime)/1000; 9 | } 10 | 11 | function ISODateString(d) { 12 | function pad(n) { return n < 10 ? '0'+n : n; } 13 | 14 | return d.getFullYear() + '-' + 15 | pad(d.getMonth()+1) + '-' + 16 | pad(d.getDate()) + 'T' + 17 | pad(d.getHours()) + ':' + 18 | pad(d.getMinutes()) + ':' + 19 | pad(d.getSeconds()); 20 | } 21 | 22 | function trim(str) { 23 | return str.replace(/^\s+/, "" ).replace(/\s+$/, "" ); 24 | } 25 | 26 | function escapeInvalidXmlChars(str) { 27 | return str.replace(/\&/g, "&") 28 | .replace(//g, ">") 30 | .replace(/\"/g, """) 31 | .replace(/\'/g, "'"); 32 | } 33 | 34 | /** 35 | * based on https://raw.github.com/larrymyers/jasmine-reporters/master/src/jasmine.junit_reporter.js 36 | */ 37 | var BlanketReporter = function(savePath, consolidate, useDotNotation) { 38 | 39 | blanket.setupCoverage(); 40 | }; 41 | BlanketReporter.finished_at = null; // will be updated after all files have been written 42 | 43 | BlanketReporter.prototype = { 44 | specStarted: function(spec) { 45 | blanket.onTestStart(); 46 | }, 47 | 48 | specDone: function(result) { 49 | var passed = result.status === "passed" ? 1 : 0; 50 | blanket.onTestDone(1,passed); 51 | }, 52 | 53 | jasmineDone: function() { 54 | blanket.onTestsDone(); 55 | }, 56 | 57 | log: function(str) { 58 | var console = jasmine.getGlobal().console; 59 | 60 | if (console && console.log) { 61 | console.log(str); 62 | } 63 | } 64 | }; 65 | 66 | // export public 67 | jasmine.BlanketReporter = BlanketReporter; 68 | 69 | //override existing jasmine execute 70 | var originalJasmineExecute = jasmine.getEnv().execute; 71 | jasmine.getEnv().execute = function(){ console.log("waiting for blanket..."); }; 72 | 73 | 74 | blanket.beforeStartTestRunner({ 75 | checkRequirejs:true, 76 | callback:function(){ 77 | jasmine.getEnv().addReporter(new jasmine.BlanketReporter()); 78 | jasmine.getEnv().execute = originalJasmineExecute; 79 | jasmine.getEnv().execute(); 80 | } 81 | }); 82 | })(); -------------------------------------------------------------------------------- /src/adapters/jasmine-blanket.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | if (typeof jasmine === "undefined") { 4 | throw new Exception("jasmine library does not exist in global namespace!"); 5 | } 6 | 7 | function elapsed(startTime, endTime) { 8 | return (endTime - startTime)/1000; 9 | } 10 | 11 | function ISODateString(d) { 12 | function pad(n) { return n < 10 ? '0'+n : n; } 13 | 14 | return d.getFullYear() + '-' + 15 | pad(d.getMonth()+1) + '-' + 16 | pad(d.getDate()) + 'T' + 17 | pad(d.getHours()) + ':' + 18 | pad(d.getMinutes()) + ':' + 19 | pad(d.getSeconds()); 20 | } 21 | 22 | function trim(str) { 23 | return str.replace(/^\s+/, "" ).replace(/\s+$/, "" ); 24 | } 25 | 26 | function escapeInvalidXmlChars(str) { 27 | return str.replace(/\&/g, "&") 28 | .replace(//g, ">") 30 | .replace(/\"/g, """) 31 | .replace(/\'/g, "'"); 32 | } 33 | 34 | /** 35 | * based on https://raw.github.com/larrymyers/jasmine-reporters/master/src/jasmine.junit_reporter.js 36 | */ 37 | var BlanketReporter = function(savePath, consolidate, useDotNotation) { 38 | 39 | blanket.setupCoverage(); 40 | }; 41 | BlanketReporter.finished_at = null; // will be updated after all files have been written 42 | 43 | BlanketReporter.prototype = { 44 | reportSpecStarting: function(spec) { 45 | blanket.onTestStart(); 46 | }, 47 | 48 | reportSpecResults: function(suite) { 49 | var results = suite.results(); 50 | 51 | blanket.onTestDone(results.totalCount,results.passed()); 52 | }, 53 | 54 | reportRunnerResults: function(runner) { 55 | blanket.onTestsDone(); 56 | }, 57 | 58 | log: function(str) { 59 | var console = jasmine.getGlobal().console; 60 | 61 | if (console && console.log) { 62 | console.log(str); 63 | } 64 | } 65 | }; 66 | 67 | 68 | // export public 69 | jasmine.BlanketReporter = BlanketReporter; 70 | 71 | //override existing jasmine execute 72 | jasmine.getEnv().execute = function(){ console.log("waiting for blanket..."); }; 73 | 74 | //check to make sure requirejs is completed before we start the test runner 75 | var allLoaded = function() { 76 | return window.jasmine.getEnv().currentRunner().specs().length > 0 && blanket.requireFilesLoaded(); 77 | }; 78 | 79 | blanket.beforeStartTestRunner({ 80 | checkRequirejs:true, 81 | condition: allLoaded, 82 | callback:function(){ 83 | jasmine.getEnv().addReporter(new jasmine.BlanketReporter()); 84 | window.jasmine.getEnv().currentRunner().execute(); 85 | jasmine.getEnv().execute = function () { 86 | jasmine.getEnv().currentRunner().execute(); 87 | }; 88 | } 89 | }); 90 | })(); 91 | -------------------------------------------------------------------------------- /src/adapters/mocha-blanket.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | if(!mocha) { 4 | throw new Exception("mocha library does not exist in global namespace!"); 5 | } 6 | 7 | 8 | /* 9 | * Mocha Events: 10 | * 11 | * - `start` execution started 12 | * - `end` execution complete 13 | * - `suite` (suite) test suite execution started 14 | * - `suite end` (suite) all tests (and sub-suites) have finished 15 | * - `test` (test) test execution started 16 | * - `test end` (test) test completed 17 | * - `hook` (hook) hook execution started 18 | * - `hook end` (hook) hook complete 19 | * - `pass` (test) test passed 20 | * - `fail` (test, err) test failed 21 | * 22 | */ 23 | 24 | var OriginalReporter = mocha._reporter; 25 | 26 | var BlanketReporter = function(runner) { 27 | runner.on('start', function() { 28 | blanket.setupCoverage(); 29 | }); 30 | 31 | runner.on('end', function() { 32 | blanket.onTestsDone(); 33 | }); 34 | 35 | runner.on('suite', function() { 36 | blanket.onModuleStart(); 37 | }); 38 | 39 | runner.on('test', function() { 40 | blanket.onTestStart(); 41 | }); 42 | 43 | runner.on('test end', function(test) { 44 | blanket.onTestDone(test.parent.tests.length, test.state === 'passed'); 45 | }); 46 | 47 | runner.on('hook', function(){ 48 | blanket.onTestStart(); 49 | }); 50 | 51 | runner.on('hook end', function(){ 52 | blanket.onTestsDone(); 53 | }); 54 | 55 | // NOTE: this is an instance of BlanketReporter 56 | new OriginalReporter(runner); 57 | }; 58 | 59 | BlanketReporter.prototype = OriginalReporter.prototype; 60 | 61 | mocha.reporter(BlanketReporter); 62 | 63 | var oldRun = mocha.run, 64 | oldCallback = null; 65 | 66 | mocha.run = function (finishCallback) { 67 | oldCallback = finishCallback; 68 | console.log("waiting for blanket..."); 69 | }; 70 | blanket.beforeStartTestRunner({ 71 | callback: function(){ 72 | if (!blanket.options("existingRequireJS")){ 73 | oldRun(oldCallback); 74 | } 75 | mocha.run = oldRun; 76 | } 77 | }); 78 | })(); 79 | -------------------------------------------------------------------------------- /src/adapters/yui-blanket.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | if(!YUI) { 4 | throw new Exception("YUI does not exist in global namespace!"); 5 | } 6 | 7 | YUI.add('blanket', function (Y) { 8 | var TestRunner = Y.Test.Runner; 9 | 10 | TestRunner.subscribe(TestRunner.COMPLETE_EVENT,function(data){ 11 | var res = data.results; 12 | blanket.onTestDone(res.total, res.failed === 0 && (res.passed+res.ignored) === res.total); 13 | }); 14 | 15 | TestRunner.subscribe(TestRunner.BEGIN_EVENT,function(){ 16 | blanket.setupCoverage(); 17 | }); 18 | 19 | TestRunner.subscribe(TestRunner.TEST_CASE_COMPLETE_EVENT,function(){ 20 | blanket.onTestsDone(); 21 | }); 22 | 23 | TestRunner.subscribe(TestRunner.TEST_SUITE_BEGIN_EVENT,function(){ 24 | blanket.onModuleStart(); 25 | }); 26 | 27 | TestRunner.subscribe(TestRunner.TEST_CASE_BEGIN_EVENT,function(){ 28 | blanket.onTestStart(); 29 | }); 30 | },'0.0.1',{ 31 | requires :['test'] 32 | }); 33 | })(); -------------------------------------------------------------------------------- /src/node-loaders/cjsx.js: -------------------------------------------------------------------------------- 1 | var simpleNodeLoader = require('./simple-node-loader'); 2 | 3 | module.exports = function(blanket) { 4 | var compiler = require("coffee-react"), 5 | oldLoaderCS = require.extensions['.cjsx']; 6 | 7 | var compile = function(content) { 8 | return compiler.compile(content); 9 | }; 10 | 11 | require.extensions['.cjsx'] = simpleNodeLoader(blanket, oldLoaderCS, compile, /\.cjsx/); 12 | }; 13 | -------------------------------------------------------------------------------- /src/node-loaders/coffee-script.js: -------------------------------------------------------------------------------- 1 | var simpleNodeLoader = require('./simple-node-loader'); 2 | 3 | module.exports = function(blanket) { 4 | var coffeeScript = require("coffee-script"), 5 | oldLoaderCS = require.extensions['.coffee']; 6 | 7 | var compile = function(content) { 8 | return coffeeScript.compile(content); 9 | }; 10 | 11 | require.extensions['.coffee'] = simpleNodeLoader(blanket, oldLoaderCS, compile, /\.coffee$/); 12 | }; 13 | -------------------------------------------------------------------------------- /src/node-loaders/dynamic-loader.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"); 2 | var path = require("path"); 3 | 4 | 5 | var transpile = function(transpiler, filename) { 6 | var transpiled = ''; 7 | m = { 8 | _compile: function(c) { 9 | transpiled = c; 10 | } 11 | }; 12 | transpiler(m, filename); 13 | return transpiled; 14 | }; 15 | 16 | var wrapTranspiler = function(blanket, extension, oldLoader) { 17 | return function(localModule, filename) { 18 | var antipattern = blanket.options("antifilter"); 19 | var pattern = blanket.options("filter"); 20 | var reporter_options = blanket.options("reporter_options"); 21 | var originalFilename = filename; 22 | var filenamePattern = new RegExp(extension, "i"); 23 | 24 | filename = blanket.normalizeBackslashes(filename); 25 | 26 | if (typeof antipattern !== "undefined" && blanket.matchPattern(filename.replace(filenamePattern, ""), antipattern)) { 27 | if (blanket.options("debug")) { 28 | console.log("BLANKET-File will never be instrumented:" + filename); 29 | } 30 | oldLoader(localModule, filename); 31 | } else if (blanket.matchPattern(filename, pattern)) { 32 | if (blanket.options("debug")) { 33 | console.log("BLANKET-Attempting instrument of:" + filename); 34 | } 35 | 36 | var content = transpile(oldLoader, filename); 37 | var inputFilename = filename; 38 | if (reporter_options && reporter_options.shortnames) { 39 | inputFilename = filename.replace(path.dirname(filename), ""); 40 | } else if (reporter_options && reporter_options.relativepath) { 41 | inputFilename = filename.replace(process.cwd(), ""); 42 | } 43 | if (reporter_options && reporter_options.basepath) { 44 | inputFilename = filename.replace(reporter_options.basepath + '/', ""); 45 | } 46 | 47 | blanket.instrument({ 48 | inputFile: content, 49 | inputFileName: inputFilename 50 | }, function (instrumented) { 51 | var baseDirPath = blanket.normalizeBackslashes(path.dirname(filename)) + '/.'; 52 | try { 53 | instrumented = instrumented.replace(/require\s*\(\s*("|')\./g, 'require($1' + baseDirPath); 54 | localModule._compile(instrumented, originalFilename); 55 | } catch (err) { 56 | console.log("Error parsing instrumented code: " + err); 57 | } 58 | }); 59 | } else { 60 | oldLoader(localModule, filename); 61 | } 62 | }; 63 | }; 64 | 65 | module.exports = function(blanket) { 66 | var extensions = require.extensions; 67 | for (var extension in extensions) { 68 | if (extensions.hasOwnProperty(extension)) { 69 | var transpiler = extensions[extension]; 70 | require.extensions[extension] = wrapTranspiler(blanket, extension, transpiler) 71 | } 72 | } 73 | 74 | }; -------------------------------------------------------------------------------- /src/node-loaders/iced-coffee-script.js: -------------------------------------------------------------------------------- 1 | var simpleNodeLoader = require('./simple-node-loader'); 2 | 3 | module.exports = function(blanket) { 4 | var coffeeScript = require("iced-coffee-script"), 5 | oldLoaderCS = require.extensions['.iced']; 6 | 7 | var compile = function(content) { 8 | return coffeeScript.compile(content); 9 | }; 10 | 11 | require.extensions['.iced'] = simpleNodeLoader(blanket, oldLoaderCS, compile, /\.iced$/); 12 | }; 13 | -------------------------------------------------------------------------------- /src/node-loaders/simple-node-loader.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"), 2 | path = require("path"); 3 | 4 | module.exports = function(blanket, oldLoader, compile, filenamePattern) { 5 | return function(localModule, filename) { 6 | 7 | var antipattern = blanket.options("antifilter"), 8 | pattern = blanket.options("filter"), 9 | reporter_options = blanket.options("reporter_options"), 10 | originalFilename = filename; 11 | filename = blanket.normalizeBackslashes(filename); 12 | 13 | if (typeof antipattern !== "undefined" && blanket.matchPattern(filename.replace(filenamePattern, ""), antipattern)) { 14 | 15 | oldLoader(localModule, filename); 16 | if (blanket.options("debug")) { 17 | console.log("BLANKET-File will never be instrumented:" + filename); 18 | } 19 | } else if (blanket.matchPattern(filename, pattern)) { 20 | if (blanket.options("debug")) { 21 | console.log("BLANKET-Attempting instrument of:" + filename); 22 | } 23 | 24 | var content = fs.readFileSync(filename, 'utf8'); 25 | content = compile(content); 26 | 27 | var inputFilename = filename; 28 | if (reporter_options && reporter_options.shortnames){ 29 | inputFilename = filename.replace(path.dirname(filename),""); 30 | } else if (reporter_options && reporter_options.relativepath) { 31 | inputFilename = filename.replace(process.cwd(),""); 32 | } 33 | if (reporter_options && reporter_options.basepath){ 34 | inputFilename = filename.replace(reporter_options.basepath + '/',""); 35 | } 36 | 37 | blanket.instrument({ 38 | inputFile: content, 39 | inputFileName: inputFilename 40 | }, function(instrumented) { 41 | var baseDirPath = blanket.normalizeBackslashes(path.dirname(filename)) + '/.'; 42 | try { 43 | instrumented = instrumented.replace(/require\s*\(\s*("|')\./g, 'require($1' + baseDirPath); 44 | localModule._compile(instrumented, originalFilename); 45 | } catch (err) { 46 | console.log("Error parsing instrumented code: " + err); 47 | } 48 | }); 49 | } else { 50 | oldLoader(localModule, filename); 51 | } 52 | }; 53 | }; 54 | 55 | -------------------------------------------------------------------------------- /src/qunit/noautorun.js: -------------------------------------------------------------------------------- 1 | if (typeof QUnit !== 'undefined'){ QUnit.config.autostart = false; } -------------------------------------------------------------------------------- /src/qunit/qunit.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | if (typeof QUnit !== 'undefined'){ 3 | //check to make sure requirejs is completed before we start the test runner 4 | var allLoaded = function() { 5 | return window.QUnit.config.queue.length > 0 && blanket.noConflict().requireFilesLoaded(); 6 | }; 7 | 8 | if (!QUnit.config.urlConfig[0].tooltip){ 9 | //older versions we run coverage automatically 10 | //and we change how events are binded 11 | QUnit.begin=function(){ 12 | blanket.noConflict().setupCoverage(); 13 | }; 14 | 15 | QUnit.done=function(failures, total) { 16 | blanket.noConflict().onTestsDone(); 17 | }; 18 | QUnit.moduleStart=function( details ) { 19 | blanket.noConflict().onModuleStart(); 20 | }; 21 | QUnit.testStart=function( details ) { 22 | blanket.noConflict().onTestStart(); 23 | }; 24 | QUnit.testDone=function( details ) { 25 | blanket.noConflict().onTestDone(details.total,details.passed); 26 | }; 27 | blanket.beforeStartTestRunner({ 28 | condition: allLoaded, 29 | callback: QUnit.start 30 | }); 31 | }else{ 32 | QUnit.config.urlConfig.push({ 33 | id: "coverage", 34 | label: "Enable coverage", 35 | tooltip: "Enable code coverage." 36 | }); 37 | 38 | if ( QUnit.urlParams.coverage || blanket.options("autoStart") ) { 39 | QUnit.begin(function(){ 40 | blanket.noConflict().setupCoverage(); 41 | }); 42 | 43 | QUnit.done(function(failures, total) { 44 | blanket.noConflict().onTestsDone(); 45 | }); 46 | QUnit.moduleStart(function( details ) { 47 | blanket.noConflict().onModuleStart(); 48 | }); 49 | QUnit.testStart(function( details ) { 50 | blanket.noConflict().onTestStart(); 51 | }); 52 | QUnit.testDone(function( details ) { 53 | blanket.noConflict().onTestDone(details.total,details.passed); 54 | }); 55 | blanket.noConflict().beforeStartTestRunner({ 56 | condition: allLoaded, 57 | callback: function(){ 58 | if (!(blanket.options("existingRequireJS") && !blanket.options("autoStart"))){ 59 | QUnit.start(); 60 | } 61 | } 62 | }); 63 | }else{ 64 | if (blanket.options("existingRequireJS")){ requirejs.load = _blanket.utils.oldloader; } 65 | blanket.noConflict().beforeStartTestRunner({ 66 | condition: allLoaded, 67 | callback: function(){ 68 | if (!(blanket.options("existingRequireJS") && !blanket.options("autoStart"))){ 69 | QUnit.start(); 70 | } 71 | }, 72 | coverage:false 73 | }); 74 | } 75 | } 76 | } 77 | })(); -------------------------------------------------------------------------------- /src/reporters/lcov_reporter.js: -------------------------------------------------------------------------------- 1 | //lcov_reporter 2 | (function (){ 3 | //takes the option: toHTML {boolean} 4 | 5 | var body = document.body; 6 | 7 | var appendHtml = function ( filename,data,toHTML) { 8 | 9 | var str=""; 10 | str += 'SF:' + filename + '\n'; 11 | 12 | data.source.forEach(function(line, num) { 13 | // increase the line number, as JS arrays are zero-based 14 | num++; 15 | 16 | if (data[num] !== undefined) { 17 | str += 'DA:' + num + ',' + data[num] + '\n'; 18 | } 19 | }); 20 | 21 | str += 'end_of_record\n'; 22 | if (toHTML){ 23 | var div = document.createElement('div'); 24 | div.className = "blanket_lcov_reporter"; 25 | div.innerText = str; 26 | body.appendChild(div); 27 | }else{ 28 | window._$blanket_LCOV = (window._$blanket_LCOV || '') + str; 29 | } 30 | }; 31 | 32 | blanket.customReporter=function(coverageData,options){ 33 | var toHTML=true; 34 | if (typeof options !== 'undefined' && typeof options.toHTML !== 'undefined'){ 35 | toHTML = options.toHTML; 36 | } 37 | for (var filename in coverageData.files) { 38 | var data = coverageData.files[filename]; 39 | appendHtml(filename,data,toHTML); 40 | } 41 | }; 42 | })(); 43 | -------------------------------------------------------------------------------- /src/reporters/simple_json_reporter.js: -------------------------------------------------------------------------------- 1 | //simple_json_reporter 2 | (function (){ 3 | 4 | var body = document.body; 5 | 6 | var appendHtml = function (el, str) { 7 | var div = document.createElement('div'); 8 | div.innerText = str; 9 | el.appendChild(div); 10 | }; 11 | 12 | blanket.customReporter= function(coverageData){ 13 | appendHtml(body, JSON.stringify(coverageData,null,"\t")); 14 | }; 15 | })(); -------------------------------------------------------------------------------- /tasks/blanketTests.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | // ========================================================================== 4 | // BLANKET TEST TASK 5 | // ========================================================================== 6 | 7 | grunt.registerMultiTask('blanketTest', 'Run tests for blanket.', function() { 8 | var async = require('async'); 9 | 10 | var testConfigs = grunt.file.readJSON("test/testconfigs.json"); 11 | var data; 12 | var done = this.async(); 13 | 14 | var testCommands = []; 15 | 16 | for(var test in this.data){ 17 | //grunt.log.write("test:"+this.data[test]+"\n"); 18 | //grunt.log.write("data:"+data+"\n"); 19 | testCommands.push(this.data[test].toString()); 20 | } 21 | 22 | async.eachSeries(testCommands, function(cmd, next) { 23 | var command = cmd.split(" "); 24 | 25 | grunt.verbose.write("\nRunning:"+command[0]+" "+command.slice(1).join(" ")+"\n"); 26 | grunt.util.spawn({ 27 | cmd: command[0], 28 | args: command.slice(1) 29 | }, function(err, result, code) { 30 | if (!err) { 31 | grunt.log.write(result+"\n"); 32 | } else { 33 | grunt.log.write("\nError:"+result); 34 | done(false); 35 | } 36 | next(); 37 | }); 38 | }, done); 39 | }); 40 | 41 | }; -------------------------------------------------------------------------------- /test/backbone-koans/filter_function.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Backbone Koans with filter function 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |

Backbone Koans

33 | 34 |

QUnit Test Suite

35 |

36 |
37 |

38 |
    39 |
    40 |
    41 | 42 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /test/backbone-koans/images/destroy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-seville/blanket/db93808886817ad70e5b8b712e08b930f41dd225/test/backbone-koans/images/destroy.png -------------------------------------------------------------------------------- /test/backbone-koans/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Backbone Koans 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |

    Backbone Koans

    30 | 31 |

    QUnit Test Suite

    32 |

    33 |
    34 |

    35 |
      36 |
      37 |
      38 | 39 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /test/backbone-koans/js/ext/backbone.localStorage.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Backbone localStorage Adapter v1.0 3 | * https://github.com/jeromegn/Backbone.localStorage 4 | */ 5 | 6 | // A simple module to replace `Backbone.sync` with *localStorage*-based 7 | // persistence. Models are given GUIDS, and saved into a JSON object. Simple 8 | // as that. 9 | 10 | // Generate four random hex digits. 11 | function S4() { 12 | return (((1+Math.random())*0x10000)|0).toString(16).substring(1); 13 | }; 14 | 15 | // Generate a pseudo-GUID by concatenating random hexadecimal. 16 | function guid() { 17 | return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4()); 18 | }; 19 | 20 | // Our Store is represented by a single JS object in *localStorage*. Create it 21 | // with a meaningful name, like the name you'd give a table. 22 | window.Store = function(name) { 23 | this.name = name; 24 | var store = localStorage.getItem(this.name); 25 | this.records = (store && store.split(",")) || []; 26 | }; 27 | 28 | _.extend(Store.prototype, { 29 | 30 | // Save the current state of the **Store** to *localStorage*. 31 | save: function() { 32 | localStorage.setItem(this.name, this.records.join(",")); 33 | }, 34 | 35 | // Add a model, giving it a (hopefully)-unique GUID, if it doesn't already 36 | // have an id of it's own. 37 | create: function(model) { 38 | if (!model.id) model.id = model.attributes.id = guid(); 39 | localStorage.setItem(this.name+"-"+model.id, JSON.stringify(model)); 40 | this.records.push(model.id.toString()); 41 | this.save(); 42 | return model; 43 | }, 44 | 45 | // Update a model by replacing its copy in `this.data`. 46 | update: function(model) { 47 | localStorage.setItem(this.name+"-"+model.id, JSON.stringify(model)); 48 | if (!_.include(this.records, model.id.toString())) this.records.push(model.id.toString()); this.save(); 49 | return model; 50 | }, 51 | 52 | // Retrieve a model from `this.data` by id. 53 | find: function(model) { 54 | return JSON.parse(localStorage.getItem(this.name+"-"+model.id)); 55 | }, 56 | 57 | // Return the array of all models currently in storage. 58 | findAll: function() { 59 | return _.map(this.records, function(id){return JSON.parse(localStorage.getItem(this.name+"-"+id));}, this); 60 | }, 61 | 62 | // Delete a model from `this.data`, returning it. 63 | destroy: function(model) { 64 | localStorage.removeItem(this.name+"-"+model.id); 65 | this.records = _.reject(this.records, function(record_id){return record_id == model.id.toString();}); 66 | this.save(); 67 | return model; 68 | } 69 | 70 | }); 71 | 72 | // localSync delegate to the model or collection's 73 | // *localStorage* property, which should be an instance of `Store`. 74 | Backbone.localSync = function(method, model, options, error) { 75 | 76 | // Backwards compatibility with Backbone <= 0.3.3 77 | if (typeof options == 'function') { 78 | options = { 79 | success: options, 80 | error: error 81 | }; 82 | } 83 | 84 | var resp; 85 | var store = model.localStorage || model.collection.localStorage; 86 | 87 | switch (method) { 88 | case "read": resp = model.id != undefined ? store.find(model) : store.findAll(); break; 89 | case "create": resp = store.create(model); break; 90 | case "update": resp = store.update(model); break; 91 | case "delete": resp = store.destroy(model); break; 92 | } 93 | 94 | if (resp) { 95 | options.success(resp); 96 | } else { 97 | options.error("Record not found"); 98 | } 99 | }; 100 | 101 | // Override 'Backbone.sync' to default to localSync, 102 | // the original 'Backbone.sync' is still available in 'Backbone.ajaxSync' 103 | Backbone.ajaxSync = Backbone.sync; 104 | Backbone.sync = Backbone.localSync; 105 | -------------------------------------------------------------------------------- /test/backbone-koans/js/ext/sinon-qunit-1.0.0.js: -------------------------------------------------------------------------------- 1 | /** 2 | * sinon-qunit 1.0.0, 2010/12/09 3 | * 4 | * @author Christian Johansen (christian@cjohansen.no) 5 | * 6 | * (The BSD License) 7 | * 8 | * Copyright (c) 2010-2011, Christian Johansen, christian@cjohansen.no 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 14 | * * Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * * Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * * Neither the name of Christian Johansen nor the names of his contributors 20 | * may be used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | /*global sinon, QUnit, test*/ 35 | sinon.assert.fail = function (msg) { 36 | QUnit.ok(false, msg); 37 | }; 38 | 39 | sinon.assert.pass = function (assertion) { 40 | QUnit.ok(true, assertion); 41 | }; 42 | 43 | sinon.config = { 44 | injectIntoThis: true, 45 | injectInto: null, 46 | properties: ["spy", "stub", "mock", "clock", "sandbox"], 47 | useFakeTimers: true, 48 | useFakeServer: false 49 | }; 50 | 51 | (function (global) { 52 | var qTest = QUnit.test; 53 | 54 | QUnit.test = global.test = function (testName, expected, callback, async) { 55 | if (arguments.length === 2) { 56 | callback = expected; 57 | expected = null; 58 | } 59 | 60 | return qTest(testName, expected, sinon.test(callback), async); 61 | }; 62 | }(this)); 63 | -------------------------------------------------------------------------------- /test/backbone-koans/js/ext/template.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | var cache = {}; 4 | 5 | function _render(elt, template, data, callback) { 6 | var data = data || {}, 7 | callback = callback || function() {}, 8 | html = template(data); 9 | 10 | elt.append(html); 11 | callback(); 12 | } 13 | 14 | 15 | /** 16 | * Fetches the Underscore.js template at the given path, 17 | * processes it with the provided data object, and appends the 18 | * resulting html to the matched DOM elements. 19 | * 20 | * Templates will only be fetched once from the server, 21 | * preprocessed template are cached in the DOM. 22 | */ 23 | $.fn.template = function(path, obj, callback) { 24 | var self = this; 25 | 26 | if (cache[path]) { 27 | _render(self, cache[path], obj, callback); 28 | return self; 29 | } 30 | 31 | $.get(path, function(data) { 32 | cache[path] = _.template(data); 33 | _render(self, cache[path], obj, callback); 34 | }); 35 | 36 | return self; 37 | }; 38 | 39 | 40 | })(jQuery); -------------------------------------------------------------------------------- /test/backbone-koans/js/koans/aboutApps.js: -------------------------------------------------------------------------------- 1 | module('About Backbone Applications', { 2 | setup: function() { 3 | Backbone.localStorageDB = new Store('testTodos'); 4 | $('#qunit-fixture').append('
      '); 5 | this.App = new TodoApp({ appendTo: $('#app') }); 6 | }, 7 | 8 | teardown: function() { 9 | this.App.todos.reset(); 10 | $('#app').remove(); 11 | } 12 | }); 13 | 14 | test('Should bootstrap the application by initializing the Collection.', function() { 15 | expect(2); 16 | notEqual(this.App.todos, undefined); 17 | equal(this.App.todos.length, 0); 18 | }); 19 | -------------------------------------------------------------------------------- /test/backbone-koans/js/koans/aboutCollections.js: -------------------------------------------------------------------------------- 1 | module('About Backbone.Collection'); 2 | 3 | test('Can add Model instances as objects and arrays.', function() { 4 | 5 | expect(3); 6 | 7 | var todos = new TodoList(); 8 | equal(todos.length, 0); 9 | 10 | todos.add({ text: 'Clean the kitchen' }); 11 | equal(todos.length, 1); 12 | 13 | todos.add([ 14 | { text: 'Do the laundry', done: true }, 15 | { text: 'Go to the gym'} 16 | ]); 17 | 18 | equal(todos.length, 3); 19 | }); 20 | 21 | test('Can have a url property to define the basic url structure for all contained models.', function() { 22 | expect(1); 23 | var todos = new TodoList(); 24 | equal(todos.url, '/todos/'); 25 | }); 26 | 27 | test('Fires custom named events when the models change.', function() { 28 | 29 | expect(2); 30 | var todos = new TodoList(); 31 | 32 | var addModelCallback = this.spy(); 33 | var removeModelCallback = this.spy(); 34 | 35 | todos.bind('add', addModelCallback); 36 | todos.bind('remove', removeModelCallback); 37 | 38 | // How would you get the 'add' event to trigger? 39 | todos.add({text:"New todo"}); 40 | 41 | ok(addModelCallback.called); 42 | 43 | // How would you get the 'remove' callback to trigger? 44 | todos.remove(todos.last()); 45 | 46 | ok(removeModelCallback.called); 47 | 48 | }); -------------------------------------------------------------------------------- /test/backbone-koans/js/koans/aboutEvents.js: -------------------------------------------------------------------------------- 1 | 2 | module('About Backbone.Events', { 3 | setup: function() { 4 | this.obj = {}; 5 | _.extend(this.obj, Backbone.Events); 6 | this.obj.unbind(); // remove all custom events before each spec is run. 7 | } 8 | }); 9 | 10 | test('Can extend javascript objects to support custom events.', function() { 11 | 12 | expect(3); 13 | var basicObject = {}; 14 | 15 | // How would you give basicObject these functions? 16 | // Hint: http://documentcloud.github.com/backbone/#Events 17 | 18 | _.extend(basicObject, Backbone.Events); 19 | 20 | equal(typeof basicObject.bind, 'function'); 21 | equal(typeof basicObject.unbind, 'function'); 22 | equal(typeof basicObject.trigger, 'function'); 23 | }); 24 | 25 | 26 | 27 | test('Allows us to bind and trigger custom named events on an object.', function() { 28 | 29 | expect(1); 30 | 31 | var callback = this.spy(); 32 | 33 | this.obj.bind('basic event', callback); 34 | 35 | this.obj.trigger("basic event"); 36 | // How would you cause the callback for this custom event to be called? 37 | 38 | ok(callback.called); 39 | 40 | }); 41 | 42 | 43 | test('Also passes along any arguments to the callback when an event is triggered.', function() { 44 | 45 | expect(1); 46 | 47 | var passedArgs = []; 48 | 49 | this.obj.bind('some event', function() { 50 | for (var i = 0; i < arguments.length; i++) { 51 | passedArgs.push(arguments[i]); 52 | } 53 | }); 54 | 55 | this.obj.trigger('some event', 'arg1', 'arg2'); 56 | 57 | deepEqual(passedArgs, ['arg1', 'arg2']); 58 | }); 59 | 60 | 61 | test('Can also bind the passed context to the event callback.', function() { 62 | 63 | expect(1); 64 | 65 | var foo = { color: 'blue' }; 66 | 67 | var changeColor = function() { 68 | this.color = 'red'; 69 | } 70 | 71 | // How would you get 'this.color' to refer to 'foo' in the changeColor function? 72 | this.obj.bind('an event', changeColor, foo); 73 | this.obj.trigger('an event'); 74 | 75 | equal(foo.color, 'red'); 76 | 77 | }); 78 | 79 | 80 | test("Uses 'all' as a special event name to capture all events bound to the object.", function() { 81 | 82 | expect(2); 83 | 84 | var callback = this.spy(); 85 | 86 | this.obj.bind('all', callback); 87 | 88 | this.obj.trigger("custom event 1"); 89 | this.obj.trigger("custom event 2"); 90 | 91 | equal(callback.callCount, 2); 92 | equal(callback.getCall(0).args[0], 'custom event 1'); 93 | 94 | }); 95 | 96 | 97 | test('Also can remove custom events from objects.', function() { 98 | 99 | expect(5); 100 | 101 | var spy1 = this.spy(); 102 | var spy2 = this.spy(); 103 | var spy3 = this.spy(); 104 | 105 | this.obj.bind('foo', spy1); 106 | this.obj.bind('foo', spy2); 107 | this.obj.bind('foo', spy3); 108 | this.obj.bind('bar', spy1); 109 | 110 | // How do you unbind just a single callback for the event? 111 | this.obj.unbind('foo', spy1); 112 | this.obj.trigger('foo'); 113 | 114 | ok(spy2.called); 115 | 116 | // How do you unbind all callbacks tied to the event with a single method 117 | this.obj.unbind('foo'); 118 | this.obj.trigger('foo'); 119 | 120 | 121 | ok(spy2.callCount, 1); 122 | ok(spy2.calledOnce, "Spy 2 called once"); 123 | ok(spy3.calledOnce, "Spy 3 called once"); 124 | 125 | // How do you unbind all callbacks and events tied to the object with a single method? 126 | this.obj.unbind('bar'); 127 | 128 | this.obj.trigger('bar'); 129 | 130 | equal(spy1.callCount, 0); 131 | 132 | 133 | 134 | }); 135 | 136 | -------------------------------------------------------------------------------- /test/backbone-koans/js/koans/aboutModels.js: -------------------------------------------------------------------------------- 1 | module('About Backbone.Model'); 2 | 3 | test('Can be created with default values for its attributes.', function() { 4 | expect(1); 5 | var todo = new Todo(); 6 | equal(todo.get('text'), ""); 7 | }); 8 | 9 | test('Will set passed attributes on the model instance when created.', function() { 10 | 11 | expect(3); 12 | var todo = new Todo({ text: 'Get oil change for car.' }); 13 | 14 | equal(todo.get('text'), "Get oil change for car."); 15 | equal(todo.get('done'), false); 16 | equal(todo.get('order'), 0); 17 | }); 18 | 19 | test('Will call a custom initialize function on the model instance when created.', function() { 20 | 21 | expect(1); 22 | var toot = new Todo({ text: 'Stop monkeys from throwing their own crap!' }); 23 | equal(toot.get('text'), 'Stop monkeys from throwing their own rainbows!'); 24 | }); 25 | 26 | test('Fires a custom event when the state changes.', function() { 27 | 28 | expect(1); 29 | 30 | var spy = this.spy(); 31 | 32 | var todo = new Todo(); 33 | 34 | todo.bind('change', spy); 35 | 36 | // How would you update a property on the todo here? 37 | // Hint: http://documentcloud.github.com/backbone/#Model-set 38 | 39 | todo.set({text:"new text"}); 40 | 41 | ok(spy.calledOnce, "A change event callback was correctly triggered"); 42 | 43 | }); 44 | 45 | 46 | test('Can contain custom validation rules, and will trigger an error event on failed validation.', function() { 47 | 48 | expect(3); 49 | var errorCallback = this.spy(); 50 | 51 | var todo = new Todo(); 52 | 53 | todo.bind('error', errorCallback); 54 | 55 | // What would you need to set on the todo properties to cause validation to fail? 56 | todo.set({done:"not a boolean"}); 57 | 58 | ok(errorCallback.called, 'A failed validation correctly triggered an error'); 59 | notEqual(errorCallback.getCall(0), undefined); 60 | equal(errorCallback.getCall(0).args[1], 'Todo.done must be a boolean value.'); 61 | 62 | }); 63 | -------------------------------------------------------------------------------- /test/backbone-koans/js/koans/aboutViews.js: -------------------------------------------------------------------------------- 1 | module('About Backbone.View', { 2 | setup: function() { 3 | $('body').append('
        '); 4 | this.todoView = new TodoView({ model: new Todo() }); 5 | }, 6 | teardown: function() { 7 | this.todoView.remove(); 8 | $('#todoList').remove(); 9 | } 10 | }); 11 | 12 | test('Should be tied to a DOM element when created, based off the property provided.', function() { 13 | equal(this.todoView.el.tagName.toLowerCase(), 'li'); 14 | }); 15 | 16 | test('Is backed by a model instance, which provides the data.', function() { 17 | notEqual(this.todoView.model, undefined); 18 | equal(this.todoView.model.get('done'), false); 19 | }); 20 | 21 | test('Can render, after which the DOM representation of the view will be visible.', function() { 22 | this.todoView.render(); 23 | 24 | // Hint: render() just builds the DOM representation of the view, but doesn't insert it into the DOM. 25 | // How would you append it to the ul#todoList? 26 | // How do you access the view's DOM representation? 27 | // 28 | // Hint: http://documentcloud.github.com/backbone/#View-el 29 | 30 | $('ul#todoList').append(this.todoView.el); 31 | equal($('#todoList').find('li').length, 1); 32 | }); 33 | -------------------------------------------------------------------------------- /test/backbone-koans/templates/app.html: -------------------------------------------------------------------------------- 1 |
        2 |
        3 |

        Todos

        4 |
        5 | 6 |
        7 |
        8 | 9 | 10 |
        11 | 12 |
        13 |
          14 |
          15 | 16 |
          17 |
          18 |
          -------------------------------------------------------------------------------- /test/backbone-koans/templates/item.html: -------------------------------------------------------------------------------- 1 |
          2 |
          3 | /> 4 |
          5 | 6 |
          7 |
          8 | 9 |
          10 |
          -------------------------------------------------------------------------------- /test/backbone-koans/templates/stats.html: -------------------------------------------------------------------------------- 1 | <% if (total) { %> 2 | 3 | <%= remaining %> 4 | <%= remaining == 1 ? 'item' : 'items' %> left. 5 | 6 | <% } %> 7 | <% if (done) { %> 8 | 9 | 10 | Clear <%= done %> 11 | completed <%= done == 1 ? 'item' : 'items' %> 12 | 13 | 14 | <% } %> -------------------------------------------------------------------------------- /test/bootstrap/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "validthis": true, 3 | "laxcomma" : true, 4 | "laxbreak" : true, 5 | "browser" : true, 6 | "eqnull" : true, 7 | "debug" : true, 8 | "devel" : true, 9 | "boss" : true, 10 | "expr" : true, 11 | "asi" : true 12 | } -------------------------------------------------------------------------------- /test/bootstrap/bootstrap-affix.js: -------------------------------------------------------------------------------- 1 | /* ========================================================== 2 | * bootstrap-affix.js v2.2.2 3 | * http://twitter.github.com/bootstrap/javascript.html#affix 4 | * ========================================================== 5 | * Copyright 2012 Twitter, Inc. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * ========================================================== */ 19 | 20 | 21 | !function ($) { 22 | 23 | "use strict"; // jshint ;_; 24 | 25 | 26 | /* AFFIX CLASS DEFINITION 27 | * ====================== */ 28 | 29 | var Affix = function (element, options) { 30 | this.options = $.extend({}, $.fn.affix.defaults, options) 31 | this.$window = $(window) 32 | .on('scroll.affix.data-api', $.proxy(this.checkPosition, this)) 33 | .on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this)) 34 | this.$element = $(element) 35 | this.checkPosition() 36 | } 37 | 38 | Affix.prototype.checkPosition = function () { 39 | if (!this.$element.is(':visible')) return 40 | 41 | var scrollHeight = $(document).height() 42 | , scrollTop = this.$window.scrollTop() 43 | , position = this.$element.offset() 44 | , offset = this.options.offset 45 | , offsetBottom = offset.bottom 46 | , offsetTop = offset.top 47 | , reset = 'affix affix-top affix-bottom' 48 | , affix 49 | 50 | if (typeof offset != 'object') offsetBottom = offsetTop = offset 51 | if (typeof offsetTop == 'function') offsetTop = offset.top() 52 | if (typeof offsetBottom == 'function') offsetBottom = offset.bottom() 53 | 54 | affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? 55 | false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 56 | 'bottom' : offsetTop != null && scrollTop <= offsetTop ? 57 | 'top' : false 58 | 59 | if (this.affixed === affix) return 60 | 61 | this.affixed = affix 62 | this.unpin = affix == 'bottom' ? position.top - scrollTop : null 63 | 64 | this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : '')) 65 | } 66 | 67 | 68 | /* AFFIX PLUGIN DEFINITION 69 | * ======================= */ 70 | 71 | var old = $.fn.affix 72 | 73 | $.fn.affix = function (option) { 74 | return this.each(function () { 75 | var $this = $(this) 76 | , data = $this.data('affix') 77 | , options = typeof option == 'object' && option 78 | if (!data) $this.data('affix', (data = new Affix(this, options))) 79 | if (typeof option == 'string') data[option]() 80 | }) 81 | } 82 | 83 | $.fn.affix.Constructor = Affix 84 | 85 | $.fn.affix.defaults = { 86 | offset: 0 87 | } 88 | 89 | 90 | /* AFFIX NO CONFLICT 91 | * ================= */ 92 | 93 | $.fn.affix.noConflict = function () { 94 | $.fn.affix = old 95 | return this 96 | } 97 | 98 | 99 | /* AFFIX DATA-API 100 | * ============== */ 101 | 102 | $(window).on('load', function () { 103 | $('[data-spy="affix"]').each(function () { 104 | var $spy = $(this) 105 | , data = $spy.data() 106 | 107 | data.offset = data.offset || {} 108 | 109 | data.offsetBottom && (data.offset.bottom = data.offsetBottom) 110 | data.offsetTop && (data.offset.top = data.offsetTop) 111 | 112 | $spy.affix(data) 113 | }) 114 | }) 115 | 116 | 117 | }(window.jQuery); -------------------------------------------------------------------------------- /test/bootstrap/bootstrap-alert.js: -------------------------------------------------------------------------------- 1 | /* ========================================================== 2 | * bootstrap-alert.js v2.2.2 3 | * http://twitter.github.com/bootstrap/javascript.html#alerts 4 | * ========================================================== 5 | * Copyright 2012 Twitter, Inc. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * ========================================================== */ 19 | 20 | 21 | !function ($) { 22 | 23 | "use strict"; // jshint ;_; 24 | 25 | 26 | /* ALERT CLASS DEFINITION 27 | * ====================== */ 28 | 29 | var dismiss = '[data-dismiss="alert"]' 30 | , Alert = function (el) { 31 | $(el).on('click', dismiss, this.close) 32 | } 33 | 34 | Alert.prototype.close = function (e) { 35 | var $this = $(this) 36 | , selector = $this.attr('data-target') 37 | , $parent 38 | 39 | if (!selector) { 40 | selector = $this.attr('href') 41 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 42 | } 43 | 44 | $parent = $(selector) 45 | 46 | e && e.preventDefault() 47 | 48 | $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) 49 | 50 | $parent.trigger(e = $.Event('close')) 51 | 52 | if (e.isDefaultPrevented()) return 53 | 54 | $parent.removeClass('in') 55 | 56 | function removeElement() { 57 | $parent 58 | .trigger('closed') 59 | .remove() 60 | } 61 | 62 | $.support.transition && $parent.hasClass('fade') ? 63 | $parent.on($.support.transition.end, removeElement) : 64 | removeElement() 65 | } 66 | 67 | 68 | /* ALERT PLUGIN DEFINITION 69 | * ======================= */ 70 | 71 | var old = $.fn.alert 72 | 73 | $.fn.alert = function (option) { 74 | return this.each(function () { 75 | var $this = $(this) 76 | , data = $this.data('alert') 77 | if (!data) $this.data('alert', (data = new Alert(this))) 78 | if (typeof option == 'string') data[option].call($this) 79 | }) 80 | } 81 | 82 | $.fn.alert.Constructor = Alert 83 | 84 | 85 | /* ALERT NO CONFLICT 86 | * ================= */ 87 | 88 | $.fn.alert.noConflict = function () { 89 | $.fn.alert = old 90 | return this 91 | } 92 | 93 | 94 | /* ALERT DATA-API 95 | * ============== */ 96 | 97 | $(document).on('click.alert.data-api', dismiss, Alert.prototype.close) 98 | 99 | }(window.jQuery); -------------------------------------------------------------------------------- /test/bootstrap/bootstrap-button.js: -------------------------------------------------------------------------------- 1 | /* ============================================================ 2 | * bootstrap-button.js v2.2.2 3 | * http://twitter.github.com/bootstrap/javascript.html#buttons 4 | * ============================================================ 5 | * Copyright 2012 Twitter, Inc. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * ============================================================ */ 19 | 20 | 21 | !function ($) { 22 | 23 | "use strict"; // jshint ;_; 24 | 25 | 26 | /* BUTTON PUBLIC CLASS DEFINITION 27 | * ============================== */ 28 | 29 | var Button = function (element, options) { 30 | this.$element = $(element) 31 | this.options = $.extend({}, $.fn.button.defaults, options) 32 | } 33 | 34 | Button.prototype.setState = function (state) { 35 | var d = 'disabled' 36 | , $el = this.$element 37 | , data = $el.data() 38 | , val = $el.is('input') ? 'val' : 'html' 39 | 40 | state = state + 'Text' 41 | data.resetText || $el.data('resetText', $el[val]()) 42 | 43 | $el[val](data[state] || this.options[state]) 44 | 45 | // push to event loop to allow forms to submit 46 | setTimeout(function () { 47 | state == 'loadingText' ? 48 | $el.addClass(d).attr(d, d) : 49 | $el.removeClass(d).removeAttr(d) 50 | }, 0) 51 | } 52 | 53 | Button.prototype.toggle = function () { 54 | var $parent = this.$element.closest('[data-toggle="buttons-radio"]') 55 | 56 | $parent && $parent 57 | .find('.active') 58 | .removeClass('active') 59 | 60 | this.$element.toggleClass('active') 61 | } 62 | 63 | 64 | /* BUTTON PLUGIN DEFINITION 65 | * ======================== */ 66 | 67 | var old = $.fn.button 68 | 69 | $.fn.button = function (option) { 70 | return this.each(function () { 71 | var $this = $(this) 72 | , data = $this.data('button') 73 | , options = typeof option == 'object' && option 74 | if (!data) $this.data('button', (data = new Button(this, options))) 75 | if (option == 'toggle') data.toggle() 76 | else if (option) data.setState(option) 77 | }) 78 | } 79 | 80 | $.fn.button.defaults = { 81 | loadingText: 'loading...' 82 | } 83 | 84 | $.fn.button.Constructor = Button 85 | 86 | 87 | /* BUTTON NO CONFLICT 88 | * ================== */ 89 | 90 | $.fn.button.noConflict = function () { 91 | $.fn.button = old 92 | return this 93 | } 94 | 95 | 96 | /* BUTTON DATA-API 97 | * =============== */ 98 | 99 | $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) { 100 | var $btn = $(e.target) 101 | if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') 102 | $btn.button('toggle') 103 | }) 104 | 105 | }(window.jQuery); -------------------------------------------------------------------------------- /test/bootstrap/bootstrap-popover.js: -------------------------------------------------------------------------------- 1 | /* =========================================================== 2 | * bootstrap-popover.js v2.2.2 3 | * http://twitter.github.com/bootstrap/javascript.html#popovers 4 | * =========================================================== 5 | * Copyright 2012 Twitter, Inc. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * =========================================================== */ 19 | 20 | 21 | !function ($) { 22 | 23 | "use strict"; // jshint ;_; 24 | 25 | 26 | /* POPOVER PUBLIC CLASS DEFINITION 27 | * =============================== */ 28 | 29 | var Popover = function (element, options) { 30 | this.init('popover', element, options) 31 | } 32 | 33 | 34 | /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js 35 | ========================================== */ 36 | 37 | Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, { 38 | 39 | constructor: Popover 40 | 41 | , setContent: function () { 42 | var $tip = this.tip() 43 | , title = this.getTitle() 44 | , content = this.getContent() 45 | 46 | $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) 47 | $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content) 48 | 49 | $tip.removeClass('fade top bottom left right in') 50 | } 51 | 52 | , hasContent: function () { 53 | return this.getTitle() || this.getContent() 54 | } 55 | 56 | , getContent: function () { 57 | var content 58 | , $e = this.$element 59 | , o = this.options 60 | 61 | content = $e.attr('data-content') 62 | || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content) 63 | 64 | return content 65 | } 66 | 67 | , tip: function () { 68 | if (!this.$tip) { 69 | this.$tip = $(this.options.template) 70 | } 71 | return this.$tip 72 | } 73 | 74 | , destroy: function () { 75 | this.hide().$element.off('.' + this.type).removeData(this.type) 76 | } 77 | 78 | }) 79 | 80 | 81 | /* POPOVER PLUGIN DEFINITION 82 | * ======================= */ 83 | 84 | var old = $.fn.popover 85 | 86 | $.fn.popover = function (option) { 87 | return this.each(function () { 88 | var $this = $(this) 89 | , data = $this.data('popover') 90 | , options = typeof option == 'object' && option 91 | if (!data) $this.data('popover', (data = new Popover(this, options))) 92 | if (typeof option == 'string') data[option]() 93 | }) 94 | } 95 | 96 | $.fn.popover.Constructor = Popover 97 | 98 | $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, { 99 | placement: 'right' 100 | , trigger: 'click' 101 | , content: '' 102 | , template: '

          ' 103 | }) 104 | 105 | 106 | /* POPOVER NO CONFLICT 107 | * =================== */ 108 | 109 | $.fn.popover.noConflict = function () { 110 | $.fn.popover = old 111 | return this 112 | } 113 | 114 | }(window.jQuery); -------------------------------------------------------------------------------- /test/bootstrap/bootstrap-transition.js: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * bootstrap-transition.js v2.2.2 3 | * http://twitter.github.com/bootstrap/javascript.html#transitions 4 | * =================================================== 5 | * Copyright 2012 Twitter, Inc. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * ========================================================== */ 19 | 20 | 21 | !function ($) { 22 | 23 | "use strict"; // jshint ;_; 24 | 25 | 26 | /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) 27 | * ======================================================= */ 28 | 29 | $(function () { 30 | 31 | $.support.transition = (function () { 32 | 33 | var transitionEnd = (function () { 34 | 35 | var el = document.createElement('bootstrap') 36 | , transEndEventNames = { 37 | 'WebkitTransition' : 'webkitTransitionEnd' 38 | , 'MozTransition' : 'transitionend' 39 | , 'OTransition' : 'oTransitionEnd otransitionend' 40 | , 'transition' : 'transitionend' 41 | } 42 | , name 43 | 44 | for (name in transEndEventNames){ 45 | if (el.style[name] !== undefined) { 46 | return transEndEventNames[name] 47 | } 48 | } 49 | 50 | }()) 51 | 52 | return transitionEnd && { 53 | end: transitionEnd 54 | } 55 | 56 | })() 57 | 58 | }) 59 | 60 | }(window.jQuery); -------------------------------------------------------------------------------- /test/bootstrap/tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Bootstrap Plugin Test Suite 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
          53 |

          Bootstrap Plugin Test Suite

          54 |

          55 |

          56 |
            57 |
            58 |
            59 | 60 | -------------------------------------------------------------------------------- /test/bootstrap/tests/index_with_worker.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Bootstrap Plugin Test Suite 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |
            52 |

            Bootstrap Plugin Test Suite

            53 |

            54 |

            55 |
              56 |
              57 |
              58 | 59 | -------------------------------------------------------------------------------- /test/bootstrap/tests/phantom.js: -------------------------------------------------------------------------------- 1 | // Simple phantom.js integration script 2 | // Adapted from Modernizr 3 | 4 | function waitFor(testFx, onReady, timeOutMillis) { 5 | var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 5001 //< Default Max Timout is 5s 6 | , start = new Date().getTime() 7 | , condition = false 8 | , interval = setInterval(function () { 9 | if ((new Date().getTime() - start < maxtimeOutMillis) && !condition) { 10 | // If not time-out yet and condition not yet fulfilled 11 | condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()) //< defensive code 12 | } else { 13 | if (!condition) { 14 | // If condition still not fulfilled (timeout but condition is 'false') 15 | console.log("'waitFor()' timeout") 16 | phantom.exit(1) 17 | } else { 18 | // Condition fulfilled (timeout and/or condition is 'true') 19 | typeof(onReady) === "string" ? eval(onReady) : onReady() //< Do what it's supposed to do once the condition is fulfilled 20 | clearInterval(interval) //< Stop this interval 21 | } 22 | } 23 | }, 100) //< repeat check every 100ms 24 | } 25 | 26 | 27 | if (phantom.args.length === 0 || phantom.args.length > 2) { 28 | console.log('Usage: phantom.js URL') 29 | phantom.exit() 30 | } 31 | 32 | var page = new WebPage() 33 | 34 | // Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this") 35 | page.onConsoleMessage = function(msg) { 36 | console.log(msg) 37 | }; 38 | 39 | page.open(phantom.args[0], function(status){ 40 | if (status !== "success") { 41 | console.log("Unable to access network") 42 | phantom.exit() 43 | } else { 44 | waitFor(function(){ 45 | return page.evaluate(function(){ 46 | var el = document.getElementById('qunit-testresult') 47 | if (el && el.innerText.match('completed')) { 48 | return true 49 | } 50 | return false 51 | }) 52 | }, function(){ 53 | var failedNum = page.evaluate(function(){ 54 | var el = document.getElementById('qunit-testresult') 55 | try { 56 | return el.getElementsByClassName('failed')[0].innerHTML 57 | } catch (e) { } 58 | return 10000 59 | }); 60 | phantom.exit((parseInt(failedNum, 10) > 0) ? 1 : 0) 61 | }) 62 | } 63 | }) -------------------------------------------------------------------------------- /test/bootstrap/tests/server.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple connect server for phantom.js 3 | * Adapted from Modernizr 4 | */ 5 | 6 | var connect = require('connect') 7 | , http = require('http') 8 | , fs = require('fs') 9 | , app = connect() 10 | .use(connect.static(__dirname + '/../../')); 11 | 12 | http.createServer(app).listen(3000); 13 | 14 | fs.writeFileSync(__dirname + '/pid.txt', process.pid, 'utf-8') -------------------------------------------------------------------------------- /test/bootstrap/tests/unit/bootstrap-affix.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module("bootstrap-affix") 4 | 5 | test("should provide no conflict", function () { 6 | var affix = $.fn.affix.noConflict() 7 | ok(!$.fn.affix, 'affix was set back to undefined (org value)') 8 | $.fn.affix = affix 9 | }) 10 | 11 | test("should be defined on jquery object", function () { 12 | ok($(document.body).affix, 'affix method is defined') 13 | }) 14 | 15 | test("should return element", function () { 16 | ok($(document.body).affix()[0] == document.body, 'document.body returned') 17 | }) 18 | 19 | test("should exit early if element is not visible", function () { 20 | var $affix = $('
              ').affix() 21 | $affix.data('affix').checkPosition() 22 | ok(!$affix.hasClass('affix'), 'affix class was not added') 23 | }) 24 | 25 | }) -------------------------------------------------------------------------------- /test/bootstrap/tests/unit/bootstrap-alert.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module("bootstrap-alerts") 4 | 5 | test("should provide no conflict", function () { 6 | var alert = $.fn.alert.noConflict() 7 | ok(!$.fn.alert, 'alert was set back to undefined (org value)') 8 | $.fn.alert = alert 9 | }) 10 | 11 | test("should be defined on jquery object", function () { 12 | ok($(document.body).alert, 'alert method is defined') 13 | }) 14 | 15 | test("should return element", function () { 16 | ok($(document.body).alert()[0] == document.body, 'document.body returned') 17 | }) 18 | 19 | test("should fade element out on clicking .close", function () { 20 | var alertHTML = '
              ' 21 | + '×' 22 | + '

              Holy guacamole! Best check yo self, you\'re not looking too good.

              ' 23 | + '
              ' 24 | , alert = $(alertHTML).alert() 25 | 26 | alert.find('.close').click() 27 | 28 | ok(!alert.hasClass('in'), 'remove .in class on .close click') 29 | }) 30 | 31 | test("should remove element when clicking .close", function () { 32 | $.support.transition = false 33 | 34 | var alertHTML = '
              ' 35 | + '×' 36 | + '

              Holy guacamole! Best check yo self, you\'re not looking too good.

              ' 37 | + '
              ' 38 | , alert = $(alertHTML).appendTo('#qunit-fixture').alert() 39 | 40 | ok($('#qunit-fixture').find('.alert-message').length, 'element added to dom') 41 | 42 | alert.find('.close').click() 43 | 44 | ok(!$('#qunit-fixture').find('.alert-message').length, 'element removed from dom') 45 | }) 46 | 47 | test("should not fire closed when close is prevented", function () { 48 | $.support.transition = false 49 | stop(); 50 | $('
              ') 51 | .bind('close', function (e) { 52 | e.preventDefault(); 53 | ok(true); 54 | start(); 55 | }) 56 | .bind('closed', function () { 57 | ok(false); 58 | }) 59 | .alert('close') 60 | }) 61 | 62 | }) -------------------------------------------------------------------------------- /test/bootstrap/tests/unit/bootstrap-collapse.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module("bootstrap-collapse") 4 | 5 | test("should provide no conflict", function () { 6 | var collapse = $.fn.collapse.noConflict() 7 | ok(!$.fn.collapse, 'collapse was set back to undefined (org value)') 8 | $.fn.collapse = collapse 9 | }) 10 | 11 | test("should be defined on jquery object", function () { 12 | ok($(document.body).collapse, 'collapse method is defined') 13 | }) 14 | 15 | test("should return element", function () { 16 | ok($(document.body).collapse()[0] == document.body, 'document.body returned') 17 | }) 18 | 19 | test("should show a collapsed element", function () { 20 | var el = $('
              ').collapse('show') 21 | ok(el.hasClass('in'), 'has class in') 22 | ok(/height/.test(el.attr('style')), 'has height set') 23 | }) 24 | 25 | test("should hide a collapsed element", function () { 26 | var el = $('
              ').collapse('hide') 27 | ok(!el.hasClass('in'), 'does not have class in') 28 | ok(/height/.test(el.attr('style')), 'has height set') 29 | }) 30 | 31 | test("should not fire shown when show is prevented", function () { 32 | $.support.transition = false 33 | stop() 34 | $('
              ') 35 | .bind('show', function (e) { 36 | e.preventDefault(); 37 | ok(true); 38 | start(); 39 | }) 40 | .bind('shown', function () { 41 | ok(false); 42 | }) 43 | .collapse('show') 44 | }) 45 | 46 | test("should reset style to auto after finishing opening collapse", function () { 47 | $.support.transition = false 48 | stop() 49 | $('
              ') 50 | .bind('show', function () { 51 | ok(this.style.height == '0px') 52 | }) 53 | .bind('shown', function () { 54 | ok(this.style.height == 'auto') 55 | start() 56 | }) 57 | .collapse('show') 58 | }) 59 | 60 | test("should add active class to target when collapse shown", function () { 61 | $.support.transition = false 62 | stop() 63 | 64 | var target = $('') 65 | .appendTo($('#qunit-fixture')) 66 | 67 | var collapsible = $('
              ') 68 | .appendTo($('#qunit-fixture')) 69 | .on('show', function () { 70 | ok(!target.hasClass('collapsed')) 71 | start() 72 | }) 73 | 74 | target.click() 75 | }) 76 | 77 | test("should remove active class to target when collapse hidden", function () { 78 | $.support.transition = false 79 | stop() 80 | 81 | var target = $('') 82 | .appendTo($('#qunit-fixture')) 83 | 84 | var collapsible = $('
              ') 85 | .appendTo($('#qunit-fixture')) 86 | .on('hide', function () { 87 | ok(target.hasClass('collapsed')) 88 | start() 89 | }) 90 | 91 | target.click() 92 | }) 93 | 94 | }) -------------------------------------------------------------------------------- /test/bootstrap/tests/unit/bootstrap-phantom.js: -------------------------------------------------------------------------------- 1 | // Logging setup for phantom integration 2 | // adapted from Modernizr 3 | 4 | QUnit.begin = function () { 5 | console.log("Starting test suite") 6 | console.log("================================================\n") 7 | } 8 | 9 | QUnit.moduleDone = function (opts) { 10 | if (opts.failed === 0) { 11 | console.log("\u2714 All tests passed in '" + opts.name + "' module") 12 | } else { 13 | console.log("\u2716 " + opts.failed + " tests failed in '" + opts.name + "' module") 14 | } 15 | } 16 | 17 | QUnit.done = function (opts) { 18 | console.log("\n================================================") 19 | console.log("Tests completed in " + opts.runtime + " milliseconds") 20 | console.log(opts.passed + " tests of " + opts.total + " passed, " + opts.failed + " failed.") 21 | } -------------------------------------------------------------------------------- /test/bootstrap/tests/unit/bootstrap-scrollspy.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module("bootstrap-scrollspy") 4 | 5 | test("should provide no conflict", function () { 6 | var scrollspy = $.fn.scrollspy.noConflict() 7 | ok(!$.fn.scrollspy, 'scrollspy was set back to undefined (org value)') 8 | $.fn.scrollspy = scrollspy 9 | }) 10 | 11 | test("should be defined on jquery object", function () { 12 | ok($(document.body).scrollspy, 'scrollspy method is defined') 13 | }) 14 | 15 | test("should return element", function () { 16 | ok($(document.body).scrollspy()[0] == document.body, 'document.body returned') 17 | }) 18 | 19 | test("should switch active class on scroll", function () { 20 | var sectionHTML = '
              ' 21 | , $section = $(sectionHTML).append('#qunit-fixture') 22 | , topbarHTML ='
              ' 23 | + '
              ' 24 | + '
              ' 25 | + '

              Bootstrap

              ' 26 | + '' 29 | + '
              ' 30 | + '
              ' 31 | + '
              ' 32 | , $topbar = $(topbarHTML).scrollspy() 33 | 34 | ok($topbar.find('.active', true)) 35 | }) 36 | 37 | }) -------------------------------------------------------------------------------- /test/bootstrap/tests/unit/bootstrap-tab.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module("bootstrap-tabs") 4 | 5 | test("should provide no conflict", function () { 6 | var tab = $.fn.tab.noConflict() 7 | ok(!$.fn.tab, 'tab was set back to undefined (org value)') 8 | $.fn.tab = tab 9 | }) 10 | 11 | test("should be defined on jquery object", function () { 12 | ok($(document.body).tab, 'tabs method is defined') 13 | }) 14 | 15 | test("should return element", function () { 16 | ok($(document.body).tab()[0] == document.body, 'document.body returned') 17 | }) 18 | 19 | test("should activate element by tab id", function () { 20 | var tabsHTML = 21 | '' 25 | 26 | $('
              ').appendTo("#qunit-fixture") 27 | 28 | $(tabsHTML).find('li:last a').tab('show') 29 | equals($("#qunit-fixture").find('.active').attr('id'), "profile") 30 | 31 | $(tabsHTML).find('li:first a').tab('show') 32 | equals($("#qunit-fixture").find('.active').attr('id'), "home") 33 | }) 34 | 35 | test("should activate element by tab id", function () { 36 | var pillsHTML = 37 | '' 41 | 42 | $('
              ').appendTo("#qunit-fixture") 43 | 44 | $(pillsHTML).find('li:last a').tab('show') 45 | equals($("#qunit-fixture").find('.active').attr('id'), "profile") 46 | 47 | $(pillsHTML).find('li:first a').tab('show') 48 | equals($("#qunit-fixture").find('.active').attr('id'), "home") 49 | }) 50 | 51 | 52 | test("should not fire closed when close is prevented", function () { 53 | $.support.transition = false 54 | stop(); 55 | $('
              ') 56 | .bind('show', function (e) { 57 | e.preventDefault(); 58 | ok(true); 59 | start(); 60 | }) 61 | .bind('shown', function () { 62 | ok(false); 63 | }) 64 | .tab('show') 65 | }) 66 | 67 | test("show and shown events should reference correct relatedTarget", function () { 68 | var dropHTML = 69 | '
                ' 70 | + '' 76 | + '
              ' 77 | 78 | $(dropHTML).find('ul>li:first a').tab('show').end() 79 | .find('ul>li:last a').on('show', function(event){ 80 | equals(event.relatedTarget.hash, "#1-1") 81 | }).on('shown', function(event){ 82 | equals(event.relatedTarget.hash, "#1-1") 83 | }).tab('show') 84 | }) 85 | 86 | }) -------------------------------------------------------------------------------- /test/bootstrap/tests/unit/bootstrap-transition.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module("bootstrap-transition") 4 | 5 | test("should be defined on jquery support object", function () { 6 | ok($.support.transition !== undefined, 'transition object is defined') 7 | }) 8 | 9 | test("should provide an end object", function () { 10 | ok($.support.transition ? $.support.transition.end : true, 'end string is defined') 11 | }) 12 | 13 | }) -------------------------------------------------------------------------------- /test/branchTracking/branch_runner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QUnit Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
              18 | 19 | 20 | -------------------------------------------------------------------------------- /test/branchTracking/branch_sample.js: -------------------------------------------------------------------------------- 1 | 2 | var sampleTest = function(x){ 3 | return x === 10 ? "ten" : "not ten"; 4 | }; 5 | 6 | var sampleTest2 = function(x){ 7 | return x === 5 ? "five" : "not five"; 8 | }; 9 | 10 | var sampleTest3 = function(x){ 11 | return x > 5 ? x < 10 ? "5-10" : "greater than ten" : "less than five"; 12 | }; 13 | 14 | var sampleTest4 = function(x){ 15 | return x === 5 ? "five" : "not five"; 16 | }; 17 | 18 | var sampleTest5 = function(x){ 19 | return x === 5 ? "five" : "not five"; 20 | }; 21 | 22 | var sampleTest6 = function(x){ 23 | return x === 5 ? 24 | "five" : 25 | "not five"; 26 | }; 27 | 28 | var sampleTest7 = function(x){ 29 | return x > 5 ? 30 | x > 10 ? x > 15 ? 31 | "greater than 15": x > 12 ? 32 | x > 13 ? "greater than 13" : "13" : "less than 12" :x > 7 ? "greater than 7" : 33 | "less than 7":"less than five"; 34 | }; 35 | 36 | var sampleTest8 = function(x){ 37 | return (x > 5 ? 38 | (x > 10 ? (x > 15 ? 39 | "greater than 15": (x > 12 ? 40 | (x > 13 ? "greater than 13" : "13") : "less than 12")) :x > 7 ? "greater than 7" : 41 | "less than 7"):"less than five"); 42 | }; 43 | 44 | var sampleTest9 = function(x){ 45 | return x === "?" ? "question mark" : "not a question mark"; 46 | }; 47 | -------------------------------------------------------------------------------- /test/branchTracking/branch_test.js: -------------------------------------------------------------------------------- 1 | 2 | test( "branch test", function() { 3 | ok( sampleTest(10) == "ten", "ten!" ); 4 | ok( sampleTest(5) == "not ten", "not ten!" ); 5 | }); 6 | 7 | test( "branch test2", function() { 8 | ok( sampleTest2(5) == "five", "five!" ); 9 | ok( sampleTest2(5) == "five", "five!" ); 10 | }); 11 | 12 | test( "branch test3", function() { 13 | ok( sampleTest3(12) == "greater than ten", "greater!" ); 14 | //ok( sampleTest3(7) == "5-10", "5-10!" ); 15 | }); 16 | 17 | test( "branch test2", function() { 18 | ok( sampleTest4(6) == "not five", "not five!" ); 19 | ok( sampleTest4(6) == "not five", "not five!" ); 20 | }); 21 | 22 | test( "multi line branch", function() { 23 | ok( sampleTest6(6) == "not five", "not five!" ); 24 | ok( sampleTest7(1) == "less than five", "less than 5!" ); 25 | ok( sampleTest7(13) == "13", "13!" ); 26 | }); 27 | 28 | test( "multi line branch2", function() { 29 | ok( sampleTest8(1) == "less than five", "less than 5!" ); 30 | ok( sampleTest8(13) == "13", "13!" ); 31 | }); 32 | 33 | test( "branch with string containing question mark", function() { 34 | ok( sampleTest9("") == "not a question mark", "not a question mark!" ); 35 | ok( sampleTest9("h") == "not a question mark", "not a question mark!" ); 36 | ok( sampleTest9("?") == "question mark", "question mark!" ); 37 | }); 38 | -------------------------------------------------------------------------------- /test/coffee_script/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QUnit Example 6 | 7 | 8 | 9 | 10 | 11 | 27 | 28 | 29 |
              30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /test/coffee_script/sample.coffee: -------------------------------------------------------------------------------- 1 | #this test should fail 2 | window.sampleTest = -> 3 | 10 -------------------------------------------------------------------------------- /test/coffee_script/test.js: -------------------------------------------------------------------------------- 1 | define(["cs!sample"],function(){ 2 | 3 | test( "require test", function() { 4 | ok( sampleTest() == 10, "Passed!" ); 5 | }); 6 | 7 | }); -------------------------------------------------------------------------------- /test/commonjs/runner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Blanket tests 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
              18 | 19 | 20 | -------------------------------------------------------------------------------- /test/commonjs/source_testing_url_module.js: -------------------------------------------------------------------------------- 1 | var url = require("url"); 2 | 3 | window.urlResult = url.parse("http://www.blanketjs.org").host; -------------------------------------------------------------------------------- /test/commonjs/source_to_cover.js: -------------------------------------------------------------------------------- 1 | var lib = require("./testlib"); 2 | 3 | window.testLibResult = lib; -------------------------------------------------------------------------------- /test/commonjs/testlib.js: -------------------------------------------------------------------------------- 1 | module.exports=true; -------------------------------------------------------------------------------- /test/commonjs/testlib_test.js: -------------------------------------------------------------------------------- 1 | test('object should exist', function(){ 2 | ok(window.testLibResult); 3 | ok(window.urlResult); 4 | }); -------------------------------------------------------------------------------- /test/custom-reporter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QUnit Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
              16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/custom-reporter/lcov.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QUnit Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
              16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/custom-reporter/lcov_test.js: -------------------------------------------------------------------------------- 1 | test( "sample test", function() { 2 | ok( sampleTest() == 10, "Passed!" ); 3 | }); -------------------------------------------------------------------------------- /test/custom-reporter/sample.js: -------------------------------------------------------------------------------- 1 | //this test should fail 2 | var sampleTest = function(){ 3 | return 10; 4 | }; -------------------------------------------------------------------------------- /test/custom-reporter/test.js: -------------------------------------------------------------------------------- 1 | test( "sample test", function() { 2 | ok( sampleTest() == 10, "Passed!" ); 3 | }); -------------------------------------------------------------------------------- /test/helpers/phantom_jasmine_runner.js: -------------------------------------------------------------------------------- 1 | var PhantomJasmineRunner, addReporter, address, page, runner; 2 | 3 | PhantomJasmineRunner = (function() { 4 | 5 | function PhantomJasmineRunner(page, exit_func) { 6 | this.page = page; 7 | this.exit_func = exit_func != null ? exit_func : phantom.exit; 8 | this.tries = 0; 9 | this.max_tries = 10; 10 | } 11 | 12 | PhantomJasmineRunner.prototype.get_status = function() { 13 | return this.page.evaluate(function() { 14 | return window.jasmine_phantom_reporter.status; 15 | }); 16 | }; 17 | 18 | PhantomJasmineRunner.prototype.terminate = function() { 19 | switch (this.get_status()) { 20 | case "success": 21 | return this.exit_func(0); 22 | case "fail": 23 | return this.exit_func(1); 24 | default: 25 | return this.exit_func(2); 26 | } 27 | }; 28 | 29 | return PhantomJasmineRunner; 30 | 31 | })(); 32 | 33 | if (phantom.args.length === 0) { 34 | console.log("Need a url as the argument"); 35 | phantom.exit(1); 36 | } 37 | 38 | page = new WebPage(); 39 | 40 | runner = new PhantomJasmineRunner(page); 41 | 42 | page.onConsoleMessage = function(msg) { 43 | console.log(msg); 44 | if (msg === "ConsoleReporter finished") { 45 | return runner.terminate(); 46 | } 47 | }; 48 | 49 | address = phantom.args[0]; 50 | 51 | 52 | 53 | page.open(address, function(status) { 54 | if (status !== "success") { 55 | console.log("can't load the address!"); 56 | phantom.exit(1); 57 | } 58 | 59 | 60 | }); 61 | 62 | -------------------------------------------------------------------------------- /test/helpers/phantom_mocha_runner.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Qt+WebKit powered headless test runner using Phantomjs 3 | * 4 | * Phantomjs installation: http://code.google.com/p/phantomjs/wiki/BuildInstructions 5 | * 6 | * Run with: 7 | * phantomjs runner.js [url-of-your-qunit-testsuite] 8 | * 9 | * E.g. 10 | * phantomjs runner.js http://localhost/qunit/test 11 | */ 12 | 13 | /*jshint latedef:false */ 14 | /*global phantom:true require:true console:true */ 15 | var url = phantom.args[0], 16 | page = require('webpage').create(); 17 | 18 | // Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this") 19 | page.onConsoleMessage = function(msg) { 20 | console.log(msg); 21 | }; 22 | 23 | page.open(url, function(status){ 24 | if (status !== "success") { 25 | console.log("Unable to access network: " + status); 26 | phantom.exit(1); 27 | } else { 28 | var interval = setInterval(function() { 29 | if (finished()) { 30 | clearInterval(interval); 31 | onfinishedTests(); 32 | } 33 | }, 500); 34 | } 35 | }); 36 | 37 | function finished() { 38 | return page.evaluate(function(){ 39 | var m = document.getElementById("mocha"), 40 | ms = document.getElementById("mocha-stats"); 41 | 42 | return m && ms; 43 | }); 44 | } 45 | 46 | function onfinishedTests() { 47 | var output = page.evaluate(function() { 48 | //print a success message 49 | var stats = document.getElementById("mocha-stats"); 50 | var passes = stats.querySelector(".passes") 51 | .lastElementChild.innerText; 52 | var failures = stats.querySelector(".failures") 53 | .lastElementChild.innerText; 54 | console.log("Completed with "+passes +" passes and "+failures+" failures."); 55 | return failures; 56 | 57 | }); 58 | phantom.exit(output > 0 ? 1 : 0); 59 | } 60 | -------------------------------------------------------------------------------- /test/helpers/phantom_qunit_old_runner.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Qt+WebKit powered headless test runner using Phantomjs 3 | * 4 | * Phantomjs installation: http://code.google.com/p/phantomjs/wiki/BuildInstructions 5 | * 6 | * Run with: 7 | * phantomjs runner.js [url-of-your-qunit-testsuite] 8 | * 9 | * E.g. 10 | * phantomjs runner.js http://localhost/qunit/test 11 | */ 12 | 13 | /*jshint latedef:false */ 14 | /*global phantom:true require:true console:true */ 15 | var url = phantom.args[0], 16 | page = require('webpage').create(); 17 | 18 | // Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this") 19 | page.onConsoleMessage = function(msg) { 20 | console.log(msg); 21 | }; 22 | 23 | page.onInitialized = function() { 24 | page.evaluate(addLogging); 25 | }; 26 | page.open(url, function(status){ 27 | if (status !== "success") { 28 | console.log("Unable to access network: " + status); 29 | phantom.exit(1); 30 | } else { 31 | var time=0; 32 | var interval = setInterval(function() { 33 | if (finished()) { 34 | clearInterval(interval); 35 | onfinishedTests(); 36 | }else if (time > 50){ 37 | console.log("Too long!"); 38 | phantom.exit(1); 39 | }else{ 40 | time++; 41 | } 42 | }, 500); 43 | } 44 | }); 45 | 46 | function finished() { 47 | return page.evaluate(function(){ 48 | 49 | return !!window.qunitDone; 50 | }); 51 | } 52 | 53 | function onfinishedTests() { 54 | var output = page.evaluate(function() { 55 | return JSON.stringify(window.qunitDone); 56 | }); 57 | phantom.exit(JSON.parse(output).failed > 0 ? 1 : 0); 58 | } 59 | 60 | function addLogging() { 61 | window.addEventListener( "DOMContentLoaded", function() { 62 | var current_test_assertions = []; 63 | var existingDone = QUnit.done; 64 | 65 | QUnit.done=function(result){ 66 | existingDone(result); 67 | console.log('Took ' + result.runtime + 'ms to run ' + result.total + ' tests. ' + result.passed + ' passed, ' + result.failed + ' failed.'); 68 | window.qunitDone = result; 69 | }; 70 | }, false ); 71 | } 72 | -------------------------------------------------------------------------------- /test/helpers/phantom_qunit_runner.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Qt+WebKit powered headless test runner using Phantomjs 3 | * 4 | * Phantomjs installation: http://code.google.com/p/phantomjs/wiki/BuildInstructions 5 | * 6 | * Run with: 7 | * phantomjs runner.js [url-of-your-qunit-testsuite] 8 | * 9 | * E.g. 10 | * phantomjs runner.js http://localhost/qunit/test 11 | */ 12 | 13 | /*jshint latedef:false */ 14 | /*global phantom:true require:true console:true */ 15 | var url = phantom.args[0], 16 | page = require('webpage').create(); 17 | 18 | // Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this") 19 | page.onConsoleMessage = function(msg) { 20 | console.log(msg); 21 | }; 22 | 23 | page.onInitialized = function() { 24 | page.evaluate(addLogging); 25 | }; 26 | 27 | page.open(url, function(status){ 28 | if (status !== "success") { 29 | console.log("Unable to access network: " + status); 30 | phantom.exit(1); 31 | } else { 32 | var time=0; 33 | var interval = setInterval(function() { 34 | if (finished()) { 35 | clearInterval(interval); 36 | onfinishedTests(); 37 | }else if (time > 50){ 38 | console.log("Too long!"); 39 | phantom.exit(1); 40 | }else{ 41 | time++; 42 | } 43 | }, 500); 44 | } 45 | }); 46 | 47 | function finished() { 48 | return page.evaluate(function(){ 49 | 50 | return !!window.qunitDone; 51 | }); 52 | } 53 | 54 | function onfinishedTests() { 55 | var output = page.evaluate(function() { 56 | return JSON.stringify(window.qunitDone); 57 | }); 58 | var num = page.evaluate(function(){ 59 | var blanket_size = function (obj) { 60 | if (typeof obj === 'undefined'){ 61 | return null; 62 | } 63 | var _size = 0, key; 64 | for (key in obj) { 65 | if (obj.hasOwnProperty(key)) _size++; 66 | } 67 | return _size; 68 | }; 69 | return typeof window.blanketTestQUnitExpected !== 'undefined' && blanket_size(window._$blanket) !== window.blanketTestQUnitExpected; 70 | }); 71 | phantom.exit(num ? 1: JSON.parse(output).failed > 0 ? 1 : 0); 72 | } 73 | 74 | function addLogging() { 75 | window.addEventListener( "DOMContentLoaded", function() { 76 | var current_test_assertions = []; 77 | QUnit.testDone(function(result) { 78 | 79 | var i, 80 | name = result.module + ': ' + result.name; 81 | 82 | if (result.failed) { 83 | console.log('Assertion Failed: ' + name); 84 | 85 | for (i = 0; i < current_test_assertions.length; i++) { 86 | console.log(' ' + current_test_assertions[i]); 87 | } 88 | } 89 | 90 | current_test_assertions = []; 91 | 92 | }); 93 | 94 | QUnit.log(function(details) { 95 | var response; 96 | 97 | if (details.result) { 98 | return; 99 | } 100 | 101 | response = details.message || ''; 102 | 103 | if (typeof details.expected !== 'undefined') { 104 | if (response) { 105 | response += ', '; 106 | } 107 | 108 | response += 'expected: ' + details.expected + ', but was: ' + details.actual; 109 | } 110 | 111 | current_test_assertions.push('Failed assertion: ' + response); 112 | }); 113 | 114 | QUnit.done(function(result){ 115 | console.log('Took ' + result.runtime + 'ms to run ' + result.total + ' tests. ' + result.passed + ' passed, ' + result.failed + ' failed.'); 116 | window.qunitDone = result; 117 | }); 118 | }, false ); 119 | } 120 | -------------------------------------------------------------------------------- /test/ignore_script_error/runner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Blanket tests 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
              18 | 19 | 20 | -------------------------------------------------------------------------------- /test/ignore_script_error/script_error.js: -------------------------------------------------------------------------------- 1 | var errorThing = { 2 | thing: ["thing" + someUndefinedVariable] 3 | }; -------------------------------------------------------------------------------- /test/ignore_script_error/script_error_test.js: -------------------------------------------------------------------------------- 1 | test('object should not exist', function(){ 2 | ok(typeof errorThing === 'undefined'); 3 | }); -------------------------------------------------------------------------------- /test/jasmine-custom-build/SpecRunner.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | Jasmine Spec Runner 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /test/jasmine-custom-build/SpecRunner_data_adapter.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | Jasmine Spec Runner 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /test/jasmine-custom-build/require.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | Jasmine Spec Runner 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /test/jasmine-custom-build/source/Player.js: -------------------------------------------------------------------------------- 1 | function Player() { 2 | } 3 | Player.prototype.play = function(song) { 4 | this.currentlyPlayingSong = song; 5 | this.isPlaying = true; 6 | }; 7 | 8 | Player.prototype.pause = function() { 9 | this.isPlaying = false; 10 | }; 11 | 12 | Player.prototype.resume = function() { 13 | if (this.isPlaying) { 14 | throw new Error("song is already playing"); 15 | } 16 | 17 | this.isPlaying = true; 18 | }; 19 | 20 | Player.prototype.makeFavorite = function() { 21 | this.currentlyPlayingSong.persistFavoriteStatus(true); 22 | }; -------------------------------------------------------------------------------- /test/jasmine-custom-build/source/Song.js: -------------------------------------------------------------------------------- 1 | function Song() { 2 | } 3 | 4 | Song.prototype.persistFavoriteStatus = function(value) { 5 | // something complicated 6 | throw new Error("not yet implemented"); 7 | }; -------------------------------------------------------------------------------- /test/jasmine-custom-build/spec/PlayerSpec.js: -------------------------------------------------------------------------------- 1 | describe("Player", function() { 2 | var player; 3 | var song; 4 | 5 | beforeEach(function() { 6 | player = new Player(); 7 | song = new Song(); 8 | }); 9 | 10 | it("should be able to play a Song", function() { 11 | player.play(song); 12 | expect(player.currentlyPlayingSong).toEqual(song); 13 | 14 | //demonstrates use of custom matcher 15 | expect(player).toBePlaying(song); 16 | }); 17 | 18 | describe("when song has been paused", function() { 19 | beforeEach(function() { 20 | player.play(song); 21 | player.pause(); 22 | }); 23 | 24 | it("should indicate that the song is currently paused", function() { 25 | expect(player.isPlaying).toBeFalsy(); 26 | 27 | // demonstrates use of 'not' with a custom matcher 28 | expect(player).not.toBePlaying(song); 29 | }); 30 | 31 | it("should be possible to resume", function() { 32 | player.resume(); 33 | expect(player.isPlaying).toBeTruthy(); 34 | expect(player.currentlyPlayingSong).toEqual(song); 35 | }); 36 | }); 37 | 38 | // demonstrates use of spies to intercept and test method calls 39 | it("tells the current song if the user has made it a favorite", function() { 40 | spyOn(song, 'persistFavoriteStatus'); 41 | 42 | player.play(song); 43 | player.makeFavorite(); 44 | 45 | expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true); 46 | }); 47 | 48 | //demonstrates use of expected exceptions 49 | describe("#resume", function() { 50 | it("should throw an exception if song is already playing", function() { 51 | player.play(song); 52 | 53 | expect(function() { 54 | player.resume(); 55 | }).toThrow("song is already playing"); 56 | }); 57 | }); 58 | }); -------------------------------------------------------------------------------- /test/jasmine-custom-build/spec/SongSpec.js: -------------------------------------------------------------------------------- 1 | describe("Song", function() { 2 | var song; 3 | 4 | beforeEach(function() { 5 | song = new Song(); 6 | }); 7 | 8 | it("should be not implemented", function() { 9 | expect(function() { 10 | song.persistFavoriteStatus(); 11 | }).toThrow("not yet implemented"); 12 | }); 13 | }); -------------------------------------------------------------------------------- /test/jasmine-custom-build/spec/SpecHelper.js: -------------------------------------------------------------------------------- 1 | beforeEach(function() { 2 | this.addMatchers({ 3 | toBePlaying: function(expectedSong) { 4 | var player = this.actual; 5 | return player.currentlyPlayingSong === expectedSong && 6 | player.isPlaying; 7 | } 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/jasmine-custom-build/spec/require_PlayerSpec.js: -------------------------------------------------------------------------------- 1 | define(["source/Player","source/Song"],function(){ 2 | 3 | describe("Player", function() { 4 | var player; 5 | var song; 6 | 7 | beforeEach(function() { 8 | player = new Player(); 9 | song = new Song(); 10 | }); 11 | 12 | it("should be able to play a Song", function() { 13 | player.play(song); 14 | expect(player.currentlyPlayingSong).toEqual(song); 15 | 16 | //demonstrates use of custom matcher 17 | expect(player).toBePlaying(song); 18 | }); 19 | 20 | describe("when song has been paused", function() { 21 | beforeEach(function() { 22 | player.play(song); 23 | player.pause(); 24 | }); 25 | 26 | it("should indicate that the song is currently paused", function() { 27 | expect(player.isPlaying).toBeFalsy(); 28 | 29 | // demonstrates use of 'not' with a custom matcher 30 | expect(player).not.toBePlaying(song); 31 | }); 32 | 33 | it("should be possible to resume", function() { 34 | player.resume(); 35 | expect(player.isPlaying).toBeTruthy(); 36 | expect(player.currentlyPlayingSong).toEqual(song); 37 | }); 38 | }); 39 | 40 | // demonstrates use of spies to intercept and test method calls 41 | it("tells the current song if the user has made it a favorite", function() { 42 | spyOn(song, 'persistFavoriteStatus'); 43 | 44 | player.play(song); 45 | player.makeFavorite(); 46 | 47 | expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true); 48 | }); 49 | 50 | //demonstrates use of expected exceptions 51 | describe("#resume", function() { 52 | it("should throw an exception if song is already playing", function() { 53 | player.play(song); 54 | 55 | expect(function() { 56 | player.resume(); 57 | }).toThrow("song is already playing"); 58 | }); 59 | }); 60 | }); 61 | }); -------------------------------------------------------------------------------- /test/jasmine-custom-build/spec/require_SongSpec.js: -------------------------------------------------------------------------------- 1 | define(["source/Song"],function(){ 2 | describe("Song", function() { 3 | var song; 4 | 5 | beforeEach(function() { 6 | song = new Song(); 7 | }); 8 | 9 | it("should be not implemented", function() { 10 | expect(function() { 11 | song.persistFavoriteStatus(); 12 | }).toThrow("not yet implemented"); 13 | }); 14 | }); 15 | }); -------------------------------------------------------------------------------- /test/jasmine-requirejs/code/all.tests.jasmine.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | From the Chutzpah test suite: http://chutzpah.codeplex.com/ 4 | 5 | 6 | */ 7 | /// 8 | /// 9 | 10 | requirejs(['./tests/base/base.jasmine.test', 11 | './tests/ui/ui.jasmine.test'], 12 | function () { } 13 | ); 14 | -------------------------------------------------------------------------------- /test/jasmine-requirejs/code/base/core.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | From the Chutzpah test suite: http://chutzpah.codeplex.com/ 4 | 5 | 6 | */ 7 | define(function () { 8 | return { 9 | version: 8 10 | }; 11 | }); -------------------------------------------------------------------------------- /test/jasmine-requirejs/code/tests/base/base.jasmine.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | From the Chutzpah test suite: http://chutzpah.codeplex.com/ 4 | 5 | 6 | */ 7 | define(['base/core'], 8 | function (core) { 9 | describe("base/core", function () { 10 | it("will return correct version from core", function () { 11 | var version = core.version; 12 | expect(version).toEqual(8); 13 | }); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /test/jasmine-requirejs/code/tests/ui/ui.jasmine.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | From the Chutzpah test suite: http://chutzpah.codeplex.com/ 4 | 5 | 6 | */ 7 | define(['ui/screen'], 8 | function (screen) { 9 | describe("ui/screen", function () { 10 | it("will build display version", function () { 11 | var disp = screen.displayVersion; 12 | expect(disp).toEqual("Version: 8"); 13 | }); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /test/jasmine-requirejs/code/ui/screen.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | From the Chutzpah test suite: http://chutzpah.codeplex.com/ 4 | 5 | 6 | */ 7 | define(["base/core"], function(core) { 8 | return { 9 | displayVersion: "Version: " + core.version 10 | }; 11 | }); -------------------------------------------------------------------------------- /test/jasmine-requirejs/runner.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 13 | Jasmine Spec Runner 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 33 | 34 | 35 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /test/jasmine/SpecRunner.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | Jasmine Spec Runner 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /test/jasmine/SpecRunner_data_adapter.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | Jasmine Spec Runner 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /test/jasmine/SpecRunner_data_adapter_array.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | Jasmine Spec Runner 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /test/jasmine/SpecRunner_data_adapter_regex.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | Jasmine Spec Runner 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /test/jasmine/source/Player.js: -------------------------------------------------------------------------------- 1 | function Player() { 2 | } 3 | Player.prototype.play = function(song) { 4 | this.currentlyPlayingSong = song; 5 | this.isPlaying = true; 6 | }; 7 | 8 | Player.prototype.pause = function() { 9 | this.isPlaying = false; 10 | }; 11 | 12 | Player.prototype.resume = function() { 13 | if (this.isPlaying) { 14 | throw new Error("song is already playing"); 15 | } 16 | 17 | this.isPlaying = true; 18 | }; 19 | 20 | Player.prototype.makeFavorite = function() { 21 | this.currentlyPlayingSong.persistFavoriteStatus(true); 22 | }; -------------------------------------------------------------------------------- /test/jasmine/source/Song.js: -------------------------------------------------------------------------------- 1 | function Song() { 2 | } 3 | 4 | Song.prototype.persistFavoriteStatus = function(value) { 5 | // something complicated 6 | throw new Error("not yet implemented"); 7 | }; -------------------------------------------------------------------------------- /test/jasmine/spec/PlayerSpec.js: -------------------------------------------------------------------------------- 1 | describe("Player", function() { 2 | var player; 3 | var song; 4 | 5 | beforeEach(function() { 6 | player = new Player(); 7 | song = new Song(); 8 | }); 9 | 10 | it("should be able to play a Song", function() { 11 | player.play(song); 12 | expect(player.currentlyPlayingSong).toEqual(song); 13 | 14 | //demonstrates use of custom matcher 15 | expect(player).toBePlaying(song); 16 | }); 17 | 18 | describe("when song has been paused", function() { 19 | beforeEach(function() { 20 | player.play(song); 21 | player.pause(); 22 | }); 23 | 24 | it("should indicate that the song is currently paused", function() { 25 | expect(player.isPlaying).toBeFalsy(); 26 | 27 | // demonstrates use of 'not' with a custom matcher 28 | expect(player).not.toBePlaying(song); 29 | }); 30 | 31 | it("should be possible to resume", function() { 32 | player.resume(); 33 | expect(player.isPlaying).toBeTruthy(); 34 | expect(player.currentlyPlayingSong).toEqual(song); 35 | }); 36 | }); 37 | 38 | // demonstrates use of spies to intercept and test method calls 39 | it("tells the current song if the user has made it a favorite", function() { 40 | spyOn(song, 'persistFavoriteStatus'); 41 | 42 | player.play(song); 43 | player.makeFavorite(); 44 | 45 | expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true); 46 | }); 47 | 48 | //demonstrates use of expected exceptions 49 | describe("#resume", function() { 50 | it("should throw an exception if song is already playing", function() { 51 | player.play(song); 52 | 53 | expect(function() { 54 | player.resume(); 55 | }).toThrow("song is already playing"); 56 | }); 57 | }); 58 | }); -------------------------------------------------------------------------------- /test/jasmine/spec/SongSpec.js: -------------------------------------------------------------------------------- 1 | describe("Song", function() { 2 | var song; 3 | 4 | beforeEach(function() { 5 | song = new Song(); 6 | }); 7 | 8 | it("should be not implemented", function() { 9 | expect(function() { 10 | song.persistFavoriteStatus(); 11 | }).toThrow("not yet implemented"); 12 | }); 13 | }); -------------------------------------------------------------------------------- /test/jasmine/spec/SpecHelper.js: -------------------------------------------------------------------------------- 1 | beforeEach(function() { 2 | this.addMatchers({ 3 | toBePlaying: function(expectedSong) { 4 | var player = this.actual; 5 | return player.currentlyPlayingSong === expectedSong && 6 | player.isPlaying; 7 | } 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/jquery-usage/images/destroy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-seville/blanket/db93808886817ad70e5b8b712e08b930f41dd225/test/jquery-usage/images/destroy.png -------------------------------------------------------------------------------- /test/jquery-usage/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | jQuery Usage 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |

              jQuery Usage

              29 | 30 |

              How much of jQuery does Backbone Koans use?

              31 |

              32 |
              33 |

              34 |
                35 |
                36 |
                37 | 38 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /test/jquery-usage/js/ext/backbone.localStorage.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Backbone localStorage Adapter v1.0 3 | * https://github.com/jeromegn/Backbone.localStorage 4 | */ 5 | 6 | // A simple module to replace `Backbone.sync` with *localStorage*-based 7 | // persistence. Models are given GUIDS, and saved into a JSON object. Simple 8 | // as that. 9 | 10 | // Generate four random hex digits. 11 | function S4() { 12 | return (((1+Math.random())*0x10000)|0).toString(16).substring(1); 13 | }; 14 | 15 | // Generate a pseudo-GUID by concatenating random hexadecimal. 16 | function guid() { 17 | return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4()); 18 | }; 19 | 20 | // Our Store is represented by a single JS object in *localStorage*. Create it 21 | // with a meaningful name, like the name you'd give a table. 22 | window.Store = function(name) { 23 | this.name = name; 24 | var store = localStorage.getItem(this.name); 25 | this.records = (store && store.split(",")) || []; 26 | }; 27 | 28 | _.extend(Store.prototype, { 29 | 30 | // Save the current state of the **Store** to *localStorage*. 31 | save: function() { 32 | localStorage.setItem(this.name, this.records.join(",")); 33 | }, 34 | 35 | // Add a model, giving it a (hopefully)-unique GUID, if it doesn't already 36 | // have an id of it's own. 37 | create: function(model) { 38 | if (!model.id) model.id = model.attributes.id = guid(); 39 | localStorage.setItem(this.name+"-"+model.id, JSON.stringify(model)); 40 | this.records.push(model.id.toString()); 41 | this.save(); 42 | return model; 43 | }, 44 | 45 | // Update a model by replacing its copy in `this.data`. 46 | update: function(model) { 47 | localStorage.setItem(this.name+"-"+model.id, JSON.stringify(model)); 48 | if (!_.include(this.records, model.id.toString())) this.records.push(model.id.toString()); this.save(); 49 | return model; 50 | }, 51 | 52 | // Retrieve a model from `this.data` by id. 53 | find: function(model) { 54 | return JSON.parse(localStorage.getItem(this.name+"-"+model.id)); 55 | }, 56 | 57 | // Return the array of all models currently in storage. 58 | findAll: function() { 59 | return _.map(this.records, function(id){return JSON.parse(localStorage.getItem(this.name+"-"+id));}, this); 60 | }, 61 | 62 | // Delete a model from `this.data`, returning it. 63 | destroy: function(model) { 64 | localStorage.removeItem(this.name+"-"+model.id); 65 | this.records = _.reject(this.records, function(record_id){return record_id == model.id.toString();}); 66 | this.save(); 67 | return model; 68 | } 69 | 70 | }); 71 | 72 | // localSync delegate to the model or collection's 73 | // *localStorage* property, which should be an instance of `Store`. 74 | Backbone.localSync = function(method, model, options, error) { 75 | 76 | // Backwards compatibility with Backbone <= 0.3.3 77 | if (typeof options == 'function') { 78 | options = { 79 | success: options, 80 | error: error 81 | }; 82 | } 83 | 84 | var resp; 85 | var store = model.localStorage || model.collection.localStorage; 86 | 87 | switch (method) { 88 | case "read": resp = model.id != undefined ? store.find(model) : store.findAll(); break; 89 | case "create": resp = store.create(model); break; 90 | case "update": resp = store.update(model); break; 91 | case "delete": resp = store.destroy(model); break; 92 | } 93 | 94 | if (resp) { 95 | options.success(resp); 96 | } else { 97 | options.error("Record not found"); 98 | } 99 | }; 100 | 101 | // Override 'Backbone.sync' to default to localSync, 102 | // the original 'Backbone.sync' is still available in 'Backbone.ajaxSync' 103 | Backbone.ajaxSync = Backbone.sync; 104 | Backbone.sync = Backbone.localSync; 105 | -------------------------------------------------------------------------------- /test/jquery-usage/js/ext/sinon-qunit-1.0.0.js: -------------------------------------------------------------------------------- 1 | /** 2 | * sinon-qunit 1.0.0, 2010/12/09 3 | * 4 | * @author Christian Johansen (christian@cjohansen.no) 5 | * 6 | * (The BSD License) 7 | * 8 | * Copyright (c) 2010-2011, Christian Johansen, christian@cjohansen.no 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 14 | * * Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * * Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * * Neither the name of Christian Johansen nor the names of his contributors 20 | * may be used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | /*global sinon, QUnit, test*/ 35 | sinon.assert.fail = function (msg) { 36 | QUnit.ok(false, msg); 37 | }; 38 | 39 | sinon.assert.pass = function (assertion) { 40 | QUnit.ok(true, assertion); 41 | }; 42 | 43 | sinon.config = { 44 | injectIntoThis: true, 45 | injectInto: null, 46 | properties: ["spy", "stub", "mock", "clock", "sandbox"], 47 | useFakeTimers: true, 48 | useFakeServer: false 49 | }; 50 | 51 | (function (global) { 52 | var qTest = QUnit.test; 53 | 54 | QUnit.test = global.test = function (testName, expected, callback, async) { 55 | if (arguments.length === 2) { 56 | callback = expected; 57 | expected = null; 58 | } 59 | 60 | return qTest(testName, expected, sinon.test(callback), async); 61 | }; 62 | }(this)); 63 | -------------------------------------------------------------------------------- /test/jquery-usage/js/ext/template.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | var cache = {}; 4 | 5 | function _render(elt, template, data, callback) { 6 | var data = data || {}, 7 | callback = callback || function() {}, 8 | html = template(data); 9 | 10 | elt.append(html); 11 | callback(); 12 | } 13 | 14 | 15 | /** 16 | * Fetches the Underscore.js template at the given path, 17 | * processes it with the provided data object, and appends the 18 | * resulting html to the matched DOM elements. 19 | * 20 | * Templates will only be fetched once from the server, 21 | * preprocessed template are cached in the DOM. 22 | */ 23 | $.fn.template = function(path, obj, callback) { 24 | var self = this; 25 | 26 | if (cache[path]) { 27 | _render(self, cache[path], obj, callback); 28 | return self; 29 | } 30 | 31 | $.get(path, function(data) { 32 | cache[path] = _.template(data); 33 | _render(self, cache[path], obj, callback); 34 | }); 35 | 36 | return self; 37 | }; 38 | 39 | 40 | })(jQuery); -------------------------------------------------------------------------------- /test/jquery-usage/js/koans/aboutApps.js: -------------------------------------------------------------------------------- 1 | module('About Backbone Applications', { 2 | setup: function() { 3 | Backbone.localStorageDB = new Store('testTodos'); 4 | $('#qunit-fixture').append('
                '); 5 | this.App = new TodoApp({ appendTo: $('#app') }); 6 | }, 7 | 8 | teardown: function() { 9 | this.App.todos.reset(); 10 | $('#app').remove(); 11 | } 12 | }); 13 | 14 | test('Should bootstrap the application by initializing the Collection.', function() { 15 | expect(2); 16 | notEqual(this.App.todos, undefined); 17 | equal(this.App.todos.length, 0); 18 | }); 19 | -------------------------------------------------------------------------------- /test/jquery-usage/js/koans/aboutCollections.js: -------------------------------------------------------------------------------- 1 | module('About Backbone.Collection'); 2 | 3 | test('Can add Model instances as objects and arrays.', function() { 4 | 5 | expect(3); 6 | 7 | var todos = new TodoList(); 8 | equal(todos.length, 0); 9 | 10 | todos.add({ text: 'Clean the kitchen' }); 11 | equal(todos.length, 1); 12 | 13 | todos.add([ 14 | { text: 'Do the laundry', done: true }, 15 | { text: 'Go to the gym'} 16 | ]); 17 | 18 | equal(todos.length, 3); 19 | }); 20 | 21 | test('Can have a url property to define the basic url structure for all contained models.', function() { 22 | expect(1); 23 | var todos = new TodoList(); 24 | equal(todos.url, '/todos/'); 25 | }); 26 | 27 | test('Fires custom named events when the models change.', function() { 28 | 29 | expect(2); 30 | var todos = new TodoList(); 31 | 32 | var addModelCallback = this.spy(); 33 | var removeModelCallback = this.spy(); 34 | 35 | todos.bind('add', addModelCallback); 36 | todos.bind('remove', removeModelCallback); 37 | 38 | // How would you get the 'add' event to trigger? 39 | todos.add({text:"New todo"}); 40 | 41 | ok(addModelCallback.called); 42 | 43 | // How would you get the 'remove' callback to trigger? 44 | todos.remove(todos.last()); 45 | 46 | ok(removeModelCallback.called); 47 | 48 | }); -------------------------------------------------------------------------------- /test/jquery-usage/js/koans/aboutEvents.js: -------------------------------------------------------------------------------- 1 | 2 | module('About Backbone.Events', { 3 | setup: function() { 4 | this.obj = {}; 5 | _.extend(this.obj, Backbone.Events); 6 | this.obj.unbind(); // remove all custom events before each spec is run. 7 | } 8 | }); 9 | 10 | test('Can extend javascript objects to support custom events.', function() { 11 | 12 | expect(3); 13 | var basicObject = {}; 14 | 15 | // How would you give basicObject these functions? 16 | // Hint: http://documentcloud.github.com/backbone/#Events 17 | 18 | _.extend(basicObject, Backbone.Events); 19 | 20 | equal(typeof basicObject.bind, 'function'); 21 | equal(typeof basicObject.unbind, 'function'); 22 | equal(typeof basicObject.trigger, 'function'); 23 | }); 24 | 25 | 26 | 27 | test('Allows us to bind and trigger custom named events on an object.', function() { 28 | 29 | expect(1); 30 | 31 | var callback = this.spy(); 32 | 33 | this.obj.bind('basic event', callback); 34 | 35 | this.obj.trigger("basic event"); 36 | // How would you cause the callback for this custom event to be called? 37 | 38 | ok(callback.called); 39 | 40 | }); 41 | 42 | 43 | test('Also passes along any arguments to the callback when an event is triggered.', function() { 44 | 45 | expect(1); 46 | 47 | var passedArgs = []; 48 | 49 | this.obj.bind('some event', function() { 50 | for (var i = 0; i < arguments.length; i++) { 51 | passedArgs.push(arguments[i]); 52 | } 53 | }); 54 | 55 | this.obj.trigger('some event', 'arg1', 'arg2'); 56 | 57 | deepEqual(passedArgs, ['arg1', 'arg2']); 58 | }); 59 | 60 | 61 | test('Can also bind the passed context to the event callback.', function() { 62 | 63 | expect(1); 64 | 65 | var foo = { color: 'blue' }; 66 | 67 | var changeColor = function() { 68 | this.color = 'red'; 69 | } 70 | 71 | // How would you get 'this.color' to refer to 'foo' in the changeColor function? 72 | this.obj.bind('an event', changeColor, foo); 73 | this.obj.trigger('an event'); 74 | 75 | equal(foo.color, 'red'); 76 | 77 | }); 78 | 79 | 80 | test("Uses 'all' as a special event name to capture all events bound to the object.", function() { 81 | 82 | expect(2); 83 | 84 | var callback = this.spy(); 85 | 86 | this.obj.bind('all', callback); 87 | 88 | this.obj.trigger("custom event 1"); 89 | this.obj.trigger("custom event 2"); 90 | 91 | equal(callback.callCount, 2); 92 | equal(callback.getCall(0).args[0], 'custom event 1'); 93 | 94 | }); 95 | 96 | 97 | test('Also can remove custom events from objects.', function() { 98 | 99 | expect(5); 100 | 101 | var spy1 = this.spy(); 102 | var spy2 = this.spy(); 103 | var spy3 = this.spy(); 104 | 105 | this.obj.bind('foo', spy1); 106 | this.obj.bind('foo', spy2); 107 | this.obj.bind('foo', spy3); 108 | this.obj.bind('bar', spy1); 109 | 110 | // How do you unbind just a single callback for the event? 111 | this.obj.unbind('foo', spy1); 112 | this.obj.trigger('foo'); 113 | 114 | ok(spy2.called); 115 | 116 | // How do you unbind all callbacks tied to the event with a single method 117 | this.obj.unbind('foo'); 118 | this.obj.trigger('foo'); 119 | 120 | 121 | ok(spy2.callCount, 1); 122 | ok(spy2.calledOnce, "Spy 2 called once"); 123 | ok(spy3.calledOnce, "Spy 3 called once"); 124 | 125 | // How do you unbind all callbacks and events tied to the object with a single method? 126 | this.obj.unbind('bar'); 127 | 128 | this.obj.trigger('bar'); 129 | 130 | equal(spy1.callCount, 0); 131 | 132 | 133 | 134 | }); 135 | 136 | -------------------------------------------------------------------------------- /test/jquery-usage/js/koans/aboutModels.js: -------------------------------------------------------------------------------- 1 | module('About Backbone.Model'); 2 | 3 | test('Can be created with default values for its attributes.', function() { 4 | expect(1); 5 | var todo = new Todo(); 6 | equal(todo.get('text'), ""); 7 | }); 8 | 9 | test('Will set passed attributes on the model instance when created.', function() { 10 | 11 | expect(3); 12 | var todo = new Todo({ text: 'Get oil change for car.' }); 13 | 14 | equal(todo.get('text'), "Get oil change for car."); 15 | equal(todo.get('done'), false); 16 | equal(todo.get('order'), 0); 17 | }); 18 | 19 | test('Will call a custom initialize function on the model instance when created.', function() { 20 | 21 | expect(1); 22 | var toot = new Todo({ text: 'Stop monkeys from throwing their own crap!' }); 23 | equal(toot.get('text'), 'Stop monkeys from throwing their own rainbows!'); 24 | }); 25 | 26 | test('Fires a custom event when the state changes.', function() { 27 | 28 | expect(1); 29 | 30 | var spy = this.spy(); 31 | 32 | var todo = new Todo(); 33 | 34 | todo.bind('change', spy); 35 | 36 | // How would you update a property on the todo here? 37 | // Hint: http://documentcloud.github.com/backbone/#Model-set 38 | 39 | todo.set({text:"new text"}); 40 | 41 | ok(spy.calledOnce, "A change event callback was correctly triggered"); 42 | 43 | }); 44 | 45 | 46 | test('Can contain custom validation rules, and will trigger an error event on failed validation.', function() { 47 | 48 | expect(3); 49 | var errorCallback = this.spy(); 50 | 51 | var todo = new Todo(); 52 | 53 | todo.bind('error', errorCallback); 54 | 55 | // What would you need to set on the todo properties to cause validation to fail? 56 | todo.set({done:"not a boolean"}); 57 | 58 | ok(errorCallback.called, 'A failed validation correctly triggered an error'); 59 | notEqual(errorCallback.getCall(0), undefined); 60 | equal(errorCallback.getCall(0).args[1], 'Todo.done must be a boolean value.'); 61 | 62 | }); 63 | -------------------------------------------------------------------------------- /test/jquery-usage/js/koans/aboutViews.js: -------------------------------------------------------------------------------- 1 | module('About Backbone.View', { 2 | setup: function() { 3 | $('body').append('
                  '); 4 | this.todoView = new TodoView({ model: new Todo() }); 5 | }, 6 | teardown: function() { 7 | this.todoView.remove(); 8 | $('#todoList').remove(); 9 | } 10 | }); 11 | 12 | test('Should be tied to a DOM element when created, based off the property provided.', function() { 13 | equal(this.todoView.el.tagName.toLowerCase(), 'li'); 14 | }); 15 | 16 | test('Is backed by a model instance, which provides the data.', function() { 17 | notEqual(this.todoView.model, undefined); 18 | equal(this.todoView.model.get('done'), false); 19 | }); 20 | 21 | test('Can render, after which the DOM representation of the view will be visible.', function() { 22 | this.todoView.render(); 23 | 24 | // Hint: render() just builds the DOM representation of the view, but doesn't insert it into the DOM. 25 | // How would you append it to the ul#todoList? 26 | // How do you access the view's DOM representation? 27 | // 28 | // Hint: http://documentcloud.github.com/backbone/#View-el 29 | 30 | $('ul#todoList').append(this.todoView.el); 31 | equal($('#todoList').find('li').length, 1); 32 | }); 33 | -------------------------------------------------------------------------------- /test/jquery-usage/templates/app.html: -------------------------------------------------------------------------------- 1 |
                  2 |
                  3 |

                  Todos

                  4 |
                  5 | 6 |
                  7 |
                  8 | 9 | 10 |
                  11 | 12 |
                  13 |
                    14 |
                    15 | 16 |
                    17 |
                    18 |
                    -------------------------------------------------------------------------------- /test/jquery-usage/templates/item.html: -------------------------------------------------------------------------------- 1 |
                    2 |
                    3 | /> 4 |
                    5 | 6 |
                    7 |
                    8 | 9 |
                    10 |
                    -------------------------------------------------------------------------------- /test/jquery-usage/templates/stats.html: -------------------------------------------------------------------------------- 1 | <% if (total) { %> 2 | 3 | <%= remaining %> 4 | <%= remaining == 1 ? 'item' : 'items' %> left. 5 | 6 | <% } %> 7 | <% if (done) { %> 8 | 9 | 10 | Clear <%= done %> 11 | completed <%= done == 1 ? 'item' : 'items' %> 12 | 13 | 14 | <% } %> -------------------------------------------------------------------------------- /test/lib-tests/runner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Blanket tests 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
                    18 | 19 | 20 | -------------------------------------------------------------------------------- /test/mocha-browser/adapter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Mocha 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 |
                    22 | 23 | -------------------------------------------------------------------------------- /test/mocha-browser/adapter.js: -------------------------------------------------------------------------------- 1 | describe('Test an Object', function() { 2 | describe('Test a Function', function() { 3 | it('should return a greeting', function() { 4 | assert(anObject.aFunction() === 'Hello Blanket'); 5 | }); 6 | }); 7 | 8 | describe('Factorial', function() { 9 | it('should return the factorial of 1', function() { 10 | assert(anObject.factorial(1) === 1); 11 | }); 12 | }); 13 | 14 | }); -------------------------------------------------------------------------------- /test/mocha-browser/array.js: -------------------------------------------------------------------------------- 1 | describe('Array', function(){ 2 | describe('#push()', function(){ 3 | it('should append a value', function(){ 4 | var arr = []; 5 | arr.push('foo'); 6 | arr.push('bar'); 7 | arr.push('baz'); 8 | assert('foo' == arr[0]); // to test indentation 9 | assert('bar' == arr[1]); 10 | assert('baz' == arr[2]); 11 | }) 12 | 13 | it('should return the length', function(){ 14 | var arr = []; 15 | assert(1 == arr.push('foo')); 16 | assert(2 == arr.push('bar')); 17 | assert(3 == arr.push('baz')); 18 | }) 19 | }) 20 | }) 21 | 22 | describe('Array', function(){ 23 | describe('#pop()', function(){ 24 | it('should remove and return the last value', function(){ 25 | var arr = [1,2,3]; 26 | assert(arr.pop() == 3); 27 | assert(arr.pop() == 2); 28 | assert(arr.pop() == -1); 29 | }) 30 | 31 | it('should adjust .length', function(){ 32 | var arr = [1,2,3]; 33 | arr.pop(); 34 | assert(arr.length == 2); 35 | }) 36 | }) 37 | }) -------------------------------------------------------------------------------- /test/mocha-browser/duration.js: -------------------------------------------------------------------------------- 1 | 2 | describe('durations', function(){ 3 | describe('when slow', function(){ 4 | it('should highlight in red', function(done){ 5 | setTimeout(function(){ 6 | done(); 7 | }, 100); 8 | }) 9 | }) 10 | 11 | describe('when reasonable', function(){ 12 | it('should highlight in yellow', function(done){ 13 | setTimeout(function(){ 14 | done(); 15 | }, 50); 16 | }) 17 | }) 18 | 19 | describe('when fast', function(){ 20 | it('should highlight in green', function(done){ 21 | setTimeout(function(){ 22 | done(); 23 | }, 10); 24 | }) 25 | }) 26 | }) -------------------------------------------------------------------------------- /test/mocha-browser/globals.js: -------------------------------------------------------------------------------- 1 | 2 | describe('global leaks', function(){ 3 | before(function(){ 4 | // uncomment to test 5 | // foo = 'hey'; 6 | // bar = 'hey'; 7 | }) 8 | 9 | beforeEach(function(){ 10 | // uncomment to test 11 | // foo = 'bar' 12 | }); 13 | 14 | it('should cause tests to fail', function(){ 15 | // uncomment to test 16 | // foo = 'bar'; 17 | // bar = 'baz'; 18 | // baz = 'raz'; 19 | }); 20 | 21 | it('should pass when accepted', function(){ 22 | global.okGlobalA = 1; 23 | global.okGlobalB = 1; 24 | global.okGlobalC = 1; 25 | }) 26 | 27 | it('should pass with wildcard', function(){ 28 | global.callback123 = 'foo'; 29 | global.callback345 = 'bar'; 30 | }); 31 | 32 | it('should pass when prefixed "mocha-"', function(){ 33 | // Opera and IE do this for HTML element IDs anyway 34 | // but to sure we can assert this in any browser, simulate it. 35 | global['mocha-example'] = { nodeType: 1 }; 36 | }); 37 | 38 | afterEach(function(){ 39 | // uncomment to test 40 | // foo = 'bar' 41 | }); 42 | }); -------------------------------------------------------------------------------- /test/mocha-browser/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Mocha 4 | 5 | 6 | 7 | 8 | 13 | 14 | 15 | 16 | 26 | 27 | 28 |
                    29 | 30 | -------------------------------------------------------------------------------- /test/mocha-browser/large.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Mocha 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 20 | 21 | 22 |
                    23 | 24 | -------------------------------------------------------------------------------- /test/mocha-browser/large.js: -------------------------------------------------------------------------------- 1 | 2 | var n = 30; 3 | while (n--) { 4 | describe('Array ' + n, function(){ 5 | var arr; 6 | 7 | beforeEach(function(){ 8 | arr = [1,2,3]; 9 | }) 10 | 11 | describe('#indexOf()', function(){ 12 | it('should return -1 when the value is not present', function(){ 13 | assert(-1 == arr.indexOf(5)); 14 | }) 15 | 16 | it('should return the correct index when the value is present', function(done){ 17 | assert(0 == arr.indexOf(1)); 18 | assert(1 == arr.indexOf(2)); 19 | done(); 20 | }) 21 | }) 22 | }) 23 | } -------------------------------------------------------------------------------- /test/mocha-browser/opts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Mocha 4 | 5 | 6 | 7 | 13 | 18 | 19 | 20 | 25 | 26 | 27 |
                    28 | 29 | -------------------------------------------------------------------------------- /test/mocha-browser/opts.js: -------------------------------------------------------------------------------- 1 | describe('Options', function() { 2 | it('should set timeout value', function() { 3 | assert(this.test._timeout === 1500); 4 | }); 5 | }) -------------------------------------------------------------------------------- /test/mocha-browser/src/aSource.js: -------------------------------------------------------------------------------- 1 | window.anObject = { 2 | aFunction: function() { 3 | return 'Hello Blanket'; 4 | }, 5 | factorial: function(n) { 6 | if(n === 0 || n === 1) { 7 | return 1; 8 | } else { 9 | return n * anObject.factorial(n - 1); 10 | } 11 | } 12 | }; -------------------------------------------------------------------------------- /test/mocha-browser/timeout.js: -------------------------------------------------------------------------------- 1 | 2 | describe('timeouts', function(){ 3 | beforeEach(function(done){ 4 | // uncomment 5 | // setTimeout(done, 3000); 6 | done(); 7 | }) 8 | 9 | it('should error on timeout', function(done){ 10 | // uncomment 11 | // setTimeout(done, 3000); 12 | done(); 13 | }) 14 | 15 | it('should allow overriding per-test', function(done){ 16 | this.timeout(1000); 17 | setTimeout(function(){ 18 | done(); 19 | }, 300); 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /test/performance/blanket_performance_test.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var test1 = function() { 4 | blanket.options("instrumentCache",true); 5 | blanket.options("debug",true); 6 | expect(2); 7 | var infile = "var a=1;if(a==1){a=2;}if(a==3){a=4;}console.log(a);"; 8 | var infilename= "testfile"; 9 | blanket.instrument({ 10 | inputFile: infile, 11 | inputFileName: infilename 12 | },function(instrumented){ 13 | ok( instrumented.length > infile.length, "instrumented." ); 14 | ok(instrumented.indexOf("_$blanket['"+infilename+"']") > -1,"added enough instrumentation."); 15 | }); 16 | }; 17 | 18 | var test2 = function() { 19 | expect(1); 20 | blanket.options("instrumentCache",true); 21 | blanket.options("debug",true); 22 | var expected = 4, 23 | result; 24 | 25 | var infile = "var a=3;if(a==1){a=2;}else if(a==3){a="+expected+";}\nresult=a;"; 26 | var infilename= "testfile2"; 27 | blanket.instrument({ 28 | inputFile: infile, 29 | inputFileName: infilename 30 | },function(instrumented){ 31 | eval(instrumented); 32 | ok( result == expected, "instrumented properly." ); 33 | 34 | }); 35 | }; 36 | 37 | var test3 = function() { 38 | expect(1); 39 | var result; 40 | blanket.options("instrumentCache",true); 41 | blanket.options("debug",true); 42 | var infile = "var arr=[]; result = window.alert ? (function() {\n for ( var key in arr ) {\n arr[ key ]=0; \n}return true; \n})() : false;"; 43 | var infilename= "testfile3"; 44 | blanket.instrument({ 45 | inputFile: infile, 46 | inputFileName: infilename 47 | },function(instrumented){ 48 | eval(instrumented); 49 | ok( result, "instrumented properly." ); 50 | 51 | }); 52 | }; 53 | 54 | for (var i=0;i<1000;i++){ 55 | test( "blanket instrument: "+i, test1); 56 | test( "blanket instrument elseif block: "+i, test2); 57 | test( "blanket instrument for in: "+i, test3); 58 | } -------------------------------------------------------------------------------- /test/performance/performance_runner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Blanket tests 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
                    22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /test/qunit-start-stop/runner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Blanket tests 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
                    17 | 18 | 19 | -------------------------------------------------------------------------------- /test/qunit-start-stop/stop_start_test.js: -------------------------------------------------------------------------------- 1 | test( "stop start test", function() { 2 | ok(ins_test(), "here"); 3 | ok(ins_test(),"something else"); 4 | ok(ins_test(),"another thing."); 5 | QUnit.start(); 6 | QUnit.config.autostart = false; 7 | }); -------------------------------------------------------------------------------- /test/qunit-start-stop/test_script.js: -------------------------------------------------------------------------------- 1 | function ins_test(){ 2 | return true; 3 | } -------------------------------------------------------------------------------- /test/requirejs/chutzpah.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | 30 | 31 |

                    Unit Tests

                    32 |

                    33 |

                    34 |
                      35 |
                      36 | 37 | -------------------------------------------------------------------------------- /test/requirejs/code/all.tests.qunit.js: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // Blanket should save the XHR just in case there's a test that overwrites them. 5 | window.XMLHttpRequest = null; 6 | window.ActiveXObject = null; 7 | 8 | requirejs(['./tests/base/base.qunit.test', 9 | './tests/ui/ui.qunit.test'], 10 | function (){} 11 | ); 12 | -------------------------------------------------------------------------------- /test/requirejs/code/base/core.js: -------------------------------------------------------------------------------- 1 | define(function () { 2 | return { 3 | version: 8 4 | }; 5 | }); -------------------------------------------------------------------------------- /test/requirejs/code/tests/base/base.qunit.test.js: -------------------------------------------------------------------------------- 1 | define(['base/core'], 2 | function (core) { 3 | 4 | module("base/core"); 5 | test("will return correct version from core", function () { 6 | var version = core.version; 7 | equal(version, 8); 8 | }); 9 | 10 | }); 11 | -------------------------------------------------------------------------------- /test/requirejs/code/tests/ui/ui.qunit.test.js: -------------------------------------------------------------------------------- 1 | define(['ui/screen'], 2 | function (screen) { 3 | module("ui/screen"); 4 | test("will build display version", function () { 5 | var disp = screen.displayVersion; 6 | equal(disp, "Version: 8"); 7 | }); 8 | 9 | }); 10 | -------------------------------------------------------------------------------- /test/requirejs/code/ui/screen.js: -------------------------------------------------------------------------------- 1 | define(["base/core"], function(core) { 2 | return { 3 | displayVersion: "Version: " + core.version 4 | }; 5 | }); -------------------------------------------------------------------------------- /test/requirejs/require_runner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QUnit Example 6 | 7 | 8 | 9 | 10 | 11 | 13 | 24 | 25 | 26 |
                      27 | 28 | 29 | -------------------------------------------------------------------------------- /test/requirejs/require_sample.js: -------------------------------------------------------------------------------- 1 | //this test should fail 2 | var sampleTest = function(){ 3 | return 10; 4 | }; -------------------------------------------------------------------------------- /test/requirejs/require_test.js: -------------------------------------------------------------------------------- 1 | define(["require_sample"],function(){ 2 | 3 | test( "require test", function() { 4 | ok( sampleTest() == 10, "Passed!" ); 5 | }); 6 | 7 | }); -------------------------------------------------------------------------------- /test/test-node/fixture/blockinjection_test_file.js: -------------------------------------------------------------------------------- 1 | if(true) 2 | var a=true; 3 | else if(false) 4 | if (true) 5 | var b=false; -------------------------------------------------------------------------------- /test/test-node/fixture/blockinjection_test_file_instrumented.js: -------------------------------------------------------------------------------- 1 | _$jscoverage['blockinjection_test_file.js'][1]++; 2 | if(true) 3 | { 4 | _$jscoverage['blockinjection_test_file.js'][2]++; 5 | var a=true;} 6 | 7 | else { 8 | _$jscoverage['blockinjection_test_file.js'][3]++; 9 | if(false) 10 | { 11 | _$jscoverage['blockinjection_test_file.js'][4]++; 12 | if (true) 13 | { 14 | _$jscoverage['blockinjection_test_file.js'][5]++; 15 | var b=false;} 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/test-node/fixture/branch_complex_test_file.js: -------------------------------------------------------------------------------- 1 | function COMPLEXBRANCHTEST(x,y,z){ 2 | return x === 1 ? true : y === 2 ? z === 3 ? true : false : false; 3 | } -------------------------------------------------------------------------------- /test/test-node/fixture/branch_complex_test_file_instrumented.js: -------------------------------------------------------------------------------- 1 | if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; 2 | var _$branchFcn=function(f,l,c,r){ if (!!r) { _$jscoverage[f].branchData[l][c][0] = _$jscoverage[f].branchData[l][c][0] || [];_$jscoverage[f].branchData[l][c][0].push(r); }else { _$jscoverage[f].branchData[l][c][1] = _$jscoverage[f].branchData[l][c][1] || [];_$jscoverage[f].branchData[l][c][1].push(r); }return r;}; 3 | if (typeof _$jscoverage['branch_complex_test_file'] === 'undefined'){_$jscoverage['branch_complex_test_file']=[]; 4 | _$jscoverage['branch_complex_test_file'].branchData=[]; 5 | _$jscoverage['branch_complex_test_file'].source=['function COMPLEXBRANCHTEST(x,y,z){', 6 | 'return x === 1 ? true : y === 2 ? z === 3 ? true : false : false;', 7 | '}']; 8 | _$jscoverage['branch_complex_test_file'][1]=0; 9 | _$jscoverage['branch_complex_test_file'][2]=0; 10 | if (typeof _$jscoverage['branch_complex_test_file'].branchData[2] === 'undefined'){ 11 | _$jscoverage['branch_complex_test_file'].branchData[2]=[]; 12 | }_$jscoverage['branch_complex_test_file'].branchData[2][7] = []; 13 | _$jscoverage['branch_complex_test_file'].branchData[2][7].consequent = {"start":{"line":2,"column":17},"end":{"line":2,"column":21}}; 14 | _$jscoverage['branch_complex_test_file'].branchData[2][7].alternate = {"start":{"line":2,"column":24},"end":{"line":2,"column":64}}; 15 | if (typeof _$jscoverage['branch_complex_test_file'].branchData[2] === 'undefined'){ 16 | _$jscoverage['branch_complex_test_file'].branchData[2]=[]; 17 | }_$jscoverage['branch_complex_test_file'].branchData[2][24] = []; 18 | _$jscoverage['branch_complex_test_file'].branchData[2][24].consequent = {"start":{"line":2,"column":34},"end":{"line":2,"column":56}}; 19 | _$jscoverage['branch_complex_test_file'].branchData[2][24].alternate = {"start":{"line":2,"column":59},"end":{"line":2,"column":64}}; 20 | if (typeof _$jscoverage['branch_complex_test_file'].branchData[2] === 'undefined'){ 21 | _$jscoverage['branch_complex_test_file'].branchData[2]=[]; 22 | }_$jscoverage['branch_complex_test_file'].branchData[2][34] = []; 23 | _$jscoverage['branch_complex_test_file'].branchData[2][34].consequent = {"start":{"line":2,"column":44},"end":{"line":2,"column":48}}; 24 | _$jscoverage['branch_complex_test_file'].branchData[2][34].alternate = {"start":{"line":2,"column":51},"end":{"line":2,"column":56}}; 25 | }_$jscoverage['branch_complex_test_file'][1]++; 26 | function COMPLEXBRANCHTEST(x,y,z){ 27 | _$jscoverage['branch_complex_test_file'][2]++; 28 | return _$branchFcn('branch_complex_test_file',2,7,x === 1)?true:_$branchFcn('branch_complex_test_file',2,24,y === 2)?_$branchFcn('branch_complex_test_file',2,34,z === 3)?true:false:false; 29 | } -------------------------------------------------------------------------------- /test/test-node/fixture/branch_test_file.js: -------------------------------------------------------------------------------- 1 | function BRANCHTEST(x){ 2 | return x === 1 ? true : false; 3 | } -------------------------------------------------------------------------------- /test/test-node/fixture/branch_test_file_instrumented.js: -------------------------------------------------------------------------------- 1 | if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; 2 | var _$branchFcn=function(f,l,c,r){ if (!!r) { _$jscoverage[f].branchData[l][c][0] = _$jscoverage[f].branchData[l][c][0] || [];_$jscoverage[f].branchData[l][c][0].push(r); }else { _$jscoverage[f].branchData[l][c][1] = _$jscoverage[f].branchData[l][c][1] || [];_$jscoverage[f].branchData[l][c][1].push(r); }return r;}; 3 | if (typeof _$jscoverage['branch_test_file'] === 'undefined'){_$jscoverage['branch_test_file']=[]; 4 | _$jscoverage['branch_test_file'].branchData=[]; 5 | _$jscoverage['branch_test_file'].source=['function BRANCHTEST(x){', 6 | 'return x === 1 ? true : false;', 7 | '}']; 8 | _$jscoverage['branch_test_file'][1]=0; 9 | _$jscoverage['branch_test_file'][2]=0; 10 | if (typeof _$jscoverage['branch_test_file'].branchData[2] === 'undefined'){ 11 | _$jscoverage['branch_test_file'].branchData[2]=[]; 12 | }_$jscoverage['branch_test_file'].branchData[2][7] = []; 13 | _$jscoverage['branch_test_file'].branchData[2][7].consequent = {"start":{"line":2,"column":17},"end":{"line":2,"column":21}}; 14 | _$jscoverage['branch_test_file'].branchData[2][7].alternate = {"start":{"line":2,"column":24},"end":{"line":2,"column":29}}; 15 | }_$jscoverage['branch_test_file'][1]++; 16 | function BRANCHTEST(x){ 17 | _$jscoverage['branch_test_file'][2]++; 18 | return _$branchFcn('branch_test_file',2,7,x === 1)?true:false; 19 | } -------------------------------------------------------------------------------- /test/test-node/fixture/comment_test_file.js: -------------------------------------------------------------------------------- 1 | // this is a comment 2 | console.log("this should be instrumented."); 3 | // this is another comment 4 | console.log("this should also be instrumented"); 5 | /* longer comment */ 6 | console.log("another instrumented line."); 7 | // a multiline 8 | // comment 9 | console.log("yet another"); 10 | /* another 11 | multiline 12 | comment 13 | */ 14 | console.log("final line"); -------------------------------------------------------------------------------- /test/test-node/fixture/comment_test_file_instrumented.js: -------------------------------------------------------------------------------- 1 | if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; 2 | if (typeof _$jscoverage['comment_test_file'] === 'undefined'){_$jscoverage['comment_test_file']=[]; 3 | _$jscoverage['comment_test_file'].source=['// this is a comment', 4 | 'console.log("this should be instrumented.");', 5 | '// this is another comment', 6 | 'console.log("this should also be instrumented");', 7 | '/* longer comment */', 8 | 'console.log("another instrumented line.");', 9 | '// a multiline', 10 | '// comment', 11 | 'console.log("yet another");', 12 | '/* another', 13 | ' multiline', 14 | ' comment', 15 | ' */', 16 | 'console.log("final line");']; 17 | _$jscoverage['comment_test_file'][2]=0; 18 | _$jscoverage['comment_test_file'][4]=0; 19 | _$jscoverage['comment_test_file'][6]=0; 20 | _$jscoverage['comment_test_file'][9]=0; 21 | _$jscoverage['comment_test_file'][14]=0; 22 | }// this is a comment 23 | _$jscoverage['comment_test_file'][2]++; 24 | console.log("this should be instrumented."); 25 | // this is another comment 26 | _$jscoverage['comment_test_file'][4]++; 27 | console.log("this should also be instrumented"); 28 | /* longer comment */ 29 | _$jscoverage['comment_test_file'][6]++; 30 | console.log("another instrumented line."); 31 | // a multiline 32 | // comment 33 | _$jscoverage['comment_test_file'][9]++; 34 | console.log("yet another"); 35 | /* another 36 | multiline 37 | comment 38 | */ 39 | _$jscoverage['comment_test_file'][14]++; 40 | console.log("final line"); -------------------------------------------------------------------------------- /test/test-node/fixture/core_fixtures.js: -------------------------------------------------------------------------------- 1 | fs = require("fs"); 2 | 3 | //simple file fixture 4 | exports.simple_test_file_js = fs.readFileSync(__dirname+"/simple_test_file.js.js","utf-8"); 5 | 6 | exports.simple_test_file_instrumented_js = fs.readFileSync(__dirname+"/simple_test_file_instrumented.js.js","utf-8"); 7 | 8 | exports.simple_test_file_instrumented_full_js = fs.readFileSync(__dirname+"/simple_test_file_instrumented_full.js.js","utf-8"); 9 | 10 | //shebang file fixture 11 | exports.shebang_test_file_js = fs.readFileSync(__dirname+"/shebang_test_file.js","utf-8"); 12 | 13 | exports.shebang_test_file_instrumented_js = fs.readFileSync(__dirname+"/shebang_test_file_instrumented.js","utf-8"); 14 | 15 | //Block injection fixtures 16 | exports.blockinjection_test_file_js = fs.readFileSync(__dirname+"/blockinjection_test_file.js","utf-8"); 17 | 18 | exports.blockinjection_test_file_instrumented_js = fs.readFileSync(__dirname+"/blockinjection_test_file_instrumented.js","utf-8"); 19 | 20 | //comment fixtures 21 | exports.comment_test_file_js = fs.readFileSync(__dirname+"/comment_test_file.js","utf-8"); 22 | 23 | exports.comment_test_file_instrumented_js = fs.readFileSync(__dirname+"/comment_test_file_instrumented.js","utf-8"); 24 | 25 | //branch fixtures 26 | exports.branch_test_file_js = fs.readFileSync(__dirname+"/branch_test_file.js","utf-8"); 27 | 28 | exports.branch_test_file_instrumented_js = fs.readFileSync(__dirname+"/branch_test_file_instrumented.js","utf-8"); 29 | 30 | //complex branch fixtures 31 | exports.branch_complex_test_file_js = fs.readFileSync(__dirname+"/branch_complex_test_file.js","utf-8"); 32 | 33 | exports.branch_complex_test_file_instrumented_js = fs.readFileSync(__dirname+"/branch_complex_test_file_instrumented.js","utf-8"); 34 | 35 | //multi-line branch fixtures 36 | exports.branch_multi_line_test_file_js = fs.readFileSync(__dirname+"/multi_line_branch_test_file.js","utf-8"); 37 | 38 | exports.branch_multi_line_test_file_instrumented_js = fs.readFileSync(__dirname+"/multi_line_branch_test_file_instrumented.js","utf-8"); 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /test/test-node/fixture/multi_line_branch_test_file.js: -------------------------------------------------------------------------------- 1 | function MULTIBRANCHTEST(x){ 2 | return x === 1 ? 3 | true : 4 | false; 5 | } -------------------------------------------------------------------------------- /test/test-node/fixture/multi_line_branch_test_file_instrumented.js: -------------------------------------------------------------------------------- 1 | if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; 2 | var _$branchFcn=function(f,l,c,r){ if (!!r) { _$jscoverage[f].branchData[l][c][0] = _$jscoverage[f].branchData[l][c][0] || [];_$jscoverage[f].branchData[l][c][0].push(r); }else { _$jscoverage[f].branchData[l][c][1] = _$jscoverage[f].branchData[l][c][1] || [];_$jscoverage[f].branchData[l][c][1].push(r); }return r;}; 3 | if (typeof _$jscoverage['multi_line_branch_test_file'] === 'undefined'){_$jscoverage['multi_line_branch_test_file']=[]; 4 | _$jscoverage['multi_line_branch_test_file'].branchData=[]; 5 | _$jscoverage['multi_line_branch_test_file'].source=['function MULTIBRANCHTEST(x){', 6 | 'return x === 1 ?', 7 | ' true :', 8 | ' false;', 9 | '}']; 10 | _$jscoverage['multi_line_branch_test_file'][1]=0; 11 | _$jscoverage['multi_line_branch_test_file'][2]=0; 12 | if (typeof _$jscoverage['multi_line_branch_test_file'].branchData[2] === 'undefined'){ 13 | _$jscoverage['multi_line_branch_test_file'].branchData[2]=[]; 14 | }_$jscoverage['multi_line_branch_test_file'].branchData[2][7] = []; 15 | _$jscoverage['multi_line_branch_test_file'].branchData[2][7].consequent = {"start":{"line":3,"column":4},"end":{"line":3,"column":8}}; 16 | _$jscoverage['multi_line_branch_test_file'].branchData[2][7].alternate = {"start":{"line":4,"column":4},"end":{"line":4,"column":9}}; 17 | }_$jscoverage['multi_line_branch_test_file'][1]++; 18 | function MULTIBRANCHTEST(x){ 19 | _$jscoverage['multi_line_branch_test_file'][2]++; 20 | return _$branchFcn('multi_line_branch_test_file',2,7,x === 1)?true:false; 21 | } -------------------------------------------------------------------------------- /test/test-node/fixture/shebang_test_file.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | //this is test source 4 | var test='1234'; 5 | if (test === '1234') 6 | console.log(true); 7 | //comment 8 | console.log(test); 9 | -------------------------------------------------------------------------------- /test/test-node/fixture/shebang_test_file_instrumented.js: -------------------------------------------------------------------------------- 1 | if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; 2 | if (typeof _$jscoverage['shebang_test_file.js'] === 'undefined'){_$jscoverage['shebang_test_file.js']=[]; 3 | _$jscoverage['shebang_test_file.js'].source=['#!/usr/bin/env node', 4 | '', 5 | '//this is test source', 6 | 'var test=\'1234\';', 7 | 'if (test === \'1234\')', 8 | ' console.log(true);', 9 | '//comment', 10 | 'console.log(test);', 11 | '']; 12 | _$jscoverage['shebang_test_file.js'][4]=0; 13 | _$jscoverage['shebang_test_file.js'][5]=0; 14 | _$jscoverage['shebang_test_file.js'][6]=0; 15 | _$jscoverage['shebang_test_file.js'][8]=0; 16 | } 17 | //this is test source 18 | _$jscoverage['shebang_test_file.js'][4]++; 19 | var test='1234'; 20 | _$jscoverage['shebang_test_file.js'][5]++; 21 | if (test === '1234') 22 | { 23 | _$jscoverage['shebang_test_file.js'][6]++; 24 | console.log(true);} 25 | 26 | //comment 27 | _$jscoverage['shebang_test_file.js'][8]++; 28 | console.log(test); 29 | -------------------------------------------------------------------------------- /test/test-node/fixture/simple_test_file.js.js: -------------------------------------------------------------------------------- 1 | //this is test source 2 | var test='1234'; 3 | if (test === '1234') 4 | console.log(true); 5 | //comment 6 | console.log(test); -------------------------------------------------------------------------------- /test/test-node/fixture/simple_test_file_instrumented.js.js: -------------------------------------------------------------------------------- 1 | //this is test source 2 | _$jscoverage['simple_test_file.js'][2]++; 3 | var test='1234'; 4 | _$jscoverage['simple_test_file.js'][3]++; 5 | if (test === '1234') 6 | { 7 | _$jscoverage['simple_test_file.js'][4]++; 8 | console.log(true);} 9 | 10 | //comment 11 | _$jscoverage['simple_test_file.js'][6]++; 12 | console.log(test); -------------------------------------------------------------------------------- /test/test-node/fixture/simple_test_file_instrumented_full.js.js: -------------------------------------------------------------------------------- 1 | if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; 2 | if (typeof _$jscoverage['simple_test_file.js'] === 'undefined'){_$jscoverage['simple_test_file.js']=[]; 3 | _$jscoverage['simple_test_file.js'].source=['//this is test source', 4 | 'var test=\'1234\';', 5 | 'if (test === \'1234\')', 6 | ' console.log(true);', 7 | '//comment', 8 | 'console.log(test);']; 9 | _$jscoverage['simple_test_file.js'][2]=0; 10 | _$jscoverage['simple_test_file.js'][3]=0; 11 | _$jscoverage['simple_test_file.js'][4]=0; 12 | _$jscoverage['simple_test_file.js'][6]=0; 13 | }//this is test source 14 | _$jscoverage['simple_test_file.js'][2]++; 15 | var test='1234'; 16 | _$jscoverage['simple_test_file.js'][3]++; 17 | if (test === '1234') 18 | { 19 | _$jscoverage['simple_test_file.js'][4]++; 20 | console.log(true);} 21 | 22 | //comment 23 | _$jscoverage['simple_test_file.js'][6]++; 24 | console.log(test); -------------------------------------------------------------------------------- /test/test-node/fixture/src/sample.coffee: -------------------------------------------------------------------------------- 1 | module.exports = -> 2 | 10 -------------------------------------------------------------------------------- /test/test-node/fixture/src/sampleCjsx.cjsx: -------------------------------------------------------------------------------- 1 | React = require 'react' 2 | 3 | module.exports = -> 4 |
                      10
                      -------------------------------------------------------------------------------- /test/test-node/fixture/src/sourceA.js: -------------------------------------------------------------------------------- 1 | var B = require("./sourceB"); 2 | var C = require("./sourceC"); 3 | 4 | module.exports = B + C; -------------------------------------------------------------------------------- /test/test-node/fixture/src/sourceB.js: -------------------------------------------------------------------------------- 1 | module.exports = 3; -------------------------------------------------------------------------------- /test/test-node/fixture/src/sourceC.js: -------------------------------------------------------------------------------- 1 | require("./sourceB"); 2 | 3 | module.exports = 4; -------------------------------------------------------------------------------- /test/test-node/fixture/test/testA.js: -------------------------------------------------------------------------------- 1 | var srcA = require("../src/sourceA"); 2 | 3 | module.exports = srcA; -------------------------------------------------------------------------------- /test/test-node/testrunner.js: -------------------------------------------------------------------------------- 1 | var path = require("path"); 2 | var blanket = require("../../src/index")({ 3 | "pattern":"/src/blanket" 4 | }); 5 | 6 | /* 7 | since we're using blanket to test blanket, 8 | we need to remove the module entry from the require cache 9 | so that it can be instrumented. 10 | */ 11 | delete require.cache[path.normalize(__dirname+"/../../src/blanket.js")]; 12 | /* 13 | now start the tests 14 | */ 15 | 16 | require("./tests/blanket_core"); 17 | require("./tests/nested_test"); 18 | require("./tests/instrumentation_test"); -------------------------------------------------------------------------------- /test/test-node/testrunner_cjsx.js: -------------------------------------------------------------------------------- 1 | var blanket = require("../../src/index")(); 2 | blanket.options("filter","src/sample"); 3 | 4 | require("./tests/cjsx/test.coffee"); -------------------------------------------------------------------------------- /test/test-node/testrunner_cs.js: -------------------------------------------------------------------------------- 1 | var blanket = require("../../src/index")(); 2 | blanket.options("filter","src/sample"); 3 | 4 | require("./tests/coffee-script/test.coffee"); -------------------------------------------------------------------------------- /test/test-node/tests/cjsx/test.coffee: -------------------------------------------------------------------------------- 1 | React = require("react") 2 | sampleTest = require("../../fixture/src/sampleCjsx.cjsx") 3 | assert = require("assert") 4 | describe "require test", -> 5 | it "should return div with 10", -> 6 | result = sampleTest() 7 | assert.equal 'div', result.type 8 | assert.equal 10, result.props.children -------------------------------------------------------------------------------- /test/test-node/tests/coffee-script/test.coffee: -------------------------------------------------------------------------------- 1 | sampleTest = require("../../fixture/src/sample.coffee") 2 | assert = require("assert") 3 | describe "require test", -> 4 | it "should return 10", -> 5 | assert.equal 10, sampleTest() -------------------------------------------------------------------------------- /test/test-node/tests/nested_test.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var test1 = require("../fixture/test/testA"); 4 | var assert = require("assert"); 5 | 6 | 7 | describe('nested test', function(){ 8 | it('should return 7', function(){ 9 | assert.equal(7, test1); 10 | }); 11 | }); 12 | 13 | -------------------------------------------------------------------------------- /test/testconfigs.json: -------------------------------------------------------------------------------- 1 | { 2 | "phantom": { 3 | "qunit": "test/helpers/phantom_qunit_runner.js", 4 | "qunit_old": "test/helpers/phantom_qunit_old_runner.js", 5 | "jasmine": "test/helpers/phantom_jasmine_runner.js", 6 | "mocha": "test/helpers/phantom_mocha_runner.js" 7 | }, 8 | "reporters": { 9 | "qunit": "node_modules/travis-cov/phantom_runner.js", 10 | "jasmine": "node_modules/travis-cov/phantom_jasmine_runner.js", 11 | "mocha": { 12 | "browser": "node_modules/travis-cov/phantom_mocha_runner.js", 13 | "node": "travis-cov" 14 | } 15 | }, 16 | "runners": { 17 | "node": "test/test-node/testrunner.js", 18 | "nodeCS": "test/test-node/testrunner_cs.js", 19 | "nodeCJSX": "test/test-node/testrunner_cjsx.js", 20 | "browser" :"test/lib-tests/runner.html?coverage=true", 21 | "browserBranchTracking" :"test/branchTracking/branch_runner.html?coverage=true", 22 | "browserRequire" :"test/requirejs/require_runner.html?coverage=true", 23 | "browserBackbone" :"test/backbone-koans/index.html?coverage=true", 24 | "browserReporter" :"test/custom-reporter/index.html?coverage=true", 25 | "browserJasmine" :"test/jasmine/SpecRunner.html", 26 | "browserJasmineBuild" :"test/jasmine-custom-build/SpecRunner.html", 27 | "browserJasmineAdapter" :"test/jasmine/SpecRunner_data_adapter.html", 28 | "browserJasmineAdapterArray" :"test/jasmine/SpecRunner_data_adapter_array.html", 29 | "browserJasmineAdapterRegex" :"test/jasmine/SpecRunner_data_adapter_regex.html", 30 | "browserMochaAdapter" :"test/mocha-browser/adapter.html", 31 | "browserBootstrap" :"test/bootstrap/tests/index.html", 32 | "browserCoffeeScript" :"test/coffee_script/index.html?coverage=true", 33 | "browserJasmineRequire" :"test/jasmine-requirejs/runner.html", 34 | "browserChutzpah" :"test/requirejs/chutzpah.html?coverage=true", 35 | "browserCommonjs" :"test/commonjs/runner.html?coverage=true" 36 | }, 37 | "cmds": { 38 | "phantom": "./node_modules/phantomjs/bin/phantomjs", 39 | "mocha": "./node_modules/mocha/bin/mocha", 40 | "mochaCS": "./node_modules/mocha/bin/mocha --compilers coffee:coffee-script/register", 41 | "mochaCJSX": "./node_modules/mocha/bin/mocha --compilers coffee:coffee-script/register,cjsx:coffee-react/register" 42 | } 43 | } -------------------------------------------------------------------------------- /test/usage/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Backbone.js Todos 7 | 8 | 9 | 10 | 11 | 12 |
                      13 | 14 |
                      15 |

                      Todos

                      16 | 17 |
                      18 | 19 |
                      20 | 21 | 22 |
                        23 |
                        24 | 25 | 29 | 30 |
                        31 | 32 |
                        33 | Double-click to edit a todo. 34 |
                        35 | 36 |
                        37 | Created by 38 |
                        39 | Jérôme Gravel-Niquet. 40 |
                        Rewritten by: TodoMVC. 41 |
                        42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 59 | 60 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /test/usage/test_fcn.js: -------------------------------------------------------------------------------- 1 | function testfcn(){ 2 | console.log("test"); 3 | } 4 | 5 | $("#testheader").click(testfcn); -------------------------------------------------------------------------------- /test/usage/testpage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

                        Test

                        8 | 9 | 10 | -------------------------------------------------------------------------------- /test/yui/runner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Blanket YUI tests 6 | 7 | 8 | 9 | 10 | 11 | 12 | 42 | 43 | 44 | 45 |
                        46 |

                        47 | 48 | -------------------------------------------------------------------------------- /test/yui/test_module_yui.js: -------------------------------------------------------------------------------- 1 | YUI.add('test-module', function (Y) { 2 | Y.testModule = 5; 3 | }); -------------------------------------------------------------------------------- /test/yui/test_module_yui_test.js: -------------------------------------------------------------------------------- 1 | YUI().use('test-module','test', function (Y) { 2 | var testCase = new Y.Test.Case({ 3 | 4 | name: "TestModule", 5 | 6 | testUsingAsserts : function () { 7 | Y.assert(Y.testModule == 5, "The value should be five."); 8 | } 9 | }); 10 | 11 | //add the test cases and suites 12 | Y.Test.Runner.add(testCase); 13 | }); -------------------------------------------------------------------------------- /testserver.js: -------------------------------------------------------------------------------- 1 | /* modules */ 2 | var url = require('url'), 3 | express = require('express'); 4 | 5 | /* init */ 6 | var app = express.createServer(); 7 | app.use(require('express').bodyParser()); 8 | 9 | app.configure(function(){ 10 | app.use(express.static(__dirname)); 11 | }); 12 | 13 | app.get('*', function(req, res){ 14 | res.render('./runner.html'); 15 | }); 16 | 17 | app.listen(3000); 18 | console.log("App started."); 19 | --------------------------------------------------------------------------------