Skip to content
This repository has been archived by the owner on Feb 12, 2022. It is now read-only.

Add code coverage to QUnit tests #1124

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 106 additions & 77 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,33 @@ module.exports = function (grunt) {
sauceLoginFile: grunt.file.exists('SAUCE_API_KEY.yml') ? grunt.file.readYAML('SAUCE_API_KEY.yml') : undefined,
sauceUser: process.env.SAUCE_USERNAME || 'fuelux',
sauceKey: process.env.SAUCE_ACCESS_KEY ? process.env.SAUCE_ACCESS_KEY : '<%= sauceLoginFile.key %>',
allTestUrls: ['2.1.0', '1.11.0', '1.9.1', 'browserGlobals'].map(function (ver) {
if (ver === 'browserGlobals') {
return 'http://localhost:<%= connect.testServer.options.port %>/test/fuelux-browser-globals.html';
// TEST URLS
allTestUrls: ['2.1.0', '1.11.0', '1.9.1', 'browserGlobals', 'noMoment', 'codeCoverage' ].map(function (type) {
if (type === 'browserGlobals') {
return 'http://localhost:<%= connect.testServer.options.port %>/test/browser-globals.html';
}
else if (type === 'codeCoverage') {
return 'http://localhost:<%= connect.testServer.options.port %>/test/?coverage=true';
}
else if (type === 'noMoment') {
return 'http://localhost:<%= connect.testServer.options.port %>/test/?no-moment=true';
}
else {
// test dist with multiple jQuery versions
return 'http://localhost:<%= connect.testServer.options.port %>/test/?testdist=true';
}

return 'http://localhost:<%= connect.testServer.options.port %>/test/fuelux.html?jquery=' + ver + '&testdist=true';
}),
testUrl: ['http://localhost:<%= connect.testServer.options.port %>/test/fuelux.html?jquery=' + '1.9.1&testdist=true'],

//Tasks configuration
blanket_qunit: {
source: {
options: {
urls: ['http://localhost:<%= connect.testServer.options.port %>/test/?coverage=true&gruntReport'],
threshold: 1,
globalThreshold: 1
}
}
},
clean: {
dist: ['dist'],
zipsrc: ['dist/fuelux'],// temp folder
Expand Down Expand Up @@ -126,14 +143,26 @@ module.exports = function (grunt) {
server: {
options: {
hostname: '*',
base: {
path: '.',
options: {
index: ['index.html', 'tests.html'],
}
},
port: process.env.PORT || 8000,
useAvailablePort: true// increment port number, if unavailable...
useAvailablePort: true // increment port number, if unavailable...
}
},
testServer: {
options: {
base: {
path: '.',
options: {
index: ['index.html', 'tests.html'],
}
},
hostname: '*',
port: 9000,// allows main server to be run simultaneously
port: 9000, // allows main server to be run simultaneously
useAvailablePort: true// increment port number, if unavailable...
}
}
Expand Down Expand Up @@ -196,7 +225,7 @@ module.exports = function (grunt) {
undef: true,
unused: false// changed
},
source: ['Gruntfile.js', 'js/*.js', 'dist/fuelux.js'],
sourceAndDist: ['Gruntfile.js', 'js/*.js', 'dist/fuelux.js'],
tests: {
options: {
latedef: false,
Expand All @@ -210,7 +239,7 @@ module.exports = function (grunt) {
},
qunit: {
//run with `grunt releasetest` or `grunt travisci`. Requires connect server to be running.
full: {
release: {
options: {
urls: '<%= allTestUrls %>',
screenshot: true,
Expand All @@ -222,11 +251,25 @@ module.exports = function (grunt) {
}
}
},
//can be run with `grunt qunit:simple`
simple: ['test/*.html'],
globals: {
options: {
urls: ['http://localhost:<%= connect.testServer.options.port %>/test/browser-globals.html']
}
},
noMoment: {
options: {
urls: ['http://localhost:<%= connect.testServer.options.port %>/test/?no-moment=true']
}
},
// `grunt qunit:source` will test the source files directly.
source: {
options: {
urls: ['http://localhost:<%= connect.testServer.options.port %>/test/']
}
},
dist: {
options: {
urls: ['http://localhost:<%= connect.server.options.port %>/test/fuelux.html?testdist=true']
urls: ['http://localhost:<%= connect.testServer.options.port %>/test/?testdist=true']
}
}
},
Expand Down Expand Up @@ -297,29 +340,7 @@ module.exports = function (grunt) {
var valid = semver.valid(value);
return valid || 'Must be a valid semver, such as 1.2.3-rc1. See http://semver.org/ for more details.';
}
}//,
// {
// config: 'bump.files',
// type: 'checkbox',
// message: 'What should get the new version:',
// choices: [
// {
// value: 'package',
// name: 'package.json' + (!grunt.file.isFile('package.json') ? ' not found, will create one' : ''),
// checked: grunt.file.isFile('package.json')
// },
// {
// value: 'bower',
// name: 'bower.json' + (!grunt.file.isFile('bower.json') ? ' not found, will create one' : ''),
// checked: grunt.file.isFile('bower.json')
// },
// {
// value: 'git',
// name: 'git tag',
// checked: grunt.file.isDir('.git')
// }
// ]
// }
}
]
}
}
Expand All @@ -345,7 +366,7 @@ module.exports = function (grunt) {
browsers: grunt.file.readYAML('sauce_browsers_tricky.yml'),
build: process.env.TRAVIS_BUILD_NUMBER || '<%= pkg.version %>',
testname: process.env.TRAVIS_JOB_ID || Math.floor((new Date()).getTime() / 1000 - 1230768000).toString(),
urls: '<%= testUrl %>'
urls: ['http://localhost:<%= connect.testServer.options.port %>/test/?testdist=true']
}
},
defaultBrowsers: {
Expand All @@ -358,7 +379,7 @@ module.exports = function (grunt) {
browsers: grunt.file.readYAML('sauce_browsers.yml'),
build: process.env.TRAVIS_BUILD_NUMBER || '<%= pkg.version %>',
testname: process.env.TRAVIS_JOB_ID || '<%= pkg.version %>-<%= grunt.template.today("dddd, mmmm dS, yyyy, h:MM:ss TT") %>',
urls: '<%= testUrl %>',
urls: ['http://localhost:<%= connect.testServer.options.port %>/test/?testdist=true'],
maxPollRetries: 4,
throttled: 3,
maxRetries: 3
Expand Down Expand Up @@ -422,19 +443,19 @@ module.exports = function (grunt) {
watch: {
//watch everything and test everything (test dist)
full: {
files: ['Gruntfile.js', 'fonts/**', 'js/**', 'less/**', 'lib/**', 'test/**', 'index.html', 'dev.html'],
files: ['Gruntfile.js', 'fonts/**', 'js/**', 'less/**', 'test/**', 'index.html', 'dev.html'],
options: {
livereload: isLivereloadEnabled
},
tasks: ['jshint', 'dist', 'qunit:dist', 'validation']
tasks: ['jshint', 'blanket_qunit:source', 'qunit:noMoment', 'qunit:globals', 'dist', 'qunit:dist', 'validation']
},
//watch everything but only perform simple qunit tests (don't test dist)
simple: {
files: ['Gruntfile.js', 'fonts/**', 'js/**', 'less/**', 'lib/**', 'test/**', 'index.html', 'dev.html'],
//watch everything but only perform source qunit tests (don't test dist)
source: {
files: ['Gruntfile.js', 'fonts/**', 'js/**', 'less/**', 'test/**', 'index.html', 'dev.html'],
options: {
livereload: isLivereloadEnabled
},
tasks: ['jshint', 'qunit:simple', 'validation']
tasks: ['jshint', 'connect:testServer', 'blanket_qunit:source', 'qunit:noMoment', 'qunit:globals', 'validation']
},
//only watch and dist less, useful when doing LESS/CSS work
less: {
Expand Down Expand Up @@ -469,7 +490,6 @@ module.exports = function (grunt) {
});



/* -------------
BUILD
------------- */
Expand All @@ -487,9 +507,6 @@ module.exports = function (grunt) {
grunt.file.delete('less/fuelux-no-namespace.less', options);
});




// ZIP distribution task
grunt.registerTask('distzip', 'Compress and zip "dist"', ['copy:zipsrc', 'compress', 'clean:zipsrc']);

Expand All @@ -501,25 +518,32 @@ module.exports = function (grunt) {
TESTS
------------- */
// The default build task
grunt.registerTask('default', 'Run simple tests. Pass --no-resetdist to keep dist changes from being wiped out', ['test', 'clean:screenshots', 'resetdist']);
grunt.registerTask('default', 'Run source file tests. Pass --no-resetdist to keep "dist" changes from being wiped out',
['test', 'clean:screenshots', 'resetdist']);

// to be run prior to submitting a PR
grunt.registerTask('test', 'run jshint, qunit:simple, and validate HTML', ['jshint', 'qunit:simple', 'validation']);
grunt.registerTask('test', 'run jshint, qunit source w/ coverage, and validate HTML',
['jshint', 'connect:testServer', 'blanket_qunit:source', 'qunit:noMoment', 'qunit:globals', 'validation']);

//If qunit:simple is working but qunit:full is breaking, check to see if the dist broke the code. This would be especially useful if we start mangling our code, but, is 99.99% unlikely right now
grunt.registerTask('validate-dist', 'run qunit:simple, dist, and then qunit:full', ['connect:testServer', 'qunit:simple', 'dist', 'qunit:full']);
//If qunit:source is working but qunit:full is breaking, check to see if the dist broke the code. This would be especially useful if we start mangling our code, but, is 99.99% unlikely right now
grunt.registerTask('validate-dist', 'run qunit:source, dist, and then qunit:full',
['connect:testServer', 'qunit:source', 'dist', 'qunit:dist']);

// multiple jquery versions, then run SauceLabs VMs
grunt.registerTask('releasetest', 'run jshint, dist, qunit:full, validation, and qunit on saucelabs', ['connect:testServer', 'jshint', 'qunit:simple', 'dist', 'qunit:full', 'validation', 'saucelabs-qunit:defaultBrowsers']);
// multiple jQuery versions, then run SauceLabs VMs
grunt.registerTask('releasetest', 'run jshint, build dist, all source tests, validation, and qunit on SauceLabs',
['test', 'dist', 'qunit:dist', 'saucelabs-qunit:defaultBrowsers']);

// can be run locally instead of through TravisCI, but requires the Fuel UX Saucelabs API key file which is not public at this time.
grunt.registerTask('saucelabs', 'run jshint, and qunit on saucelabs', ['connect:testServer', 'jshint', 'saucelabs-qunit:defaultBrowsers']);
grunt.registerTask('saucelabs', 'run jshint, and qunit on saucelabs',
['connect:testServer', 'jshint', 'saucelabs-qunit:defaultBrowsers']);

// can be run locally instead of through TravisCI, but requires the FuelUX Saucelabs API key file which is not public at this time.
grunt.registerTask('trickysauce', 'run tests, jshint, and qunit for "tricky browsers" (IE8-11)', ['connect:testServer', 'jshint', 'saucelabs-qunit:trickyBrowsers']);
grunt.registerTask('trickysauce', 'run tests, jshint, and qunit for "tricky browsers" (IE8-11)',
['connect:testServer', 'jshint', 'saucelabs-qunit:trickyBrowsers']);

// Travis CI task. This task no longer uses SauceLabs. Please run 'grunt saucelabs' manually.
grunt.registerTask('travisci', 'Tests to run when in Travis CI environment', ['connect:testServer', 'jshint', 'qunit:simple', 'dist', 'qunit:full']);
grunt.registerTask('travisci', 'Tests to run when in Travis CI environment',
['test', 'dist', 'qunit:dist']);

//if you've already accidentally added your files for commit, this will at least unstage them. If you haven't, this will wipe them out.
grunt.registerTask('resetdist', 'resets changes to dist to keep them from being checked in', function () {
Expand All @@ -546,65 +570,70 @@ module.exports = function (grunt) {

if (!grunt.option('no-tests')) {
grunt.task.run(['releasetest']);
//delete any screenshots that may have happened if it got this far. This isn't foolproof because it relies on the phantomjs server/page timeout, which can take longer than this grunt task depending on how long saucelabs takes to run...
// Delete any screenshots that may have happened if it got this far. This isn't foolproof

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's up with splitting this onto multiple lines?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't read it. It went off the page. I don't have line wrap on, do you? I thought we typically tried to keep code to 80 characters, so it doesn't wrap. I looked into the styleguide and didn't see any mention of line length. Maybe we we should add a recommendation?

The 80 standard length due to IBM punch cards, but in magazines articles, for instance, I don't think columns are supposed to be over 9 words for readability. You also have to scroll within this GH interface and on your phone farther.

http://stackoverflow.com/questions/903754/do-you-still-limit-line-length-in-code

// because it relies on the phantomjs server/page timeout, which can take longer than this
// grunt task depending on how long saucelabs takes to run...
grunt.task.run('clean:screenshots');
}

grunt.config('banner', '<%= bannerRelease %>');
//make sure we run dist again to grab the latest version numbers. Yeah, we're running it twice... ¯\_(ツ)_/¯
// Run dist again to grab the latest version numbers. Yeah, we're running it twice... ¯\_(ツ)_/¯
grunt.task.run(['bump-only:' + grunt.config('bump.increment'), 'replace:readme', 'dist']);
});


/* -------------
SERVE
------------- */
//most basic serve task, it's the safest, but also the slowest.
grunt.registerTask('serve', 'Serve the files. --no-test to skip tests', function () {
//default --test=true
if (typeof grunt.option('test') === "undefined") {
grunt.option('test', true);
}
// default serve task that runs tests and builds and tests dist by default.
grunt.registerTask('serve', 'Test, build, serve files. (~20s)', function () {
var tasks = ['test', 'servedist'];
grunt.task.run(tasks);
});

grunt.task.run(['servedist']);
// default serve task that runs tests and builds and tests dist by default (~20s).
grunt.registerTask('serveslow', 'Serve files. Run all tests. Does not build. (~20s)', function () {
var tasks = ['connect:server', 'test', 'watch:source'];
grunt.task.run(tasks);
});

//Fastest serve command for freely slinging code (you won't get interrupted by tests, etc).
grunt.registerTask('servefast', 'Serve the files. pass --test to run tests.', function () {
//Fastest serve command for freely slinging code (no tests will run by default).
grunt.registerTask('servefast', 'Serve the files (no watch), --test to run minimal tests. (~0s)', function () {
grunt.task.run(['connect:server']);

if (grunt.option('test')) {
grunt.task.run(['qunit:simple', 'watch:simple']);
grunt.task.run(['connect:testServer', 'qunit:source', 'watch:source']);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did this switch to the testServer?

} else {
grunt.task.run(['watch:lite']);
}
});

//Fastest serve command when you're working on LESS
grunt.registerTask('serveless', 'Compile LESS and serve the files. pass --tests to run test.', function () {
// Fastest serve command when you're working on LESS
grunt.registerTask('serveless', 'Compile LESS and serve the files. pass --tests to run test. (~3s)', function () {
grunt.task.run(['distcss']);

if (grunt.option('test')) {
//add qunit:simple as a watch task for watch:less since they want tests
// add qunit:source as a watch task for watch:less since they want tests
grunt.config.merge({
watch: {
less: {
tasks: ['qunit:simple']
tasks: ['qunit:source']
}
}
});
grunt.task.run(['qunit:simple']);
grunt.task.run(['qunit:source']);
}

grunt.task.run(['connect:server', 'watch:less']);
});

//basically just `grunt serve` but tests default to being off
grunt.registerTask('servedist', 'Compile and serve everything, pass --test to run tests.', function () {
// same as `grunt serve` but tests default to being off
grunt.registerTask('servedist', 'Compile and serve everything, pass --test to run tests. (~7s)', function () {
grunt.task.run(['dist']);

//start up the server here so we can run tests if appropriate
//start up the servers here so we can run tests if appropriate
grunt.task.run(['connect:server']);
grunt.task.run(['connect:testServer']);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why start two servers? Which one is supposed to be the one the files are serving from for development? Will both serve all the same files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they will. Here's were I made the change. If my memory serves me right, I think it had something to do with SauceLabs. Maybe the tunneling was blocking the main server, so the testServer was set up so you can serve at the same time, since saucelabs takes so long? I'll need to look into it some more to make sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm thinking that was reason. It means you can use :8000 for working on the project while you are sending it to Saucelabs. This decision was made when were doing regular testing of IE8 via Saucelabs and did not use the useAvailablePort: true setting.

We can probably sunset the testServer for this "serving parallel servers of the same repos" edge case, but we may want to tell people to check your connect server port (as in it might be 8001 instead.) Here is a screenshot of the context below:

screen shot 2015-02-24 at 11 02 55 am


if (grunt.option('test')) {
grunt.task.run(['qunit:dist', 'watch:full']);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<link rel="stylesheet" href="../bower_components/qunit/qunit/qunit.css" media="screen">
</head>
<body>
<h1 id="qunit-header">Fuel UX Test Suite</h1>
<h1 id="qunit-header">Fuel UX Global Variable Test Suite</h1>

<h2 id="qunit-banner"></h2>

Expand Down Expand Up @@ -45,7 +45,7 @@ <h2 id="qunit-userAgent"></h2>
<script src="../js/scheduler.js"></script>

<!-- Test -->
<script src="fuelux-browser-globals.js"></script>
<script src="browser-globals.js"></script>

</body>
</html>
File renamed without changes.
12 changes: 3 additions & 9 deletions test/datepicker-moment-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ define(function(require){
var html = require('text!test/markup/datepicker-markup.html');

require('bootstrap');
require('moment');
require('fuelux/datepicker');

require('test/datepicker-test'); //this ensures the non-moment tests run before the moment tests
// require('test/datepicker-test'); //this ensures the non-moment tests run before the moment tests

function uaMatch(ua){
ua = ua.toLowerCase();
Expand Down Expand Up @@ -38,14 +39,7 @@ define(function(require){
//IE 8 & 9 have problems with the moment switching. Figure a way around this later, if possible. Otherwise, just
//test manually by commenting this if statement out and refreshing over and over again.
if(runTestsBoolean){
module('Fuel UX Datepicker with moment.js', {
setup: function(){
window.moment = window.tmpMoment;
},
teardown: function(){
window.moment = undefined;
}
});
module('Fuel UX Datepicker with moment.js');

test("should be defined on jquery object", function () {
ok($().datepicker, 'datepicker method is defined');
Expand Down
Loading