webfontloader 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. data/CHANGELOG +9 -0
  2. data/Gemfile +2 -8
  3. data/README.md +31 -32
  4. data/Rakefile +2 -33
  5. data/docs/EVENTS.md +10 -1
  6. data/docs/MODULES.md +4 -3
  7. data/lib/webfontloader.rb +1 -1
  8. data/spec/ascender/ascenderscript_spec.js +43 -0
  9. data/spec/core/cssclassname_spec.js +42 -0
  10. data/spec/core/cssfontfamilyname_spec.js +38 -0
  11. data/spec/core/domhelper_spec.js +158 -0
  12. data/spec/core/eventdispatcher_spec.js +209 -0
  13. data/spec/core/font_spec.js +218 -0
  14. data/spec/core/fontmoduleloader_spec.js +55 -0
  15. data/spec/core/fontruler_spec.js +33 -0
  16. data/spec/core/fontvariationdescription_spec.js +67 -0
  17. data/spec/core/fontwatcher_spec.js +204 -0
  18. data/spec/core/fontwatchrunner_spec.js +398 -0
  19. data/spec/core/size_spec.js +17 -0
  20. data/spec/core/useragentparser_spec.js +921 -0
  21. data/spec/custom/customcss_spec.js +36 -0
  22. data/spec/fontdeck/fontdeckscript_spec.js +111 -0
  23. data/spec/fonts/LICENSE.txt +93 -0
  24. data/spec/fonts/nullfont.css +1 -0
  25. data/spec/fonts/nullfont1.css +1 -0
  26. data/spec/fonts/nullfont2.css +1 -0
  27. data/spec/fonts/nullfont3.css +1 -0
  28. data/spec/fonts/sourcesans.eot +0 -0
  29. data/spec/fonts/sourcesans.otf +0 -0
  30. data/spec/fonts/sourcesans.svg +2523 -0
  31. data/spec/fonts/sourcesans.ttf +0 -0
  32. data/spec/fonts/sourcesans.woff +0 -0
  33. data/spec/fonts/sourcesansa.css +1 -0
  34. data/spec/fonts/sourcesansb.css +1 -0
  35. data/spec/google/fontapiparser_spec.js +348 -0
  36. data/spec/google/fontapiurlbuilder_spec.js +40 -0
  37. data/spec/google/googlefontapi_spec.js +123 -0
  38. data/spec/google/lastresortwebkitfontwatchrunner_spec.js +145 -0
  39. data/spec/index.html +95 -0
  40. data/spec/monotype/monotypescript_spec.js +49 -0
  41. data/spec/typekit/typekitscript_spec.js +93 -0
  42. data/src/core/domhelper.js +6 -3
  43. data/src/core/fontruler.js +1 -1
  44. data/src/core/fontwatcher.js +5 -0
  45. data/src/core/fontwatchrunner.js +7 -4
  46. data/src/monotype/monotype_script.js +4 -3
  47. data/tools/jasmine-phantomjs/jasmine-phantomjs.js +26 -0
  48. data/tools/jasmine-phantomjs/terminal-reporter.js +177 -0
  49. data/tools/jasmine/MIT.LICENSE +20 -0
  50. data/tools/jasmine/jasmine-html.js +681 -0
  51. data/tools/jasmine/jasmine.css +82 -0
  52. data/tools/jasmine/jasmine.js +2600 -0
  53. data/webfontloader.gemspec +46 -25
  54. metadata +77 -42
  55. data/src-test/ascender/ascender_script_test.js +0 -51
  56. data/src-test/core/cssclassnametest.js +0 -42
  57. data/src-test/core/cssfontfamilynametest.js +0 -54
  58. data/src-test/core/domhelpertest.js +0 -151
  59. data/src-test/core/eventdispatchertest.js +0 -275
  60. data/src-test/core/fontmoduleloadertest.js +0 -30
  61. data/src-test/core/fonttest.js +0 -121
  62. data/src-test/core/fontvariationdescriptiontest.js +0 -76
  63. data/src-test/core/fontwatchertest.js +0 -287
  64. data/src-test/core/fontwatchrunnertest.js +0 -454
  65. data/src-test/core/useragenttest.js +0 -755
  66. data/src-test/custom/customcsstest.js +0 -35
  67. data/src-test/fontdeck/fontdeck_script_test.js +0 -116
  68. data/src-test/google/fontapiparsertest.js +0 -252
  69. data/src-test/google/fontapiurlbuildertest.js +0 -71
  70. data/src-test/google/googlefontapitest.js +0 -185
  71. data/src-test/google/lastresortwebkitfontwatchrunnertest.js +0 -204
  72. data/src-test/monotype/monotype_script_test.js +0 -304
  73. data/src-test/typekit/typekit_script_test.js +0 -195
  74. data/tools/jstestdriver/JsTestDriver-1.2.1.jar +0 -0
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ v1.2.1 (February 26, 2013)
2
+ * Fix the possibility of test strings wrapping to a new line and thereby breaking font watching.
3
+ * Change the FontWatchRunner to not create DOM elements until it is started.
4
+ * Fix the possibility of extraneous whitespace in class names.
5
+ * Add a cache buster parameter to the Monotype/Fonts.com module.
6
+ * Fix the case where there are no fonts to load. Webfontloader will now fire the inactive event correctly.
7
+ * Test suite now uses the active browser to test font watching in addition to the mocked font watching tests.
8
+ * Test suite is now using Jasmine instead of JSTestDriver.
9
+
1
10
  v1.2.0 (January 30, 2013)
2
11
  * Improved font watching for browsers with the WebKit web font fallback bug
3
12
  * Improved font watching in general by comparing both width and height
data/Gemfile CHANGED
@@ -1,9 +1,3 @@
1
- source :gemcutter
1
+ source :rubygems
2
2
 
3
- gem "rake"
4
-
5
- group :demos do
6
- gem "rack"
7
- gem "sinatra"
8
- gem "vegas"
9
- end
3
+ gemspec
data/README.md CHANGED
@@ -5,7 +5,6 @@ WebFont Loader gives you added control when using linked fonts via
5
5
  the source, then adds a standard set of events you may use to control the
6
6
  loading experience.
7
7
 
8
-
9
8
  ## Get Started
10
9
 
11
10
  (These samples use WebFont Loader hosted on [Google's AJAX Libraries][gajax].)
@@ -36,7 +35,6 @@ Alternatively, load fonts from Typekit. Just specify your Kit ID.
36
35
  Learn more about the
37
36
  [modules][mod].
38
37
 
39
-
40
38
  ## Do More
41
39
 
42
40
  WebFont Loader gives you control over how fonts are loaded. If you're
@@ -91,65 +89,67 @@ WebFont Loader aims to provide a common interface for font loading. Today it
91
89
  works with Google, Typekit, Ascender, Fontdeck, Fonts.com Web fonts and your own
92
90
  CSS. Learn more in [transitions][trn].
93
91
 
92
+ ## Problems?
94
93
 
95
- ## More to see
94
+ Please open [an issue][issues]. Sample pages are greatly appreciated.
96
95
 
97
- A full suite of demo pages is included in this source. Here you can find some
98
- live examples using the JS and CSS events.
96
+ ## Developing
99
97
 
100
- To view the demos, just boot up our demo server and start browsing.
98
+ Is there something else WebFont Loader should do? Did you find a bug and want
99
+ to fix it?
101
100
 
102
- $ rake demo
101
+ ### Installing development requirements
103
102
 
104
- You may need a few rubygems to run the server. Get them with [Bundler](http://gembundler.com/).
103
+ You'll need a few rubygems to run the tests, demo server, and other rake tasks, which should be installed with [Bundler](http://gembundler.com/).
105
104
 
106
105
  $ gem install bundler
107
106
  $ bundle install
108
107
 
109
- Browse the demos [source code][demos].
110
-
111
-
112
- ## Problems?
108
+ To run the tests in a headless WebKit you will also need to have [PhantomJS](http://www.phantomjs.org) installed. You can install PhantomJS by downloading a binary of using HomeBrew.
113
109
 
114
- Please open [an issue][issues]. Sample pages are greatly appreciated.
110
+ $ brew install phantomjs
115
111
 
112
+ ### Building
116
113
 
117
- ## Developing
114
+ To build a JS file from source, just run rake:
118
115
 
119
- Is there something else WebFont Loader should do? Did you find a bug and want
120
- to fix it?
116
+ $ rake
121
117
 
122
- ### Building
118
+ ### Demos
123
119
 
124
- Run rake:
120
+ A full suite of demo pages is included in this source. Here you can find some
121
+ live examples using the JS and CSS events. Run the demo server with:
125
122
 
126
- rake
123
+ $ rake demo
127
124
 
128
- ### Testing
125
+ You can also run the demos with uncompressed, debuggable code to aid in
126
+ development. Just start the server in dev mode:
129
127
 
130
- You can run uncompressed, debuggable code by starting the demo server in dev mode:
128
+ $ rake demodev
131
129
 
132
- rake demodev
130
+ Browse the demos [source code][demos].
133
131
 
134
- WebFont Loader has an extensive test suite that runs via
135
- [jsTestDriver][jstestdriver]. Please add tests for any changes.
132
+ ### Testing
136
133
 
137
- To run tests, first boot the test server. Then open a browser and navigate to
138
- the test server url listed by `rake test` to start listing for test executions.
139
- You can register multiple browsers.
134
+ WebFont Loader has an extensive test suite that runs via Jasmine. The test suite
135
+ should be passing before submitting a pull request, and new tests should be added
136
+ for any new functionality.
140
137
 
141
- rake test:boot
138
+ To run tests, open up `spec/index.html` in a browser and check the results. The
139
+ test suite will run automatically. Again, before submitting a pull request
140
+ please run the test suite in multiple browsers and list them in the pull request.
142
141
 
143
- Then, run the tests.
142
+ To run tests in a headless WebKit using [PhantomJS](http://www.phantomjs.org) run:
144
143
 
145
- rake test
144
+ $ rake test
146
145
 
147
146
  ## Contributing
148
147
 
149
148
  * Fork webfontloader
150
149
  * Create a topic branch - `git checkout -b my_branch`
151
150
  * Push to your branch - `git push origin my_branch`
152
- * Create an [issue][issues] with a link to your branch
151
+ * Make sure all tests are passing
152
+ * Create a pull request for your branch
153
153
  * That's it!
154
154
 
155
155
 
@@ -173,5 +173,4 @@ WebFont Loader is released under the [Apache 2.0][lic] license.
173
173
  [demos]: http://github.com/typekit/webfontloader/blob/master/lib/webfontloader/demo/public
174
174
  [gfontapi]: https://code.google.com/apis/webfonts/
175
175
  [gajax]: http://code.google.com/apis/ajaxlibs/
176
- [jstestdriver]: http://code.google.com/p/js-test-driver/
177
176
  [issues]: https://github.com/typekit/webfontloader/issues
data/Rakefile CHANGED
@@ -63,11 +63,6 @@ require 'webfontloader'
63
63
  CLEAN.include("target")
64
64
  CLEAN.include("tmp")
65
65
 
66
- # JsTestDriver
67
- JsTestPort = "9876"
68
- JsTestServer = "http://localhost:#{JsTestPort}"
69
- JsTestJar = "tools/jstestdriver/JsTestDriver-1.2.1.jar"
70
-
71
66
  # JsCompiler
72
67
  JsCompilerJar = "tools/compiler/compiler.jar"
73
68
 
@@ -85,15 +80,6 @@ SourceJs = FileList["src/**/*"]
85
80
  directory "target"
86
81
  directory "tmp"
87
82
 
88
- file "tmp/jsTestDriver.conf" => AllJs + ["tmp"] do |t|
89
- require 'yaml'
90
- config = {
91
- "server" => JsTestServer,
92
- "load" => (@modules.all_source_files + @modules.all_test_globs).map { |f| "../#{f}" }
93
- }
94
- File.open(t.name, "w") { |f| YAML.dump(config, f) }
95
- end
96
-
97
83
  desc "Compile the JavaScript into target/webfont.js"
98
84
  task :compile => "target/webfont.js"
99
85
 
@@ -143,26 +129,9 @@ end
143
129
  desc "Test everything"
144
130
  task :default => [:clean, :gzipbytes, :test]
145
131
 
146
- namespace :test do
147
- task :server do
148
- system "java -jar #{JsTestJar} --port #{JsTestPort}"
149
- end
150
- task :capture do
151
- system "open #{JsTestServer}/capture?strict"
152
- end
153
- desc "Execute tests against a running server"
154
- task :run => ["tmp/jsTestDriver.conf"] do |t|
155
- config = t.prerequisites.first
156
- system "java -jar #{JsTestJar} --config #{config} --server #{JsTestServer} --tests all --captureConsole --verbose"
157
- end
158
- desc "Boot the test server and capture a browser"
159
- multitask :boot => ['test:server', 'test:capture']
160
- end
161
-
162
132
  desc "Run all tests"
163
- task :test => ["tmp/jsTestDriver.conf"] do |t|
164
- config = t.prerequisites.first
165
- system "java -jar #{JsTestJar} --port #{JsTestPort} --config #{config} --server #{JsTestServer} --browser open --tests all --captureConsole --verbose"
133
+ task :test do |t|
134
+ exec "phantomjs tools/jasmine-phantomjs/jasmine-phantomjs.js spec/index.html"
166
135
  end
167
136
 
168
137
  desc "Start the demo server"
data/docs/EVENTS.md CHANGED
@@ -117,7 +117,16 @@ event will be triggered, else the `Inative` even will be triggered.
117
117
  ### Browser Support
118
118
 
119
119
  Every web browser has varying levels of support for fonts linked via
120
- @font-face.
120
+ @font-face. Support for web fonts is determined using the browser user agent
121
+ string. The user agent string may claim to support a web font format
122
+ when it in fact does not. This is especially noticable on mobile browsers
123
+ with a "Desktop" mode, which usually identify as Chrome on Linux.
124
+ In this case a web font provider may decide to send WOFF fonts to the
125
+ device because the real desktop Chrome supports it, while the mobile
126
+ browser does not. The WebFont Loader is not designed to handle these
127
+ cases and it chooses to believe the user agent string. Web font providers
128
+ may or may not build on top of the basic WebFont Loader functionality
129
+ to handle these special cases individually.
121
130
 
122
131
  > If WebFont Loader determines that the current browser does not support
123
132
  `@font-face`, the `Inactive` event will be triggered.
data/docs/MODULES.md CHANGED
@@ -61,7 +61,8 @@ When using [Fonts.com web fonts][mtiwfs]
61
61
  <script type="text/javascript">
62
62
  WebFont.load({
63
63
  monotype: {
64
- projectId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
64
+ projectId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
65
+ version: 12345 // (optional, flushes the CDN cache)
65
66
  }
66
67
  });
67
68
  </script>
@@ -78,7 +79,7 @@ provides.
78
79
 
79
80
  You can specify a specific font variation or set of variations to load and watch
80
81
  by appending the variations separated by commas to the family name separated by
81
- a colon. variations are specified using (FVD notation)[fvd].
82
+ a colon. Variations are specified using [FVD notation][fvd].
82
83
 
83
84
  WebFont.load({
84
85
  custom: {
@@ -92,4 +93,4 @@ a colon. variations are specified using (FVD notation)[fvd].
92
93
  [tk]: http://typekit.com/
93
94
  [fd]: http://fontdeck.com/
94
95
  [mtiwfs]: http://webfonts.fonts.com/
95
- [fvd]: https://github.com/typekit/fvd
96
+ [fvd]: https://github.com/typekit/fvd
data/lib/webfontloader.rb CHANGED
@@ -3,7 +3,7 @@ require 'yaml'
3
3
  require 'webfontloader/modules'
4
4
 
5
5
  module WebFontLoader
6
- VERSION = '1.2.0'
6
+ VERSION = '1.2.1'
7
7
 
8
8
  ProjectRoot = File.expand_path(File.dirname(__FILE__) + "/..")
9
9
 
@@ -0,0 +1,43 @@
1
+ describe('AscenderScript', function () {
2
+ var AscenderScript = webfont.AscenderScript;
3
+
4
+ var configuration = {
5
+ key: 'ec2de397-11ae-4c10-937f-bf94283a70c1',
6
+ families: ['AndyBold', 'Arial:bold,regular']
7
+ };
8
+
9
+ describe('load family and variations', function () {
10
+ var fakeDomHelper = null,
11
+ fakeOnReady = null,
12
+ ascenderScript = null;
13
+
14
+ beforeEach(function () {
15
+ fakeDomHelper = {
16
+ insertInto: jasmine.createSpy('insertInto'),
17
+ createCssLink: jasmine.createSpy('createCssLink'),
18
+ getProtocol: jasmine.createSpy('getProtocol').andReturn('http:')
19
+ };
20
+
21
+ fakeOnReady = jasmine.createSpy('onReady');
22
+
23
+ ascenderScript = new AscenderScript(fakeDomHelper, configuration);
24
+ ascenderScript.load(fakeOnReady);
25
+ });
26
+
27
+ it('should create the link correctly', function () {
28
+ expect(fakeDomHelper.createCssLink).toHaveBeenCalledWith('http://webfonts.fontslive.com/css/ec2de397-11ae-4c10-937f-bf94283a70c1.css');
29
+ expect(fakeDomHelper.insertInto.calls[0].args[0]).toEqual('head');
30
+ });
31
+
32
+ it('should parse variations correctly', function () {
33
+ expect(ascenderScript.parseVariations('regular')).toEqual(['n4']);
34
+ expect(ascenderScript.parseVariations('bold')).toEqual(['n7']);
35
+ expect(ascenderScript.parseVariations('italic')).toEqual(['i4']);
36
+ expect(ascenderScript.parseVariations('bolditalic')).toEqual(['i7']);
37
+ expect(ascenderScript.parseVariations('regular,')).toEqual(['n4']);
38
+ expect(ascenderScript.parseVariations('regular,bold')).toEqual(['n4', 'n7']);
39
+ expect(ascenderScript.parseVariations('regular,,bold')).toEqual(['n4', 'n7']);
40
+ expect(ascenderScript.parseVariations('n4,n7')).toEqual(['n4', 'n7']);
41
+ });
42
+ })
43
+ });
@@ -0,0 +1,42 @@
1
+ describe('CssClassName', function () {
2
+ var CssClassName = webfont.CssClassName,
3
+ sanitizer = new CssClassName();
4
+
5
+ describe('#sanitize', function () {
6
+ it('should sanitize spaces in names', function () {
7
+ expect(sanitizer.sanitize(' My Family ')).toEqual('myfamily');
8
+ });
9
+
10
+ it('should sanitize numbers in names', function () {
11
+ expect(sanitizer.sanitize('99 My Family 99')).toEqual('99myfamily99');;
12
+ });
13
+
14
+ it('should sanitize other characters', function () {
15
+ expect(sanitizer.sanitize('_My+Family!-')).toEqual('myfamily');
16
+ });
17
+ });
18
+
19
+ describe('#build', function () {
20
+ it('should build many parts', function () {
21
+ expect(sanitizer.build('pre_', 'My Family', '_post')).toEqual('pre-myfamily-post');
22
+ });
23
+
24
+ it('should build some parts', function () {
25
+ expect(sanitizer.build('pre!', 'My Family')).toEqual('pre-myfamily');
26
+ });
27
+ });
28
+
29
+ describe('#constructor', function () {
30
+ it('should use a hyphen as a default separator', function () {
31
+ var sanitizer = new CssClassName();
32
+
33
+ expect(sanitizer.build('pre', 'post')).toEqual('pre-post');
34
+ });
35
+
36
+ it('should use the configured separator', function () {
37
+ var sanitizer = new CssClassName('_');
38
+
39
+ expect(sanitizer.build('pre', 'post')).toEqual('pre_post');
40
+ });
41
+ });
42
+ });
@@ -0,0 +1,38 @@
1
+ describe('CssFontFamilyName', function () {
2
+ var CssFontFamilyName = webfont.CssFontFamilyName,
3
+ sanitizer = new CssFontFamilyName();
4
+
5
+ describe('#quote', function () {
6
+ it('should quote names with spaces', function () {
7
+ expect(sanitizer.quote('My Family')).toEqual("'My Family'");
8
+ });
9
+
10
+ it('should quote names with spaces and double quotes', function () {
11
+ expect(sanitizer.quote('"My Family"')).toEqual("'My Family'");
12
+ });
13
+
14
+ it('should quote names with spaces and single quotes', function () {
15
+ expect(sanitizer.quote("'My Family'")).toEqual("'My Family'");
16
+ });
17
+
18
+ it('should quote multiple single quoted names separated with a comma', function () {
19
+ expect(sanitizer.quote("'family 1','family 2'")).toEqual("'family 1','family 2'");
20
+ });
21
+
22
+ it('should quote multiple single quoted names separated with a comma and space', function () {
23
+ expect(sanitizer.quote("'family 1', 'family 2'")).toEqual("'family 1','family 2'");
24
+ });
25
+
26
+ it('should not quote when there is no space', function () {
27
+ expect(sanitizer.quote('MyFamily')).toEqual('MyFamily');
28
+ });
29
+
30
+ it('should remove quotes when they are unnecesssary', function () {
31
+ expect(sanitizer.quote('"MyFamily"')).toEqual('MyFamily');
32
+ });
33
+
34
+ it('should not quote multiple names when there is no space', function () {
35
+ expect(sanitizer.quote("'family-1', 'family-2'")).toEqual('family-1,family-2');
36
+ });
37
+ });
38
+ });
@@ -0,0 +1,158 @@
1
+ describe('DomHelper', function () {
2
+ var domHelper = new webfont.DomHelper(window);
3
+
4
+ describe('#createElement', function () {
5
+ it('should create an element', function () {
6
+ var div = domHelper.createElement('div');
7
+
8
+ expect(div).not.toBeNull();
9
+ });
10
+
11
+ it('should create an element with inline content', function () {
12
+ var div = domHelper.createElement('div', {}, 'moo');
13
+
14
+ expect(div).not.toBeNull();
15
+ expect(div.innerHTML).toEqual('moo');
16
+ });
17
+
18
+ it('should create an element with attributes and inline content', function () {
19
+ var div = domHelper.createElement('div', {
20
+ style: 'font-size: 42px',
21
+ id: 'mySpan'
22
+ }, 'hello');
23
+
24
+ expect(div).not.toBeNull();
25
+ expect(div.innerHTML).toEqual('hello');
26
+ expect(div.style.fontSize).toEqual('42px');
27
+ expect(div.id).toEqual('mySpan');
28
+ });
29
+
30
+ it('should work with augmented Object.prototype', function () {
31
+ Object.prototype.evil = function () {};
32
+
33
+ var div = domHelper.createElement('div', { id: 'augmented' });
34
+ var parentDiv = domHelper.createElement('div', { id: 'parentaugmented' });
35
+
36
+ parentDiv.appendChild(div);
37
+
38
+ expect(div).not.toBeNull();
39
+ expect(!!div.getAttribute('evil')).toBe(false);
40
+ expect(-1, parentDiv.innerHTML.indexOf('evil'));
41
+
42
+ delete Object.prototype.evil;
43
+ });
44
+ });
45
+
46
+ describe('#createCssLink', function () {
47
+ var link = domHelper.createCssLink('http://moo/somecss.css');
48
+
49
+ it('should create a link', function () {
50
+ expect(link).not.toBeNull();
51
+ });
52
+
53
+ it('should create a link with correct rel and href properties', function () {
54
+ expect(link.rel).toEqual('stylesheet');
55
+ expect(link.href).toEqual('http://moo/somecss.css');
56
+ });
57
+ });
58
+
59
+ describe('#createScriptSrc', function () {
60
+ var script = domHelper.createScriptSrc('http://moo/somescript.js');
61
+
62
+ it('should create a script element', function () {
63
+ expect(script).not.toBeNull();
64
+ });
65
+
66
+ it('should have a src property', function () {
67
+ expect(script.src).toEqual('http://moo/somescript.js');
68
+ });
69
+ });
70
+
71
+ describe('#appendClassName', function () {
72
+ it('should have added a class name', function () {
73
+ var div = domHelper.createElement('div');
74
+ domHelper.appendClassName(div, 'moo');
75
+
76
+ expect(div.className).toEqual('moo');
77
+ });
78
+
79
+ it('should not add duplicate class names', function () {
80
+ var div = domHelper.createElement('div');
81
+
82
+ domHelper.appendClassName(div, 'moo');
83
+ domHelper.appendClassName(div, 'meu');
84
+ domHelper.appendClassName(div, 'moo');
85
+
86
+ expect(div.className).toEqual('moo meu');
87
+ });
88
+
89
+ it('should add multiple class names', function () {
90
+ var div = domHelper.createElement('div');
91
+
92
+ domHelper.appendClassName(div, 'moo meu moo');
93
+ expect(div.className).toEqual('moo meu moo');
94
+ });
95
+
96
+ it('should normalize spaces and tabs', function () {
97
+ var div = domHelper.createElement('div');
98
+
99
+ domHelper.appendClassName(div, 'meu');
100
+ domHelper.appendClassName(div, ' foo ');
101
+ expect(div.className).toEqual('meu foo');
102
+ });
103
+ });
104
+
105
+ describe('#removeClassName', function () {
106
+ it('should remove class names', function () {
107
+ var div = domHelper.createElement('div');
108
+
109
+ domHelper.appendClassName(div, 'meu moo');
110
+ expect(div.className).toEqual('meu moo');
111
+
112
+ domHelper.removeClassName(div, 'meu');
113
+ expect(div.className).toEqual('moo');
114
+ });
115
+
116
+ it('should not remove non-existing classes', function () {
117
+ var div = domHelper.createElement('div');
118
+
119
+ domHelper.appendClassName(div, 'moo');
120
+ expect(div.className).toEqual('moo');
121
+ domHelper.removeClassName(div, 'boo');
122
+ expect(div.className).toEqual('moo');
123
+ });
124
+ });
125
+
126
+ describe('#hasClassName', function () {
127
+ var div = null;
128
+
129
+ beforeEach(function () {
130
+ div = domHelper.createElement('div');
131
+ domHelper.appendClassName(div, 'moo moo-meu');
132
+ });
133
+
134
+ it('should return true', function () {
135
+ expect(domHelper.hasClassName(div, 'moo')).toBe(true);
136
+ expect(domHelper.hasClassName(div, 'moo-meu')).toBe(true);
137
+ });
138
+
139
+ it('should return false', function () {
140
+ expect(domHelper.hasClassName(div, 'boo')).toBe(false);
141
+ expect(domHelper.hasClassName(div, 'meu')).toBe(false);
142
+ });
143
+ });
144
+
145
+ describe('#setStyle', function () {
146
+ var div = null;
147
+
148
+ beforeEach(function () {
149
+ div = domHelper.createElement('div');
150
+ });
151
+
152
+ it('should set the style correctly', function () {
153
+ domHelper.setStyle(div, 'left:3px;top:1px;');
154
+ expect(div.style.left).toEqual('3px');
155
+ expect(div.style.top).toEqual('1px');
156
+ });
157
+ });
158
+ });