Browse Source

Adds test coverage for all of javascript modules

pull/258/head
jlukic 11 years ago
parent
commit
639ee62b78
33 changed files with 516 additions and 178 deletions
  1. 26
      Gruntfile.js
  2. 3
      karma.conf.js
  3. 1
      package.json
  4. 1
      src/modules/accordion.js
  5. 7
      src/modules/dimmer.js
  6. 35
      src/modules/dropdown.js
  7. 5
      src/modules/popup.js
  8. 15
      src/modules/rating.js
  9. 3
      src/modules/tab.js
  10. 2
      src/modules/transition.js
  11. 8
      src/modules/video.js
  12. 24
      test/fixtures/accordion.html
  13. 46
      test/fixtures/checkbox.html
  14. 9
      test/fixtures/dropdown.html
  15. 8
      test/fixtures/popup.html
  16. 7
      test/fixtures/rating.html
  17. 7
      test/fixtures/shape.html
  18. 25
      test/fixtures/sidebar.html
  19. 8
      test/fixtures/tab.html
  20. 1
      test/fixtures/transition.html
  21. 5
      test/fixtures/video.html
  22. 10
      test/modules/accordion.spec.js
  23. 8
      test/modules/checkbox.spec.js
  24. 8
      test/modules/dropdown.spec.js
  25. 150
      test/modules/modal.spec.js
  26. 215
      test/modules/module.spec.js
  27. 8
      test/modules/popup.spec.js
  28. 8
      test/modules/search.spec.js
  29. 8
      test/modules/shape.spec.js
  30. 8
      test/modules/sidebar.spec.js
  31. 9
      test/modules/tab.spec.js
  32. 8
      test/modules/transition.spec.js
  33. 8
      test/modules/video.spec.js

26
Gruntfile.js

@ -16,7 +16,11 @@ module.exports = function(grunt) {
// copies examples over to docs
'copy:examplesToDocs'
],
testWatchTasks = [
'clear',
'karma:watch:run'
],
testTasks = [
@ -86,6 +90,24 @@ module.exports = function(grunt) {
'copy:buildToDocs'
],
setWatchTests = function(action, filePath) {
var
karmaFiles = grunt.config('karma.watch.files'),
isJavascript = (filePath.search('.js') !== -1),
isModule = (filePath.search('modules/') !== -1),
isSpec = (filePath.search('.spec') !== -1),
specFile = (isSpec)
? filePath
: filePath
.replace('src/', 'test/')
.replace('.js', '.spec.js')
;
if(isJavascript && (isSpec || isModule) ) {
karmaFiles.pop();
karmaFiles.push(specFile);
}
},
setWatchFiles = function(action, filePath) {
var
buildPath = filePath.replace('src/', 'docs/build/').replace('less', 'css')
@ -126,7 +148,7 @@ module.exports = function(grunt) {
'test/**/*.js',
'src/**/*.js'
],
tasks : ['clear', 'karma:test:run']
tasks : testWatchTasks
},
src: {
files: [
@ -149,7 +171,7 @@ module.exports = function(grunt) {
},
karma: {
test: {
watch: {
configFile : 'karma.conf.js',
background : true
},

3
karma.conf.js

@ -23,10 +23,11 @@ module.exports = function(config) {
// require fixtures
{
pattern : 'test/fixtures/*.html',
watched : true,
included : false,
served : true
},
// require spec
'test/modules/module.spec.js',
// require tests
'test/modules/*.js'
],

1
package.json

@ -40,7 +40,6 @@
"karma-phantomjs-launcher": "~0.1.0",
"karma": "~0.10.2",
"grunt-karma": "~0.6.2",
"karma-coverage": "~0.1.0",
"karma-spec-reporter": "0.0.5",
"grunt-clear": "~0.2.1"
}

1
src/modules/accordion.js

@ -60,6 +60,7 @@ $.fn.accordion = function(parameters) {
},
instantiate: function() {
instance = module;
$module
.data(moduleNamespace, module)
;

7
src/modules/dimmer.js

@ -45,12 +45,12 @@ $.fn.dimmer = function(parameters) {
? 'touchstart'
: 'click',
$module = $(this),
$module = $(this),
$dimmer,
$dimmable,
element = this,
instance = $module.data(moduleNamespace),
element = this,
instance = $module.data(moduleNamespace),
module
;
@ -118,6 +118,7 @@ $.fn.dimmer = function(parameters) {
.off(eventNamespace)
;
$dimmer
.remove()
.off(eventNamespace)
;
},

35
src/modules/dropdown.js

@ -33,26 +33,26 @@ $.fn.dropdown = function(parameters) {
? $.extend(true, {}, $.fn.dropdown.settings, parameters)
: $.extend({}, $.fn.dropdown.settings),
className = settings.className,
metadata = settings.metadata,
namespace = settings.namespace,
selector = settings.selector,
error = settings.error,
className = settings.className,
metadata = settings.metadata,
namespace = settings.namespace,
selector = settings.selector,
error = settings.error,
eventNamespace = '.' + namespace,
dropdownNamespace = 'module-' + namespace,
isTouchDevice = ('ontouchstart' in document.documentElement),
eventNamespace = '.' + namespace,
moduleNamespace = 'module-' + namespace,
isTouchDevice = ('ontouchstart' in document.documentElement),
$module = $(this),
$item = $module.find(selector.item),
$text = $module.find(selector.text),
$input = $module.find(selector.input),
$module = $(this),
$item = $module.find(selector.item),
$text = $module.find(selector.text),
$input = $module.find(selector.input),
$menu = $module.children(selector.menu),
$menu = $module.children(selector.menu),
element = this,
instance = $module.data(dropdownNamespace),
element = this,
instance = $module.data(moduleNamespace),
module
;
@ -94,8 +94,9 @@ $.fn.dropdown = function(parameters) {
instantiate: function() {
module.verbose('Storing instance of dropdown', module);
instance = module;
$module
.data(dropdownNamespace, module)
.data(moduleNamespace, module)
;
},
@ -106,7 +107,7 @@ $.fn.dropdown = function(parameters) {
;
$module
.off(eventNamespace)
.removeData(dropdownNamespace)
.removeData(moduleNamespace)
;
},

5
src/modules/popup.js

@ -41,7 +41,7 @@ $.fn.popup = function(parameters) {
namespace = settings.namespace,
eventNamespace = '.' + settings.namespace,
moduleNamespace = settings.namespace + '-module',
moduleNamespace = 'module-' + namespace,
$module = $(this),
@ -98,6 +98,9 @@ $.fn.popup = function(parameters) {
destroy: function() {
module.debug('Destroying previous module');
$window
.off(eventNamespace)
;
$module
.off(eventNamespace)
.removeData(moduleNamespace)

15
src/modules/rating.js

@ -27,7 +27,9 @@ $.fn.rating = function(parameters) {
$allModules
.each(function() {
var
settings = $.extend(true, {}, $.fn.rating.settings, parameters),
settings = ( $.isPlainObject(parameters) )
? $.extend(true, {}, $.fn.rating.settings, parameters)
: $.extend({}, $.fn.rating.settings),
namespace = settings.namespace,
className = settings.className,
@ -38,11 +40,12 @@ $.fn.rating = function(parameters) {
eventNamespace = '.' + namespace,
moduleNamespace = 'module-' + namespace,
element = this,
instance = $(this).data(moduleNamespace),
$module = $(this),
$icon = $module.find(selector.icon),
element = this,
instance = $module.data(moduleNamespace),
module
;
@ -71,12 +74,14 @@ $.fn.rating = function(parameters) {
instantiate: function() {
module.verbose('Instantiating module', settings);
instance = module;
$module
.data(moduleNamespace, module)
;
},
destroy: function() {
module.verbose('Destroying previous instance', instance);
$module
.removeData(moduleNamespace)
;
@ -274,6 +279,9 @@ $.fn.rating = function(parameters) {
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
if($allModules.size() > 1) {
title += ' ' + '(' + $allModules.size() + ')';
}
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
@ -343,7 +351,6 @@ $.fn.rating = function(parameters) {
return found;
}
};
if(methodInvoked) {
if(instance === undefined) {
module.initialize();

3
src/modules/tab.js

@ -38,7 +38,7 @@
error = settings.error,
eventNamespace = '.' + settings.namespace,
moduleNamespace = settings.namespace + '-module',
moduleNamespace = 'module-' + settings.namespace,
instance = $module.data(moduleNamespace),
@ -103,6 +103,7 @@
destroy: function() {
module.debug('Destroying tabs', $module);
$module
.removeData(moduleNamespace)
.off(eventNamespace)
;
},

2
src/modules/transition.js

@ -314,7 +314,7 @@ $.fn.transition = function() {
animation : animation
});
}
return $.fn.transition.settings;
return $.extend({}, $.fn.transition.settings);
},
animationName: function() {

8
src/modules/video.js

@ -41,7 +41,7 @@ $.fn.video = function(parameters) {
namespace = settings.namespace,
eventNamespace = '.' + namespace,
moduleNamespace = namespace + '-module',
moduleNamespace = 'module-' + namespace,
$module = $(this),
$placeholder = $module.find(selector.placeholder),
@ -80,6 +80,12 @@ $.fn.video = function(parameters) {
.removeData(moduleNamespace)
.off(eventNamespace)
;
$placeholder
.off(eventNamespace)
;
$playButton
.off(eventNamespace)
;
},
// sets new video

24
test/fixtures/accordion.html

@ -0,0 +1,24 @@
<div class="ui accordion">
<div class="active title">
<i class="dropdown icon"></i>
What is a dog?
</div>
<div class="active content">
<p>A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world.</p>
</div>
<div class="title">
<i class="dropdown icon"></i>
What kinds of dogs are there?
</div>
<div class="content">
<p>There are many breeds of dogs. Each breed varies in size and temperament. Owners often select a breed of dog that they find to be compatible with their own lifestyle and desires from a companion.</p>
</div>
<div class="title">
<i class="dropdown icon"></i>
How do you acquire a dog?
</div>
<div class="content">
<p>Three common ways for a prospective owner to acquire a dog is from pet shops, private owners, or shelters.</p>
<p>A pet shop may be the most convenient way to buy a dog. Buying a dog from a private owner allows you to assess the pedigree and upbringing of your dog before choosing to take it home. Lastly, finding your dog from a shelter, helps give a good home to a dog who may not find one so readily.</p>
</div>
</div>

46
test/fixtures/checkbox.html

@ -0,0 +1,46 @@
<div class="ui form">
<div class="grouped inline fields">
<div class="field">
<div class="ui radio checkbox">
<input type="radio" name="fruit" checked="checked" />
<label>Apples</label>
</div>
</div>
<div class="field">
<div class="ui radio checkbox">
<input type="radio" name="fruit" />
<label>Oranges</label>
</div>
</div>
<div class="field">
<div class="ui radio checkbox">
<input type="radio" name="fruit" />
<label>Pears</label>
</div>
</div>
<div class="field">
<div class="ui radio checkbox">
<input type="radio" name="fruit" />
<label>Grapefruit</label>
</div>
</div>
</div>
<div class="field">
<div class="ui checkbox">
<input type="checkbox">
<label>Poodle</label>
</div>
</div>
<div class="field">
<div class="ui toggle checkbox">
<input type="checkbox" name="pet" />
<label>Allow other people to pet my dog</label>
</div>
</div>
<div class="field">
<div class="ui slider checkbox">
<input type="checkbox" name="pet" />
<label>Allow other people to pet my dog</label>
</div>
</div>
</div>

9
test/fixtures/dropdown.html

@ -0,0 +1,9 @@
<div class="ui selection dropdown">
<input type="hidden" name="gender">
<i class="dropdown icon"></i>
<div class="default text">Gender</div>
<div class="menu">
<div class="item" data-value="male">Male</div>
<div class="item" data-value="female">Female</div>
</div>
</div>

8
test/fixtures/popup.html

@ -0,0 +1,8 @@
<i class="circular heart icon link" data-content="Top Left" data-position="top left"></i>
<i class="circular heart icon link" data-content="Top Center" data-position="top center"></i>
<i class="circular heart icon link" data-content="Top Right" data-position="top right"></i>
<i class="circular heart icon link" data-content="Left Center" data-position="left center"></i>
<i class="circular heart icon link" data-content="Right Center" data-position="right center"></i>
<i class="circular heart icon link" data-content="Bottom Left" data-position="bottom left"></i>
<i class="circular heart icon link" data-content="Bottom Center" data-position="bottom center"></i>
<i class="circular heart icon link" data-content="Bottom Right" data-position="bottom right"></i>

7
test/fixtures/rating.html

@ -0,0 +1,7 @@
<div class="ui star rating">
<i class="icon"></i>
<i class="icon"></i>
<i class="icon"></i>
<i class="icon"></i>
<i class="icon"></i>
</div>

7
test/fixtures/shape.html

@ -0,0 +1,7 @@
<div class="ui shape">
<div class="sides">
<div class="active side">This side is visible.</div>
<div class="side">This side is not visible.</div>
<div class="side">This side is not visible.</div>
</div>
</div>

25
test/fixtures/sidebar.html

@ -0,0 +1,25 @@
<div class="ui red vertical demo sidebar menu">
<a class="item">
<i class="home icon"></i>
Home
</a>
<a class="active item">
<i class="heart icon"></i>
Current Section
</a>
<a class="item">
<i class="facebook icon"></i>
Like us on Facebook
</a>
<div class="item">
<b>More</b>
<div class="menu">
<a class="item">About</a>
<a class="item">Contact Us</a>
</div>
</div>
</div>
<div class="ui disabled teal toggle button">
<i class="left arrow icon"></i>
Trigger Sidebar
</div>

8
test/fixtures/tab.html

@ -0,0 +1,8 @@
<div class="ui menu">
<a class="active item" data-tab="first">First</a>
<a class="item" data-tab="second">Second</a>
<a class="item" data-tab="third">Third</a>
</div>
<div class="ui active tab segment" data-tab="first">First</div>
<div class="ui tab segment" data-tab="second">Second</div>
<div class="ui tab segment" data-tab="third">Third</div>

1
test/fixtures/transition.html

@ -0,0 +1 @@
<div class="ui image"></div>

5
test/fixtures/video.html

@ -0,0 +1,5 @@
<div class="ui video">
<div class="play"></div>
<div class="placeholder"></div>
<div class="embed"></div>
</div>

10
test/modules/accordion.spec.js

@ -0,0 +1,10 @@
describe("UI Accordion", function() {
$.fn.dimmer.settings.debug = false;
moduleTests({
module : 'accordion',
element : '.ui.accordion'
});
});

8
test/modules/checkbox.spec.js

@ -0,0 +1,8 @@
describe("UI Checkbox", function() {
moduleTests({
module : 'checkbox',
element : '.ui.checkbox'
});
});

8
test/modules/dropdown.spec.js

@ -0,0 +1,8 @@
describe("UI Dropdown", function() {
moduleTests({
module : 'dropdown',
element : '.ui.dropdown'
});
});

150
test/modules/modal.spec.js

@ -1,152 +1,10 @@
describe("UI Modal", function() {
var
module = 'modal',
testValue = 'Test',
name = module.charAt(0).toUpperCase() + module.slice(1),
fixtures = jasmine.getFixtures(),
$module
;
fixtures.fixturesPath = 'base/test/fixtures/';
beforeEach(function() {
// load fixtures
fixtures.load(module + '.html');
// disable debug
$.fn[module].debug = false;
// module available in scope
$module = $('.ui.'+ module);
});
afterEach(function() {
$('.ui.'+ module).remove();
});
/*******************************
Module
*******************************/
/*-------------------
Instantiation
--------------------*/
it("should have an instance in metadata after init", function() {
$module[module]();
expect($module).toHaveData('module-' + module);
});
/*-------------------
Settings
--------------------*/
describe('Settings', function() {
it("should allow default settings to be changed", function() {
$.fn[module].settings.name = testValue;
$module[module]();
var retrievedValue = $module[module]('setting', 'name');
$.fn[module].settings.name = name;
expect(retrievedValue).toBe(testValue);
});
it("should allow settings to be changed during init", function() {
$module[module]({
name: testValue
});
var retrievedValue = $module[module]('setting', 'name');
expect(retrievedValue).toBe(testValue);
});
it("should allow settings to be changed during runtime", function() {
$module[module]();
var retrievedValue = $module[module]('setting', 'name');
expect(retrievedValue).toBe(name);
});
});
/*-------------------
Groups
--------------------*/
describe('Group Contamination', function() {
it("should create settings for all instances", function() {
$moduleClone = $module.clone().appendTo( $(sandbox() ));
$modules = $moduleClone.add($module);
$modules[module]('setting', 'name', testValue);
var retrievedValue = $module[module]('setting', 'name');
var clonedSetting = $moduleClone[module]('setting', 'name');
expect(retrievedValue).toBe(testValue);
expect(clonedSetting).toBe(testValue);
$modules[module]({
'name': testValue
});
expect(retrievedValue).toBe(testValue);
expect(clonedSetting).toBe(testValue);
});
it("should not change other elements settings when changing one element", function() {
$moduleClone = $module.clone().appendTo( $(sandbox() ));
$modules = $moduleClone.add($module);
$modules[module]();
$module[module]('setting', 'name', testValue);
var retrievedValue = $module[module]('setting', 'name');
var clonedSetting = $moduleClone[module]('setting', 'name');
expect(retrievedValue).toBe(testValue);
expect(clonedSetting).toBe(name);
});
it("should not change other elements when re-initalized", function() {
$moduleClone = $module.clone().appendTo( $(sandbox() ));
$modules = $moduleClone.add($module);
$modules[module]();
$module[module]({
'name': testValue
});
var retrievedValue = $module[module]('setting', 'name');
var clonedSetting = $moduleClone[module]('setting', 'name');
expect(retrievedValue).toBe(testValue);
expect(clonedSetting).toBe(name);
});
});
/*-------------------
Destroy
--------------------*/
describe('Destroy', function() {
it("destroy should remove all events from page", function() {
$module[module]('destroy');
expect($.events().length).toBe(0);
});
it("destroy should remove instance metadata", function() {
$module[module]('destroy');
expect( $module.data('module-'+ module) ).toBe(undefined);
});
$.fn.dimmer.settings.debug = false;
moduleTests({
module : 'modal',
element : '.ui.modal'
});
});

215
test/modules/module.spec.js

@ -0,0 +1,215 @@
function moduleTests(ui) {
var
module = ui.module,
element = ui.element,
singleton = ui.singleton,
name = $.fn[module].settings.name,
testValue = 'Test',
fixtures = jasmine.getFixtures(),
originalSettings,
$modules,
$oneModule,
$module,
$clone
;
// set fixture path
fixtures.fixturesPath = 'base/test/fixtures/';
// disable debug
$.fn[module].settings.debug = false;
$.fn[module].settings.performance = false;
$.fn[module].settings.verbose = false;
beforeEach(function() {
// load fixtures
fixtures.load(module + '.html');
// save settings
originalSettings = $.fn[module].settings;
// module available in scope
$module = $(element);
// one module available in fixture
if($module.size() == 1) {
$oneModule = $module;
$clone = $module.clone().appendTo( $(sandbox()) );
$modules = $clone.add($module);
}
// multiple modules available in fixture
else {
$modules = $(element);
$clone = $module.eq(1);
$oneModule = $modules.first();
}
});
afterEach(function() {
// restore settings
$.fn[module].settings = originalSettings;
// remove element
$(element).remove();
});
/*******************************
Module
*******************************/
/*-------------------
Instantiation
--------------------*/
describe('Module', function() {
it("allows chaining when no settings returned", function() {
var $chain = $modules[module]();
expect($chain).toExist();
expect($chain.size()).toBe($modules.size());
});
it("returns a string when one setting returned", function() {
var result = $oneModule[module]('setting', 'name');
expect(typeof result).toBe('string');
});
it("returns an array when multiple settings returned", function() {
var result = $modules[module]('setting', 'name');
expect( $.isArray(result) ).toBeTruthy();
});
it("has an instance in metadata after init", function() {
$oneModule[module]();
expect($module).toHaveData('module-' + module);
});
});
/*-------------------
Settings
--------------------*/
describe('Settings', function() {
it("clears settings on re-init", function() {
$oneModule[module]({
name: testValue
});
var retrievedValue = $oneModule[module]('setting', 'name');
expect(retrievedValue).toBe(testValue);
// reinit
$oneModule[module]();
retrievedValue = $oneModule[module]('setting', 'name');
expect(retrievedValue).toBe(name);
});
it("allows default settings to be changed", function() {
$.fn[module].settings.name = testValue;
$oneModule[module]();
var retrievedValue = $oneModule[module]('setting', 'name');
$.fn[module].settings.name = name;
expect(retrievedValue).toBe(testValue);
});
it("allows settings to be changed during init", function() {
$oneModule[module]({
name: testValue
});
var retrievedValue = $oneModule[module]('setting', 'name');
expect(retrievedValue).toBe(testValue);
});
it("allows settings to be changed during runtime", function() {
$oneModule[module]();
var retrievedValue = $oneModule[module]('setting', 'name');
expect(retrievedValue).toBe(name);
});
});
/*-------------------
Groups
--------------------*/
if(!singleton) {
describe('Group Contamination', function() {
it("creates settings for all instances", function() {
$modules[module]('setting', 'name', testValue);
var retrievedValue = $oneModule[module]('setting', 'name');
var clonedSetting = $clone[module]('setting', 'name');
expect(retrievedValue).toBe(testValue);
expect(clonedSetting).toBe(testValue);
$oneModule[module]({
'name': testValue
});
expect(retrievedValue).toBe(testValue);
expect(clonedSetting).toBe(testValue);
});
it("does not change other elements settings when changing one element", function() {
$modules[module]();
$oneModule[module]('setting', 'name', testValue);
var retrievedValue = $oneModule[module]('setting', 'name');
var clonedSetting = $clone[module]('setting', 'name');
expect(retrievedValue).toBe(testValue);
expect(clonedSetting).toBe(name);
});
it("does not change other elements when re-initalized", function() {
$modules[module]();
$oneModule[module]({
'name': testValue
});
var retrievedValue = $oneModule[module]('setting', 'name');
var clonedSetting = $clone[module]('setting', 'name');
expect(retrievedValue).toBe(testValue);
expect(clonedSetting).toBe(name);
});
});
}
/*-------------------
Destroy
--------------------*/
describe('Destroy', function() {
it("removes all events from page", function() {
$module[module]('destroy');
expect($.events().length).toBe(0);
});
it("removes instance metadata", function() {
$module[module]('destroy');
expect( $module.data('module-'+ module) ).toBe(undefined);
});
});
}

8
test/modules/popup.spec.js

@ -0,0 +1,8 @@
describe("UI Popup", function() {
moduleTests({
module : 'popup',
element : 'i.icon'
});
});

8
test/modules/search.spec.js

@ -0,0 +1,8 @@
xdescribe("UI Search", function() {
moduleTests({
module : 'search',
element : '.ui.search'
});
});

8
test/modules/shape.spec.js

@ -0,0 +1,8 @@
describe("UI Shape", function() {
moduleTests({
module : 'shape',
element : '.ui.shape'
});
});

8
test/modules/sidebar.spec.js

@ -0,0 +1,8 @@
describe("UI Rating", function() {
moduleTests({
module : 'rating',
element : '.ui.rating'
});
});

9
test/modules/tab.spec.js

@ -0,0 +1,9 @@
xdescribe("UI Tab", function() {
moduleTests({
module : 'tab',
element : '.ui.menu .item',
singleton : true
});
});

8
test/modules/transition.spec.js

@ -0,0 +1,8 @@
xdescribe("UI Transition", function() {
moduleTests({
module : 'transition',
element : '.ui.image'
});
});

8
test/modules/video.spec.js

@ -0,0 +1,8 @@
describe("UI Video", function() {
moduleTests({
module : 'video',
element : '.ui.video'
});
});
Loading…
Cancel
Save