├── app └── .gitkeep ├── addon └── .gitkeep ├── vendor └── .gitkeep ├── tests ├── unit │ └── .gitkeep ├── dummy │ ├── app │ │ ├── helpers │ │ │ └── .gitkeep │ │ ├── models │ │ │ └── .gitkeep │ │ ├── routes │ │ │ └── .gitkeep │ │ ├── views │ │ │ └── .gitkeep │ │ ├── components │ │ │ └── .gitkeep │ │ ├── controllers │ │ │ └── .gitkeep │ │ ├── templates │ │ │ ├── components │ │ │ │ └── .gitkeep │ │ │ └── application.hbs │ │ ├── styles │ │ │ └── app.css │ │ ├── router.js │ │ ├── app.js │ │ └── index.html │ ├── public │ │ ├── robots.txt │ │ └── crossdomain.xml │ └── config │ │ └── environment.js ├── helpers │ ├── cassette.js │ ├── resolver.js │ └── start-app.js ├── test-helper.js ├── index.html └── .jshintrc ├── .bowerrc ├── blueprints ├── .jshintrc └── ember-cli-betamax │ ├── files │ └── tests │ │ └── helpers │ │ └── cassette.js │ └── index.js ├── config └── environment.js ├── .npmignore ├── testem.json ├── index.js ├── .ember-cli ├── .gitignore ├── .travis.yml ├── .jshintrc ├── .editorconfig ├── bower.json ├── Brocfile.js ├── test-support └── helpers │ ├── insert-cassette.js │ ├── fake-server.js │ └── betamax-recorder.js ├── LICENSE.md ├── package.json └── README.md /app/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /addon/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/unit/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/dummy/app/helpers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/dummy/app/models/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/dummy/app/routes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/dummy/app/views/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/dummy/app/components/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/dummy/app/controllers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/components/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/dummy/app/styles/app.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | margin: 20px; 3 | } 4 | -------------------------------------------------------------------------------- /tests/dummy/public/robots.txt: -------------------------------------------------------------------------------- 1 | # http://www.robotstxt.org 2 | User-agent: * 3 | -------------------------------------------------------------------------------- /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components", 3 | "analytics": false 4 | } 5 | -------------------------------------------------------------------------------- /blueprints/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "console" 4 | ], 5 | "strict": false 6 | } 7 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/application.hbs: -------------------------------------------------------------------------------- 1 |

Welcome to Ember.js

2 | 3 | {{outlet}} 4 | -------------------------------------------------------------------------------- /config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(/* environment, appConfig */) { 4 | return { }; 5 | }; 6 | -------------------------------------------------------------------------------- /tests/helpers/cassette.js: -------------------------------------------------------------------------------- 1 | export default function(server) { 2 | server.respondWith( 'GET', 3 | '/api/foo', [ 200, {}, "{}" ]); 4 | } 5 | -------------------------------------------------------------------------------- /blueprints/ember-cli-betamax/files/tests/helpers/cassette.js: -------------------------------------------------------------------------------- 1 | export default function(server) { 2 | server.respondWith( 'GET', 3 | '/api/foo', [ 200, {}, "{}" ]); 4 | } 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | bower_components/ 2 | tests/ 3 | 4 | .bowerrc 5 | .editorconfig 6 | .ember-cli 7 | .travis.yml 8 | .npmignore 9 | **/.gitkeep 10 | bower.json 11 | Brocfile.js 12 | testem.json 13 | -------------------------------------------------------------------------------- /testem.json: -------------------------------------------------------------------------------- 1 | { 2 | "framework": "qunit", 3 | "test_page": "tests/index.html?hidepassed", 4 | "launch_in_ci": [ 5 | "PhantomJS" 6 | ], 7 | "launch_in_dev": [ 8 | "PhantomJS", 9 | "Chrome" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/dummy/app/router.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import config from './config/environment'; 3 | 4 | var Router = Ember.Router.extend({ 5 | location: config.locationType 6 | }); 7 | 8 | Router.map(function() { 9 | }); 10 | 11 | export default Router; 12 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* jshint node: true */ 2 | 'use strict'; 3 | 4 | module.exports = { 5 | name: 'ember-cli-betamax', 6 | included: function(app) { 7 | if (app.tests) { 8 | app.import('bower_components/sinon/index.js', { 9 | type: 'test' 10 | }); 11 | } 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /.ember-cli: -------------------------------------------------------------------------------- 1 | { 2 | /** 3 | Ember CLI sends analytics information by default. The data is completely 4 | anonymous, but there are times when you might want to disable this behavior. 5 | 6 | Setting `disableAnalytics` to true will prevent any data from being sent. 7 | */ 8 | "disableAnalytics": false 9 | } 10 | -------------------------------------------------------------------------------- /tests/helpers/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from 'ember/resolver'; 2 | import config from '../../config/environment'; 3 | 4 | var resolver = Resolver.create(); 5 | 6 | resolver.namespace = { 7 | modulePrefix: config.modulePrefix, 8 | podModulePrefix: config.podModulePrefix 9 | }; 10 | 11 | export default resolver; 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | 7 | # dependencies 8 | /node_modules 9 | /bower_components 10 | 11 | # misc 12 | /.sass-cache 13 | /connect.lock 14 | /coverage/* 15 | /libpeerconnection.log 16 | npm-debug.log 17 | testem.log 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: node_js 3 | 4 | sudo: false 5 | 6 | cache: 7 | directories: 8 | - node_modules 9 | 10 | before_install: 11 | - "npm config set spin false" 12 | - "npm install -g npm@^2" 13 | 14 | install: 15 | - npm install -g bower 16 | - npm install 17 | - bower install 18 | 19 | script: 20 | - npm test 21 | -------------------------------------------------------------------------------- /tests/dummy/app/app.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import Resolver from 'ember/resolver'; 3 | import loadInitializers from 'ember/load-initializers'; 4 | import config from './config/environment'; 5 | 6 | Ember.MODEL_FACTORY_INJECTIONS = true; 7 | 8 | var App = Ember.Application.extend({ 9 | modulePrefix: config.modulePrefix, 10 | podModulePrefix: config.podModulePrefix, 11 | Resolver: Resolver 12 | }); 13 | 14 | loadInitializers(App, config.modulePrefix); 15 | 16 | export default App; 17 | -------------------------------------------------------------------------------- /tests/helpers/start-app.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import Application from '../../app'; 3 | import Router from '../../router'; 4 | import config from '../../config/environment'; 5 | 6 | export default function startApp(attrs) { 7 | var application; 8 | 9 | var attributes = Ember.merge({}, config.APP); 10 | attributes = Ember.merge(attributes, attrs); // use defaults, but you can override; 11 | 12 | Ember.run(function() { 13 | application = Application.create(attributes); 14 | application.setupForTesting(); 15 | application.injectTestHelpers(); 16 | }); 17 | 18 | return application; 19 | } 20 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "document", 4 | "window", 5 | "-Promise" 6 | ], 7 | "browser": true, 8 | "boss": true, 9 | "curly": true, 10 | "debug": false, 11 | "devel": true, 12 | "eqeqeq": true, 13 | "evil": true, 14 | "forin": false, 15 | "immed": false, 16 | "laxbreak": false, 17 | "newcap": true, 18 | "noarg": true, 19 | "noempty": false, 20 | "nonew": false, 21 | "nomen": false, 22 | "onevar": false, 23 | "plusplus": false, 24 | "regexp": false, 25 | "undef": true, 26 | "sub": true, 27 | "strict": false, 28 | "white": false, 29 | "eqnull": true, 30 | "esnext": true, 31 | "unused": true 32 | } 33 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [*.js] 17 | indent_style = space 18 | indent_size = 2 19 | 20 | [*.hbs] 21 | indent_style = space 22 | indent_size = 2 23 | 24 | [*.css] 25 | indent_style = space 26 | indent_size = 2 27 | 28 | [*.html] 29 | indent_style = space 30 | indent_size = 2 31 | 32 | [*.{diff,md}] 33 | trim_trailing_whitespace = false 34 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-cli-betamax", 3 | "dependencies": { 4 | "handlebars": "~1.3.0", 5 | "jquery": "^1.11.1", 6 | "ember": "1.8.1", 7 | "ember-data": "1.0.0-beta.12", 8 | "ember-resolver": "~0.1.11", 9 | "loader.js": "ember-cli/loader.js#1.0.1", 10 | "ember-cli-shims": "ember-cli/ember-cli-shims#0.0.3", 11 | "ember-cli-test-loader": "rwjblue/ember-cli-test-loader#0.0.4", 12 | "ember-load-initializers": "ember-cli/ember-load-initializers#0.0.2", 13 | "ember-qunit": "0.1.8", 14 | "ember-qunit-notifications": "0.0.5", 15 | "qunit": "~1.17.1", 16 | "sinon": "http://sinonjs.org/releases/sinon-1.12.2.js" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/dummy/public/crossdomain.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /tests/dummy/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dummy 7 | 8 | 9 | 10 | {{content-for 'head'}} 11 | 12 | 13 | 14 | 15 | {{content-for 'head-footer'}} 16 | 17 | 18 | {{content-for 'body'}} 19 | 20 | 21 | 22 | 23 | {{content-for 'body-footer'}} 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/test-helper.js: -------------------------------------------------------------------------------- 1 | import resolver from './helpers/resolver'; 2 | import insertCassette from './helpers/insert-cassette'; 3 | import cassette from './helpers/cassette'; 4 | import { 5 | setResolver 6 | } from 'ember-qunit'; 7 | import cassette from './helpers/cassette'; 8 | import insertCassette from './helpers/insert-cassette'; 9 | 10 | setResolver(resolver); 11 | insertCassette(cassette); 12 | 13 | document.write('
'); 14 | 15 | QUnit.config.urlConfig.push({ id: 'nocontainer', label: 'Hide container' }); 16 | var containerVisibility = QUnit.urlParams.nocontainer ? 'hidden' : 'visible'; 17 | document.getElementById('ember-testing-container').style.visibility = containerVisibility; 18 | 19 | 20 | -------------------------------------------------------------------------------- /Brocfile.js: -------------------------------------------------------------------------------- 1 | /* jshint node: true */ 2 | /* global require, module */ 3 | 4 | var EmberAddon = require('ember-cli/lib/broccoli/ember-addon'); 5 | 6 | var app = new EmberAddon(); 7 | 8 | // Use `app.import` to add additional libraries to the generated 9 | // output files. 10 | // 11 | // If you need to use different assets in different 12 | // environments, specify an object as the first parameter. That 13 | // object's keys should be the environment name and the values 14 | // should be the asset to use in that environment. 15 | // 16 | // If the library that you are including contains AMD or ES6 17 | // modules that you would like to import into your application 18 | // please specify an object with the list of modules as keys 19 | // along with the exports of each module as its value. 20 | 21 | module.exports = app.toTree(); 22 | -------------------------------------------------------------------------------- /test-support/helpers/insert-cassette.js: -------------------------------------------------------------------------------- 1 | import { 2 | startServer, 3 | stopServer, 4 | setupServer 5 | } from './fake-server'; 6 | import betamaxRecorder from './betamax-recorder'; 7 | 8 | export default function(cassette){ 9 | 10 | QUnit.config.urlConfig.push({ 11 | id: 'record', 12 | value: 'true', 13 | label: 'record API Queries', 14 | tooltip: 'Allow for live API querying and save the results' 15 | }); 16 | 17 | QUnit.begin(function(){ 18 | startServer(); 19 | //if record is not selected, use recordings 20 | if(!(QUnit.urlParams && QUnit.urlParams.record)){ 21 | setupServer(cassette); 22 | } 23 | betamaxRecorder.setup(); 24 | }); 25 | 26 | QUnit.done(function(){ 27 | stopServer(); 28 | //if we are not in testem, download new casettes. 29 | if(QUnit.urlParams && QUnit.urlParams.record){ 30 | betamaxRecorder.download(); 31 | } 32 | }); 33 | } 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-cli-betamax", 3 | "version": "0.1.8", 4 | "description": "Allows for the recording and playback of API responses, Sort of like Rails VCR, but for Ember CLI", 5 | "directories": { 6 | "doc": "doc", 7 | "test": "tests" 8 | }, 9 | "scripts": { 10 | "start": "ember server", 11 | "build": "ember build", 12 | "test": "ember test" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/simplereach/ember-cli-betamax.git" 17 | }, 18 | "engines": { 19 | "node": ">= 0.10.0" 20 | }, 21 | "author": "André Malan", 22 | "license": "MIT", 23 | "devDependencies": { 24 | "body-parser": "^1.10.2", 25 | "broccoli-asset-rev": "^2.0.0", 26 | "broccoli-ember-hbs-template-compiler": "^1.6.1", 27 | "ember-cli": "0.1.9", 28 | "ember-cli-ic-ajax": "0.1.1", 29 | "ember-cli-inject-live-reload": "^1.3.0", 30 | "ember-cli-qunit": "0.1.2", 31 | "ember-data": "1.0.0-beta.12", 32 | "ember-export-application-global": "^1.0.0", 33 | "express": "^4.8.5", 34 | "glob": "^4.0.5" 35 | }, 36 | "keywords": [ 37 | "ember-addon" 38 | ], 39 | "ember-addon": { 40 | "configPath": "tests/dummy/config" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ember-cli-betamax 2 | 3 | 4 | ## Installation 5 | 6 | * npm install simplereach/ember-cli-betamax --save-dev 7 | * ember generate ember-cli-betamax 8 | * this *should* add the following to your tests/test-helper file: 9 | 10 | ``` 11 | import cassette from './helpers/cassette'; 12 | import insertCassette from './helpers/insert-cassette'; 13 | 14 | insertCassette(cassette); 15 | ``` 16 | 17 | ## Creating a recording 18 | 19 | * in a QUnit test click on the "Record API Queries" checkbox (typically you should do it on the global test route) 20 | * when the tests are finished a file will automatically be downloaded 21 | * replace the current cassette.js in tests/helpers with the new cassette.js 22 | 23 | 24 | ## How it works 25 | 26 | * When record is set to true, every ajax response is monitored and saved to an array. 27 | * Within one recording session responses are cached, so you will only hit the same endpoint once. 28 | * At the end of the session a "cassette" is saved in the format that Sinon Fake server expects. 29 | * If record is not true, Sinon Fake server is pre-loaded with your already recorded cassette. 30 | * If something has not been recorded, it will be downloaded at the end of a test run. The new cassette can be manually merged. 31 | -------------------------------------------------------------------------------- /tests/dummy/config/environment.js: -------------------------------------------------------------------------------- 1 | /* jshint node: true */ 2 | 3 | module.exports = function(environment) { 4 | var ENV = { 5 | modulePrefix: 'dummy', 6 | environment: environment, 7 | baseURL: '/', 8 | locationType: 'auto', 9 | EmberENV: { 10 | FEATURES: { 11 | // Here you can enable experimental features on an ember canary build 12 | // e.g. 'with-controller': true 13 | } 14 | }, 15 | 16 | APP: { 17 | // Here you can pass flags/options to your application instance 18 | // when it is created 19 | } 20 | }; 21 | 22 | if (environment === 'development') { 23 | // ENV.APP.LOG_RESOLVER = true; 24 | // ENV.APP.LOG_ACTIVE_GENERATION = true; 25 | // ENV.APP.LOG_TRANSITIONS = true; 26 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; 27 | // ENV.APP.LOG_VIEW_LOOKUPS = true; 28 | } 29 | 30 | if (environment === 'test') { 31 | // Testem prefers this... 32 | ENV.baseURL = '/'; 33 | ENV.locationType = 'none'; 34 | 35 | // keep test console output quieter 36 | ENV.APP.LOG_ACTIVE_GENERATION = false; 37 | ENV.APP.LOG_VIEW_LOOKUPS = false; 38 | 39 | ENV.APP.rootElement = '#ember-testing'; 40 | } 41 | 42 | if (environment === 'production') { 43 | 44 | } 45 | 46 | return ENV; 47 | }; 48 | -------------------------------------------------------------------------------- /test-support/helpers/fake-server.js: -------------------------------------------------------------------------------- 1 | var server; 2 | 3 | export function startServer(){ 4 | if (server) { 5 | console.warn('startServer called while server is already running, ignoring.'); 6 | return; 7 | } 8 | server = sinon.fakeServer.create(); 9 | server.autoRespond = true; 10 | server.autoRespondAfter = 1; 11 | server.xhr.useFilters = true; 12 | 13 | //fake response to make sure the response hash is generated 14 | server.respondWith('GET', '/foo/bar', [200,{},""]); 15 | server.xhr.addFilter(function(method, url) { 16 | //whenever the this returns true the request will not be faked 17 | var fake = true; 18 | server.responses.forEach(function(response){ 19 | if(response.url === url){ 20 | fake = false; 21 | return; 22 | } 23 | }); 24 | if (fake) { 25 | console.error("request for url not faked:" + url); 26 | } 27 | return fake; 28 | }); 29 | } 30 | 31 | export function stopServer() { 32 | if(server) { 33 | server.restore(); 34 | server = null; 35 | } 36 | } 37 | 38 | export function setupServer(setup) { 39 | setup(server); 40 | } 41 | 42 | export function getServer(){ 43 | if (!server) { 44 | console.log('STARTING server from getServer'); 45 | startServer(); 46 | } 47 | return server; 48 | } 49 | -------------------------------------------------------------------------------- /blueprints/ember-cli-betamax/index.js: -------------------------------------------------------------------------------- 1 | /* globals module */ 2 | 3 | var EOL = require('os').EOL; 4 | 5 | module.exports = { 6 | description: 'record api queries to cassettes', 7 | 8 | afterInstall: function( options ) { 9 | 10 | // Import statement 11 | var firstFile = 'tests/test-helper.js', 12 | firstText = "import insertCassette from './helpers/insert-cassette';" + EOL + 13 | "import cassette from './helpers/cassette';", 14 | firstLocationText = "import resolver from './helpers/resolver';" + EOL, 15 | 16 | 17 | // Execution of registration function 18 | secondText = "insertCassette(cassette);", 19 | secondLocationText = "setResolver(resolver);" + EOL; 20 | 21 | // Import statement 22 | // 23 | return this.addBowerPackageToProject('sinon=http://sinonjs.org/releases/sinon-1.12.2.js') 24 | 25 | .then(function(){ 26 | return this.insertIntoFile( firstFile, firstText, { after: firstLocationText } ) 27 | }.bind(this)) 28 | 29 | // Execution of registration function 30 | .then( function() { 31 | return this.insertIntoFile( firstFile, secondText, { after: secondLocationText } ); 32 | }.bind(this)) 33 | }, 34 | //this is neccessary for ember generate to work 35 | normalizeEntityName: function() {} 36 | }; 37 | -------------------------------------------------------------------------------- /tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dummy Tests 7 | 8 | 9 | 10 | {{content-for 'head'}} 11 | {{content-for 'test-head'}} 12 | 13 | 14 | 15 | 16 | 32 | 33 | {{content-for 'head-footer'}} 34 | {{content-for 'test-head-footer'}} 35 | 36 | 37 | 38 | {{content-for 'body'}} 39 | {{content-for 'test-body'}} 40 | 41 | 42 | 43 | 44 | 45 | 46 | {{content-for 'body-footer'}} 47 | {{content-for 'test-body-footer'}} 48 | 49 | 50 | -------------------------------------------------------------------------------- /tests/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "document", 4 | "window", 5 | "location", 6 | "setTimeout", 7 | "$", 8 | "-Promise", 9 | "QUnit", 10 | "define", 11 | "console", 12 | "equal", 13 | "notEqual", 14 | "notStrictEqual", 15 | "test", 16 | "asyncTest", 17 | "testBoth", 18 | "testWithDefault", 19 | "raises", 20 | "throws", 21 | "deepEqual", 22 | "start", 23 | "stop", 24 | "ok", 25 | "strictEqual", 26 | "module", 27 | "moduleFor", 28 | "moduleForComponent", 29 | "moduleForModel", 30 | "process", 31 | "expect", 32 | "visit", 33 | "exists", 34 | "fillIn", 35 | "click", 36 | "keyEvent", 37 | "triggerEvent", 38 | "find", 39 | "findWithAssert", 40 | "wait", 41 | "DS", 42 | "isolatedContainer", 43 | "startApp", 44 | "andThen", 45 | "currentURL", 46 | "currentPath", 47 | "currentRouteName" 48 | ], 49 | "node": false, 50 | "browser": false, 51 | "boss": true, 52 | "curly": false, 53 | "debug": false, 54 | "devel": false, 55 | "eqeqeq": true, 56 | "evil": true, 57 | "forin": false, 58 | "immed": false, 59 | "laxbreak": false, 60 | "newcap": true, 61 | "noarg": true, 62 | "noempty": false, 63 | "nonew": false, 64 | "nomen": false, 65 | "onevar": false, 66 | "plusplus": false, 67 | "regexp": false, 68 | "undef": true, 69 | "sub": true, 70 | "strict": false, 71 | "white": false, 72 | "eqnull": true, 73 | "esnext": true 74 | } 75 | -------------------------------------------------------------------------------- /test-support/helpers/betamax-recorder.js: -------------------------------------------------------------------------------- 1 | import { 2 | getServer 3 | } from './fake-server'; 4 | 5 | var responses = [], strings = []; 6 | var allResponseUrls = []; 7 | 8 | //turning headers into js is a real pain 9 | function parseResponseHeaders(headerStr) { 10 | var headers = {}; 11 | if (!headerStr) { 12 | return headers; 13 | } 14 | var headerPairs = headerStr.split('\u000d\u000a'); 15 | for (var i = 0; i < headerPairs.length; i++) { 16 | var headerPair = headerPairs[i]; 17 | var index = headerPair.indexOf('\u003a\u0020'); 18 | if (index > 0) { 19 | var key = headerPair.substring(0, index); 20 | var val = headerPair.substring(index + 2); 21 | headers[key] = val; 22 | } 23 | } 24 | return headers; 25 | } 26 | 27 | export default { 28 | setup: function() { 29 | var server = getServer(); 30 | server.responses.mapBy('url').forEach(function(response) { 31 | allResponseUrls[response] = true; 32 | }); 33 | 34 | //listen to incoming xhr requests 35 | $( document ).ajaxSuccess(function( event, xhr, settings ) { 36 | var url = settings.url; 37 | var newResponse = { 38 | url: url, 39 | data: xhr.responseText, 40 | type: settings.type, 41 | status: xhr.status, 42 | headers: parseResponseHeaders(xhr.getAllResponseHeaders()) 43 | }; 44 | //if response isn't in old or new cassettes, add it to new one 45 | if(!allResponseUrls[url]) { 46 | responses.push(newResponse); 47 | allResponseUrls[newResponse.url] = true; 48 | 49 | //ensure that if a request is added to new cassette, it 50 | //doesn't hit the server again 51 | server.respondWith( 52 | settings.type, newResponse.url, 53 | [ 54 | newResponse.status, 55 | newResponse.headers, 56 | JSON.stringify(JSON.parse(newResponse.data)) 57 | ] 58 | ); 59 | } 60 | }); 61 | }, 62 | 63 | download: function() { 64 | //convert responses into string expected by sinon 65 | strings.push("export default function(server) {\n\n"); 66 | if (responses.length > 0){ 67 | responses.forEach(function(response) { 68 | strings.push("server.respondWith( '"+ response.type + "', \n"); 69 | strings.push("'" + response.url + "',\n"); 70 | strings.push(" [\n " + response.status + ",\n"); 71 | strings.push(JSON.stringify(response.headers) + ",\n"); 72 | strings.push(JSON.stringify(JSON.stringify(JSON.parse(response.data))) + "\n"); 73 | strings.push("]);\n\n"); 74 | }); 75 | 76 | strings.push("}"); 77 | //html 5 for downloading recordings 78 | var blob = new window.Blob(strings); 79 | var encodedUri = window.URL.createObjectURL(blob); 80 | var link = document.createElement("a"); 81 | link.setAttribute("href", encodedUri); 82 | link.setAttribute("download", "cassette.js"); 83 | link.click(); 84 | 85 | //ensure that users knows about the new cassette 86 | window.alert("Missing recorded data. New cassette recorded"); 87 | } 88 | this.reset(); 89 | }, 90 | 91 | reset: function(){ 92 | responses = []; 93 | strings = []; 94 | } 95 | }; 96 | 97 | 98 | --------------------------------------------------------------------------------