Js test fixes for common, common-requirejs, xmodule.

This commit is contained in:
muzaffaryousaf
2016-04-06 21:19:32 +05:00
committed by Usman Khalid
parent 375f2bfc59
commit 9cbfea2edd
80 changed files with 2611 additions and 2166 deletions

View File

@@ -4,7 +4,7 @@
<div
id="video_id"
class="video closed"
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": "[]", "speed": "1.5", "startTime": "", "streams": "0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": [], "speed": "1.5", "startTime": "", "streams": "0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
>
<div class="focus_grabber first"></div>

View File

@@ -4,7 +4,7 @@
<div
id="video_id"
class="video closed"
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["/base/fixtures/test.mp4","/base/fixtures/test.webm","/base/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
>
<div class="focus_grabber first"></div>

View File

@@ -4,7 +4,7 @@
<div
id="video_id"
class="video closed"
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/", "source": "", "html5_sources": ["http://youtu.be/3_yD_cEKoCk.mp4"]}'
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["/base/fixtures/test.mp4","/base/fixtures/test.webm","/base/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/", "source": "", "html5_sources": ["http://youtu.be/3_yD_cEKoCk.mp4"]}'
>
<div class="focus_grabber first"></div>

View File

@@ -4,7 +4,7 @@
<div
id="video_id"
class="video closed"
data-metadata='{"streams":"0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "showCaptions": false, "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "speed": "1.5", "startTime": "", "end": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
data-metadata='{"streams":"0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "showCaptions": false, "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "speed": "1.5", "startTime": "", "end": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
>
<div class="focus_grabber first"></div>

View File

@@ -4,9 +4,9 @@
<div
id="video_id"
class="video closed"
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
data-bumper-metadata='{"transcriptLanguage": "en", "showCaptions": "true", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "transcriptTranslationUrl": "/transcript/translation/__lang__/?is_bumper=1", "transcriptAvailableTranslationsUrl": "/transcript/available_translations/?is_bumper=1", "streams": "", "saveStateUrl": "/save_user_state"}'
data-poster='{"url": "xmodule/include/fixtures/poster.jpg", "type": "youtube"}'
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["/base/fixtures/test.mp4","/base/fixtures/test.webm","/base/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
data-bumper-metadata='{"transcriptLanguage": "en", "showCaptions": "true", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "sources": ["/base/fixtures/test.mp4","/base/fixtures/test.webm","/base/fixtures/test.ogv"], "transcriptTranslationUrl": "/transcript/translation/__lang__/?is_bumper=1", "transcriptAvailableTranslationsUrl": "/transcript/available_translations/?is_bumper=1", "streams": "", "saveStateUrl": "/save_user_state"}'
data-poster='{"url": "/base/fixtures/poster.jpg", "type": "youtube"}'
>
<div class="focus_grabber first"></div>

View File

@@ -4,7 +4,7 @@
<div
id="video_id1"
class="video closed"
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["/base/fixtures/test.mp4","/base/fixtures/test.webm","/base/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
>
<div class="focus_grabber first"></div>
@@ -38,7 +38,7 @@
<div
id="video_id2"
class="video"
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.0", "startTime": "", "streams": "0.75:7tqY6eQzVhE,1.0:cogebirgzzM", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["/base/fixtures/test.mp4","/base/fixtures/test.webm","/base/fixtures/test.ogv"], "speed": "1.0", "startTime": "", "streams": "0.75:7tqY6eQzVhE,1.0:cogebirgzzM", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
>
<div class="tc-wrapper">
<article class="video-wrapper">
@@ -68,7 +68,7 @@
<div
id="video_id3"
class="video"
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.0", "startTime": "", "streams": "0.75:7tqY6eQzVhE,1.0:cogebirgzzM", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["/base/fixtures/test.mp4","/base/fixtures/test.webm","/base/fixtures/test.ogv"], "speed": "1.0", "startTime": "", "streams": "0.75:7tqY6eQzVhE,1.0:cogebirgzzM", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
>
<div class="tc-wrapper">
<article class="video-wrapper">

View File

@@ -36,8 +36,8 @@ lib_paths:
- common_static/js/test/i18n.js
- common_static/coffee/src/ajax_prefix.js
- common_static/js/src/logger.js
- common_static/js/vendor/jasmine-jquery.js
- common_static/js/vendor/jasmine-imagediff.js
- common_static/js/libs/jasmine-waituntil.js
- common_static/js/vendor/requirejs/require.js
- RequireJS-namespace-undefine.js
- common_static/js/vendor/jquery.min.js

View File

@@ -37,6 +37,7 @@ var files = [
{pattern: 'common_static/js/src/logger.js', included: true},
{pattern: 'common_static/js/vendor/jasmine-imagediff.js', included: true},
{pattern: 'common_static/js/libs/jasmine-waituntil.js', included: true},
{pattern: 'common_static/js/libs/jasmine-extensions.js', included: true},
{pattern: 'common_static/js/vendor/requirejs/require.js', included: true},
{pattern: 'RequireJS-namespace-undefine.js', included: true},
{pattern: 'common_static/js/vendor/jquery-ui.min.js', included: true},

View File

@@ -7,7 +7,7 @@ describe 'Problem', ->
Hub: jasmine.createSpyObj('MathJax.Hub', ['getAllJax', 'Queue'])
Callback: jasmine.createSpyObj('MathJax.Callback', ['After'])
@stubbedJax = root: jasmine.createSpyObj('jax.root', ['toMathML'])
MathJax.Hub.getAllJax.andReturn [@stubbedJax]
MathJax.Hub.getAllJax.and.returnValue [@stubbedJax]
window.update_schematics = ->
spyOn SR, 'readElts'
spyOn SR, 'readText'
@@ -21,8 +21,8 @@ describe 'Problem', ->
loadFixtures 'problem.html'
spyOn Logger, 'log'
spyOn($.fn, 'load').andCallFake (url, callback) ->
$(@).html problem_content_default
spyOn($.fn, 'load').and.callFake (url, callback) ->
$(@).html readFixtures('problem_content.html')
callback()
describe 'constructor', ->
@@ -46,7 +46,7 @@ describe 'Problem', ->
describe 'bind', ->
beforeEach ->
spyOn window, 'update_schematics'
MathJax.Hub.getAllJax.andReturn [@stubbedJax]
MathJax.Hub.getAllJax.and.returnValue [@stubbedJax]
@problem = new Problem($('.xblock-student_view'))
it 'set mathjax typeset', ->
@@ -76,7 +76,7 @@ describe 'Problem', ->
describe 'bind_with_custom_input_id', ->
beforeEach ->
spyOn window, 'update_schematics'
MathJax.Hub.getAllJax.andReturn [@stubbedJax]
MathJax.Hub.getAllJax.and.returnValue [@stubbedJax]
@problem = new Problem($('.xblock-student_view'))
$(@).html readFixtures('problem_content_1240.html')
@@ -137,7 +137,7 @@ describe 'Problem', ->
describe 'with no content given', ->
beforeEach ->
spyOn($, 'postWithPrefix').andCallFake (url, callback) ->
spyOn($, 'postWithPrefix').and.callFake (url, callback) ->
callback html: "Hello World"
@problem.render()
@@ -164,7 +164,7 @@ describe 'Problem', ->
@problem.answers = 'foo=1&bar=2'
it 'log the problem_check event', ->
spyOn($, 'postWithPrefix').andCallFake (url, answers, callback) ->
spyOn($, 'postWithPrefix').and.callFake (url, answers, callback) ->
promise =
always: (callable) -> callable()
done: (callable) -> callable()
@@ -172,7 +172,7 @@ describe 'Problem', ->
expect(Logger.log).toHaveBeenCalledWith 'problem_check', 'foo=1&bar=2'
it 'log the problem_graded event, after the problem is done grading.', ->
spyOn($, 'postWithPrefix').andCallFake (url, answers, callback) ->
spyOn($, 'postWithPrefix').and.callFake (url, answers, callback) ->
response =
success: 'correct'
contents: 'mock grader response'
@@ -184,7 +184,7 @@ describe 'Problem', ->
expect(Logger.log).toHaveBeenCalledWith 'problem_graded', ['foo=1&bar=2', 'mock grader response'], @problem.id
it 'submit the answer for check', ->
spyOn($, 'postWithPrefix').andCallFake (url, answers, callback) ->
spyOn($, 'postWithPrefix').and.callFake (url, answers, callback) ->
promise =
always: (callable) -> callable()
done: (callable) -> callable()
@@ -194,58 +194,76 @@ describe 'Problem', ->
describe 'when the response is correct', ->
it 'call render with returned content', ->
spyOn($, 'postWithPrefix').andCallFake (url, answers, callback) ->
callback(success: 'correct', contents: 'Correct!')
spyOn($, 'postWithPrefix').and.callFake (url, answers, callback) ->
callback(success: 'correct', contents: 'Correct')
promise =
always: (callable) -> callable()
done: (callable) -> callable()
@problem.check()
expect(@problem.el.html()).toEqual 'Correct!'
expect(@problem.el.html()).toEqual 'Correct'
expect(window.SR.readElts).toHaveBeenCalled()
describe 'when the response is incorrect', ->
it 'call render with returned content', ->
spyOn($, 'postWithPrefix').andCallFake (url, answers, callback) ->
callback(success: 'incorrect', contents: 'Incorrect!')
spyOn($, 'postWithPrefix').and.callFake (url, answers, callback) ->
callback(success: 'incorrect', contents: 'Incorrect')
promise =
always: (callable) -> callable()
done: (callable) -> callable()
@problem.check()
expect(@problem.el.html()).toEqual 'Incorrect!'
expect(@problem.el.html()).toEqual 'Incorrect'
expect(window.SR.readElts).toHaveBeenCalled()
it 'tests if all the capa buttons are disabled while checking', ->
runs ->
spyOn($, 'postWithPrefix').andCallFake (url, answers, callback) ->
callback(success: 'incorrect', contents: 'Incorrect!')
it 'tests if all the capa buttons are disabled while checking', (done)->
deferred = $.Deferred()
self = this
runs = ->
spyOn($, 'postWithPrefix').and.callFake (url, answers, callback) ->
promise = undefined
callback
success: 'incorrect'
contents: 'Incorrect'
promise =
always: (callable) -> callable()
done: (callable) -> callable()
always: (callable) ->
callable()
done: (callable) ->
callable()
spyOn @problem, 'enableAllButtons'
@problem.check()
expect(@problem.enableAllButtons).toHaveBeenCalledWith false, true
waitsFor (->
return jQuery.active == 0
), "jQuery requests finished", 1000
if jQuery.active == 0
deferred.resolve()
deferred.promise()
runs ->
expect(@problem.enableAllButtons).toHaveBeenCalledWith true, true
runs.call(self).then(->
expect(self.problem.enableAllButtons).toHaveBeenCalledWith true, true
return
).always done
it 'tests the expected change in text of check button', ->
runs ->
spyOn($, 'postWithPrefix').andCallFake (url, answers, callback) ->
it 'tests the expected change in text of check button', (done) ->
deferred = $.Deferred()
self = this
runs = ->
spyOn($, 'postWithPrefix').and.callFake (url, answers, callback) ->
promise = undefined
promise =
always: (callable) -> callable()
done: (callable) -> callable()
always: (callable) ->
callable()
done: (callable) ->
callable()
spyOn @problem.checkButtonLabel, 'text'
@problem.check()
expect(@problem.checkButtonLabel.text).toHaveBeenCalledWith 'Checking...'
waitsFor (->
return jQuery.active == 0
), "jQuery requests finished", 1000
if jQuery.active == 0
deferred.resolve()
deferred.promise()
runs ->
expect(@problem.checkButtonLabel.text).toHaveBeenCalledWith 'Check'
runs.call(self).then(->
expect(self.problem.checkButtonLabel.text).toHaveBeenCalledWith 'Check'
return
).always done
describe 'check button on problems', ->
beforeEach ->
@@ -341,7 +359,7 @@ describe 'Problem', ->
@problem = new Problem($('.xblock-student_view'))
it 'log the problem_reset event', ->
spyOn($, 'postWithPrefix').andCallFake (url, answers, callback) ->
spyOn($, 'postWithPrefix').and.callFake (url, answers, callback) ->
promise =
always: (callable) -> callable()
@problem.answers = 'foo=1&bar=2'
@@ -349,7 +367,7 @@ describe 'Problem', ->
expect(Logger.log).toHaveBeenCalledWith 'problem_reset', 'foo=1&bar=2'
it 'POST to the problem reset page', ->
spyOn($, 'postWithPrefix').andCallFake (url, answers, callback) ->
spyOn($, 'postWithPrefix').and.callFake (url, answers, callback) ->
promise =
always: (callable) -> callable()
@problem.reset()
@@ -357,29 +375,34 @@ describe 'Problem', ->
{ id: 'i4x://edX/101/problem/Problem1' }, jasmine.any(Function)
it 'render the returned content', ->
spyOn($, 'postWithPrefix').andCallFake (url, answers, callback) ->
callback html: "Reset!"
spyOn($, 'postWithPrefix').and.callFake (url, answers, callback) ->
callback html: "Reset"
promise =
always: (callable) -> callable()
@problem.reset()
expect(@problem.el.html()).toEqual 'Reset!'
expect(@problem.el.html()).toEqual 'Reset'
it 'tests if all the buttons are disabled and the text of check button remains same while resetting', ->
runs ->
spyOn($, 'postWithPrefix').andCallFake (url, answers, callback) ->
promise =
always: (callable) -> callable()
it 'tests if all the buttons are disabled and the text of check button remains same while resetting', (done) ->
deferred = $.Deferred()
self = this
runs = ->
spyOn($, 'postWithPrefix').and.callFake (url, answers, callback) ->
promise = undefined
promise = always: (callable) ->
callable()
spyOn @problem, 'enableAllButtons'
@problem.reset()
expect(@problem.enableAllButtons).toHaveBeenCalledWith false, false
expect(@problem.checkButtonLabel).toHaveText 'Check'
waitsFor (->
return jQuery.active == 0
), "jQuery requests finished", 1000
if jQuery.active == 0
deferred.resolve()
deferred.promise()
runs ->
expect(@problem.enableAllButtons).toHaveBeenCalledWith true, false
expect(@problem.checkButtonLabel).toHaveText 'Check'
runs.call(self).then(->
expect(self.problem.enableAllButtons).toHaveBeenCalledWith true, false
expect(self.problem.checkButtonLabel).toHaveText 'Check'
).always done
describe 'show', ->
beforeEach ->
@@ -402,20 +425,20 @@ describe 'Problem', ->
jasmine.any(Function)
it 'show the answers', ->
spyOn($, 'postWithPrefix').andCallFake (url, callback) ->
spyOn($, 'postWithPrefix').and.callFake (url, callback) ->
callback answers: '1_1': 'One', '1_2': 'Two'
@problem.show()
expect($('#answer_1_1')).toHaveHtml 'One'
expect($('#answer_1_2')).toHaveHtml 'Two'
it 'toggle the show answer button', ->
spyOn($, 'postWithPrefix').andCallFake (url, callback) -> callback(answers: {})
spyOn($, 'postWithPrefix').and.callFake (url, callback) -> callback(answers: {})
@problem.show()
expect($('.show .show-label')).toHaveText 'Hide Answer'
expect(window.SR.readElts).toHaveBeenCalled()
it 'toggle the show answer button, answers are strings', ->
spyOn($, 'postWithPrefix').andCallFake (url, callback) -> callback(answers: '1_1': 'One', '1_2': 'Two')
spyOn($, 'postWithPrefix').and.callFake (url, callback) -> callback(answers: '1_1': 'One', '1_2': 'Two')
@problem.show()
expect($('.show .show-label')).toHaveText 'Hide Answer'
expect(window.SR.readElts).toHaveBeenCalledWith ['<p>Answer: One</p>', '<p>Answer: Two</p>']
@@ -423,27 +446,32 @@ describe 'Problem', ->
it 'toggle the show answer button, answers are elements', ->
answer1 = '<div><span class="detailed-solution">one</span></div>'
answer2 = '<div><span class="detailed-solution">two</span></div>'
spyOn($, 'postWithPrefix').andCallFake (url, callback) -> callback(answers: '1_1': answer1, '1_2': answer2)
spyOn($, 'postWithPrefix').and.callFake (url, callback) -> callback(answers: '1_1': answer1, '1_2': answer2)
@problem.show()
expect($('.show .show-label')).toHaveText 'Hide Answer'
expect(window.SR.readElts).toHaveBeenCalledWith [jasmine.any(jQuery), jasmine.any(jQuery)]
it 'add the showed class to element', ->
spyOn($, 'postWithPrefix').andCallFake (url, callback) -> callback(answers: {})
spyOn($, 'postWithPrefix').and.callFake (url, callback) -> callback(answers: {})
@problem.show()
expect(@problem.el).toHaveClass 'showed'
it 'reads the answers', ->
runs ->
spyOn($, 'postWithPrefix').andCallFake (url, callback) -> callback(answers: 'answers')
it 'reads the answers', (done) ->
deferred = $.Deferred()
runs = ->
spyOn($, 'postWithPrefix').and.callFake (url, callback) ->
callback answers:
'1_1': 'answers'
@problem.show()
if jQuery.active == 0
deferred.resolve()
deferred.promise()
waitsFor (->
return jQuery.active == 0
), "jQuery requests finished", 1000
runs ->
runs.call(this).then(->
expect(window.SR.readElts).toHaveBeenCalled()
return
).always done
describe 'multiple choice question', ->
beforeEach ->
@@ -455,7 +483,7 @@ describe 'Problem', ->
'''
it 'set the correct_answer attribute on the choice', ->
spyOn($, 'postWithPrefix').andCallFake (url, callback) ->
spyOn($, 'postWithPrefix').and.callFake (url, callback) ->
callback answers: '1_1': [2, 3]
@problem.show()
expect($('label[for="input_1_1_1"]')).not.toHaveAttr 'correct_answer', 'true'
@@ -496,7 +524,7 @@ describe 'Problem', ->
@problem.el.prepend(radio_text_xml)
it 'sets the correct class on the section for the correct choice', ->
spyOn($, 'postWithPrefix').andCallFake (url, callback) ->
spyOn($, 'postWithPrefix').and.callFake (url, callback) ->
callback answers: "1_2_1": ["1_2_1_choiceinput_0bc"], "1_2_1_choiceinput_0bc": "3"
@problem.show()
@@ -507,7 +535,7 @@ describe 'Problem', ->
expect($('#answer_1_2_1_choiceinput_2bc').text()).toEqual('')
it 'Should not disable input fields', ->
spyOn($, 'postWithPrefix').andCallFake (url, callback) ->
spyOn($, 'postWithPrefix').and.callFake (url, callback) ->
callback answers: "1_2_1": ["1_2_1_choiceinput_0bc"], "1_2_1_choiceinput_0bc": "3"
@problem.show()
expect($('input#1_2_1_choiceinput_0bc').attr('disabled')).not.toEqual('disabled')
@@ -537,7 +565,7 @@ describe 'Problem', ->
expect(img).toImageDiffEqual(el.find('canvas')[0])
stubRequest = (data) =>
spyOn($, 'postWithPrefix').andCallFake (url, callback) ->
spyOn($, 'postWithPrefix').and.callFake (url, callback) ->
callback data
getImage = (coords, c_width, c_height) =>
@@ -680,51 +708,61 @@ describe 'Problem', ->
@problem.answers = 'foo=1&bar=2'
it 'log the problem_save event', ->
spyOn($, 'postWithPrefix').andCallFake (url, answers, callback) ->
spyOn($, 'postWithPrefix').and.callFake (url, answers, callback) ->
promise =
always: (callable) -> callable()
@problem.save()
expect(Logger.log).toHaveBeenCalledWith 'problem_save', 'foo=1&bar=2'
it 'POST to save problem', ->
spyOn($, 'postWithPrefix').andCallFake (url, answers, callback) ->
spyOn($, 'postWithPrefix').and.callFake (url, answers, callback) ->
promise =
always: (callable) -> callable()
@problem.save()
expect($.postWithPrefix).toHaveBeenCalledWith '/problem/Problem1/problem_save',
'foo=1&bar=2', jasmine.any(Function)
it 'reads the save message', ->
runs ->
spyOn($, 'postWithPrefix').andCallFake (url, answers, callback) ->
callback(success: 'OK')
promise =
always: (callable) -> callable()
it 'reads the save message', (done) ->
deferred = $.Deferred()
runs = ->
spyOn($, 'postWithPrefix').and.callFake (url, answers, callback) ->
promise = undefined
callback success: 'OK'
promise = always: (callable) ->
callable()
@problem.save()
waitsFor (->
return jQuery.active == 0
), "jQuery requests finished", 1000
if jQuery.active == 0
deferred.resolve()
deferred.promise()
runs ->
runs.call(this).then(->
expect(window.SR.readElts).toHaveBeenCalled()
return
).always done
it 'tests if all the buttons are disabled and the text of check button does not change while saving.', ->
runs ->
spyOn($, 'postWithPrefix').andCallFake (url, answers, callback) ->
callback(success: 'OK')
promise =
always: (callable) -> callable()
it 'tests if all the buttons are disabled and the text of check button does not change while saving.', (done) ->
deferred = $.Deferred()
self = this
runs = ->
spyOn($, 'postWithPrefix').and.callFake (url, answers, callback) ->
promise = undefined
callback success: 'OK'
promise = always: (callable) ->
callable()
spyOn @problem, 'enableAllButtons'
@problem.save()
expect(@problem.enableAllButtons).toHaveBeenCalledWith false, false
expect(@problem.checkButtonLabel).toHaveText 'Check'
waitsFor (->
return jQuery.active == 0
), "jQuery requests finished", 1000
if jQuery.active == 0
deferred.resolve()
deferred.promise()
runs ->
expect(@problem.enableAllButtons).toHaveBeenCalledWith true, false
expect(@problem.checkButtonLabel).toHaveText 'Check'
runs.call(self).then(->
expect(self.problem.enableAllButtons).toHaveBeenCalledWith true, false
expect(self.problem.checkButtonLabel).toHaveText 'Check'
).always done
describe 'refreshMath', ->
beforeEach ->
@@ -739,7 +777,7 @@ describe 'Problem', ->
describe 'updateMathML', ->
beforeEach ->
@problem = new Problem($('.xblock-student_view'))
@stubbedJax.root.toMathML.andReturn '<MathML>'
@stubbedJax.root.toMathML.and.returnValue '<MathML>'
describe 'when there is no exception', ->
beforeEach ->
@@ -750,7 +788,9 @@ describe 'Problem', ->
describe 'when there is an exception', ->
beforeEach ->
@stubbedJax.root.toMathML.andThrow {restart: true}
error = new Error()
error.restart = true
@stubbedJax.root.toMathML.and.throwError error
@problem.updateMathML @stubbedJax, $('#input_example_1').get(0)
it 'should queue up the exception', ->
@@ -793,26 +833,29 @@ describe 'Problem', ->
matlabinput_html = readFixtures('matlabinput_problem.html')
beforeEach ->
spyOn($, 'postWithPrefix').andCallFake (url, callback) ->
spyOn($, 'postWithPrefix').and.callFake (url, callback) ->
callback html: matlabinput_html
jasmine.Clock.useMock()
jasmine.clock().install()
@problem = new Problem($('.xblock-student_view'))
spyOn(@problem, 'poll').andCallThrough()
spyOn(@problem, 'poll').and.callThrough()
@problem.render(matlabinput_html)
afterEach ->
jasmine.clock().uninstall()
it 'check that we stop polling after a fixed amount of time', ->
expect(@problem.poll).not.toHaveBeenCalled()
jasmine.Clock.tick(1)
jasmine.clock().tick(1)
time_steps = [1000, 2000, 4000, 8000, 16000, 32000]
num_calls = 1
for time_step in time_steps
do (time_step) =>
jasmine.Clock.tick(time_step)
expect(@problem.poll.callCount).toEqual(num_calls)
jasmine.clock().tick(time_step)
expect(@problem.poll.calls.count()).toEqual(num_calls)
num_calls += 1
# jump the next step and verify that we are not still continuing to poll
jasmine.Clock.tick(64000)
expect(@problem.poll.callCount).toEqual(6)
jasmine.clock().tick(64000)
expect(@problem.poll.calls.count()).toEqual(6)
expect($('.capa_alert').text()).toEqual("The grading process is still running. Refresh the page to see updates.")

View File

@@ -40,8 +40,8 @@
it('Default container initialized correctly', function () {
initialize(html);
expect(el.find('.shortform')).toContain('.full-top');
expect(el.find('.shortform')).toContain('.full-bottom');
expect(el.find('.shortform')).toContainElement('.full-top');
expect(el.find('.shortform')).toContainElement('.full-bottom');
expect(el.find('.longform')).toBeHidden();
expect(el.find('.full')).toHandle('click');
});
@@ -49,7 +49,7 @@
it('Custom container initialized correctly', function () {
initialize(html_custom);
expect(el.find('.shortform-custom')).toContain('.full-custom');
expect(el.find('.shortform-custom')).toContainElement('.full-custom');
expect(el.find('.full-custom')).toHaveText('Show shortform-custom');
expect(el.find('.longform')).toBeHidden();
expect(el.find('.full-custom')).toHandle('click');

View File

@@ -1,5 +1,6 @@
(function () {
'use strict';
var origAjax = $.ajax;
var stubbedYT = {
Player: function () {
@@ -15,9 +16,9 @@
]
);
Player.getDuration.andReturn(60);
Player.getAvailablePlaybackRates.andReturn([0.50, 1.0, 1.50, 2.0]);
Player.getAvailableQualityLevels.andReturn(
Player.getDuration.and.returnValue(60);
Player.getAvailablePlaybackRates.and.returnValue([0.50, 1.0, 1.50, 2.0]);
Player.getAvailableQualityLevels.and.returnValue(
['highres', 'hd1080', 'hd720', 'large', 'medium', 'small']
);
@@ -124,11 +125,11 @@
jasmine.stubRequests = function () {
var spy = $.ajax;
if (!($.ajax.isSpy)) {
if (!jasmine.isSpy($.ajax)) {
spy = spyOn($, 'ajax');
}
return spy.andCallFake(function (settings) {
return spy.and.callFake(function (settings) {
var match = settings.url
.match(/googleapis\.com\/.+\/videos\/\?id=(.+)&part=contentDetails/),
status, callCallback;
@@ -176,46 +177,16 @@
return;
} else if (settings.url === '/save_user_state') {
return {success: true};
} else if(settings.url.match(new RegExp(jasmine.getFixtures().fixturesPath + ".+", 'g'))) {
return origAjax(settings);
} else {
throw 'External request attempted for ' +
settings.url +
', which is not defined.';
$.ajax.and.callThrough();
}
});
};
// Add custom Jasmine matchers.
beforeEach(function () {
this.addMatchers({
toHaveAttrs: function (attrs) {
var element;
if ($.isEmptyObject(attrs)) {
return false;
}
element = this.actual;
return _.every(attrs, function (value, name) {
return element.attr(name) === value;
});
},
toBeInRange: function (min, max) {
return min <= this.actual && this.actual <= max;
},
toBeInArray: function (array) {
return $.inArray(this.actual, array) > -1;
},
toBeFocused: function () {
return $(this.actual)[0] === $(this.actual)[0].ownerDocument.activeElement;
}
});
return this.addMatchers(window.imagediff.jasmine);
});
// Stub jQuery.cookie module.
$.cookie = jasmine.createSpy('jQuery.cookie').andReturn('1.0');
// Stub jQuery.cookie module.
$.cookie = jasmine.createSpy('jQuery.cookie').and.returnValue('1.0');
// # Stub jQuery.qtip module.
$.fn.qtip = jasmine.createSpy('jQuery.qtip');
@@ -224,7 +195,7 @@
$.fn.scrollTo = jasmine.createSpy('jQuery.scrollTo');
// Stub window.Video.loadYouTubeIFrameAPI()
window.Video.loadYouTubeIFrameAPI = jasmine.createSpy('window.Video.loadYouTubeIFrameAPI').andReturn(
window.Video.loadYouTubeIFrameAPI = jasmine.createSpy('window.Video.loadYouTubeIFrameAPI').and.returnValue(
function (scriptTag) {
var event = document.createEvent('Event');
if (fixture === "video.html") {
@@ -275,13 +246,13 @@
],
obj = {},
delta = {
add: jasmine.createSpy().andReturn(obj),
substract: jasmine.createSpy().andReturn(obj),
reset: jasmine.createSpy().andReturn(obj)
add: jasmine.createSpy().and.returnValue(obj),
substract: jasmine.createSpy().and.returnValue(obj),
reset: jasmine.createSpy().and.returnValue(obj)
};
$.each(methods, function (index, method) {
obj[method] = jasmine.createSpy(method).andReturn(obj);
obj[method] = jasmine.createSpy(method).and.returnValue(obj);
});
obj.delta = delta;

View File

@@ -10,21 +10,21 @@ describe 'HTMLEditingDescriptor', ->
it 'Returns data from Visual Editor if text has changed', ->
visualEditorStub =
getContent: () -> 'from visual editor'
spyOn(@descriptor, 'getVisualEditor').andCallFake () ->
spyOn(@descriptor, 'getVisualEditor').and.callFake () ->
visualEditorStub
data = @descriptor.save().data
expect(data).toEqual('from visual editor')
it 'Returns data from Raw Editor if text has not changed', ->
visualEditorStub =
getContent: () -> '<p>original visual text</p>'
spyOn(@descriptor, 'getVisualEditor').andCallFake () ->
spyOn(@descriptor, 'getVisualEditor').and.callFake () ->
visualEditorStub
data = @descriptor.save().data
expect(data).toEqual('raw text')
it 'Performs link rewriting for static assets when saving', ->
visualEditorStub =
getContent: () -> 'from visual editor with /c4x/foo/bar/asset/image.jpg'
spyOn(@descriptor, 'getVisualEditor').andCallFake () ->
spyOn(@descriptor, 'getVisualEditor').and.callFake () ->
visualEditorStub
data = @descriptor.save().data
expect(data).toEqual('from visual editor with /static/image.jpg')

View File

@@ -24,7 +24,7 @@ describe 'MarkdownEditingDescriptor', ->
it 'click on advanced editor should work', ->
loadFixtures 'problem-with-markdown.html'
@descriptor = new MarkdownEditingDescriptor($('.problem-editor'))
spyOn(@descriptor, 'confirmConversionToXml').andReturn(true)
spyOn(@descriptor, 'confirmConversionToXml').and.returnValue(true)
expect(@descriptor.confirmConversionToXml).not.toHaveBeenCalled()
e = jasmine.createSpyObj('e', [ 'preventDefault' ])
@descriptor.onShowXMLButton(e)

View File

@@ -14,8 +14,8 @@ describe "TabsEditingDescriptor", ->
TabsEditingDescriptor.Model.addModelUpdate(@html_id, 'Tab 1 Transcripts', @tab_1_modelUpdate)
TabsEditingDescriptor.Model.addOnSwitch(@html_id, 'Tab 1 Transcripts', @tab_1_switch)
spyOn($.fn, 'hide').andCallThrough()
spyOn($.fn, 'show').andCallThrough()
spyOn($.fn, 'hide').and.callThrough()
spyOn($.fn, 'show').and.callThrough()
spyOn(TabsEditingDescriptor.Model, 'initialize')
spyOn(TabsEditingDescriptor.Model, 'updateValue')
@@ -37,11 +37,11 @@ describe "TabsEditingDescriptor", ->
expect(@tab_1_switch).toHaveBeenCalled()
it "if click on current tab, nothing should happen", ->
spyOn($.fn, 'trigger').andCallThrough()
spyOn($.fn, 'trigger').and.callThrough()
currentTab = @descriptor.$tabs.filter('.' + @isCurrent)
@descriptor.$tabs.eq(0).trigger("click")
expect(@descriptor.$tabs.filter('.' + @isCurrent)).toEqual(currentTab)
expect($.fn.trigger.calls.length).toEqual(1)
expect($.fn.trigger.calls.count()).toEqual(1)
it "onSwitch function call", ->
@descriptor.$tabs.eq(1).trigger("click")
@@ -82,7 +82,7 @@ describe "TabsEditingDescriptor special save cases", ->
expect(data).toEqual(null)
it "case: no function in model update, but value presented", ->
@tab_0_modelUpdate = jasmine.createSpy('tab_0_modelUpdate').andReturn(1)
@tab_0_modelUpdate = jasmine.createSpy('tab_0_modelUpdate').and.returnValue(1)
TabsEditingDescriptor.Model.addModelUpdate(@html_id, 'Tab 0 Editor', @tab_0_modelUpdate)
@descriptor.$tabs.eq(1).trigger("click")
expect(@tab_0_modelUpdate).toHaveBeenCalled()

View File

@@ -15,82 +15,66 @@ function (AsyncProcess) {
items = getArrayNthLength(1000);
describe('AsyncProcess', function () {
it ('Array is processed successfully', function () {
it ('Array is processed successfully', function (done) {
var processedArray,
expectedArray = getArrayNthLength(1000, 2),
process = function (item) {
return 2 * item;
};
runs(function () {
AsyncProcess.array(items, process).done(function (result) {
processedArray = result;
});
AsyncProcess.array(items, process).done(function (result) {
processedArray = result;
});
waitsFor(function () {
jasmine.waitUntil(function () {
return processedArray;
}, 'Array processing takes too much time', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(processedArray).toEqual(expectedArray);
});
}).always(done);
});
it ('If non-array is passed, error callback is called', function () {
it ('If non-array is passed, error callback is called', function (done) {
var isError,
process = function () {};
runs(function () {
AsyncProcess.array('string', process).fail(function () {
isError = true;
});
AsyncProcess.array('string', process).fail(function () {
isError = true;
});
waitsFor(function () {
jasmine.waitUntil(function () {
return isError;
}, 'Error callback wasn\'t called', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(isError).toBeTruthy();
});
}).always(done);
});
it ('If an empty array is passed, returns initial array', function () {
it ('If an empty array is passed, returns initial array', function (done) {
var processedArray,
process = function () {};
runs(function () {
AsyncProcess.array([], process).done(function (result) {
processedArray = result;
});
AsyncProcess.array([], process).done(function (result) {
processedArray = result;
});
waitsFor(function () {
jasmine.waitUntil(function () {
return processedArray;
}, 'Array processing takes too much time', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(processedArray).toEqual([]);
});
}).always(done);
});
it ('If no process function passed, returns initial array', function () {
it ('If no process function passed, returns initial array', function (done) {
var processedArray;
runs(function () {
AsyncProcess.array(items).done(function (result) {
processedArray = result;
});
AsyncProcess.array(items).done(function (result) {
processedArray = result;
});
waitsFor(function () {
jasmine.waitUntil(function () {
return processedArray;
}, 'Array processing takes too much time', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(processedArray).toEqual(items);
});
}).always(done);
});
});
});

View File

@@ -7,9 +7,7 @@
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice')
.andReturn(null);
jasmine.stubRequests();
.and.returnValue(null);
state = jasmine.initializePlayer();
@@ -20,26 +18,23 @@
$('source').remove();
window.onTouchBasedDevice = oldOTBD;
state.storage.clear();
state.videoPlayer.destroy();
});
it('initialize', function () {
waitsFor(function () {
it('initialize', function (done) {
jasmine.waitUntil(function () {
return state.el.hasClass('is-initialized');
}, 'Player is not initialized.', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect('initialize').not.toHaveBeenTriggeredOn('.video');
});
}).always(done);
});
it('ready', function () {
waitsFor(function () {
it('ready', function (done) {
jasmine.waitUntil(function () {
return state.el.hasClass('is-initialized');
}, 'Player is not initialized.', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect('ready').not.toHaveBeenTriggeredOn('.video');
});
}).always(done);
});
it('play', function () {
@@ -86,9 +81,7 @@
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice')
.andReturn(null);
jasmine.stubRequests();
.and.returnValue(null);
state = jasmine.initializePlayerYouTube();
});
@@ -96,6 +89,8 @@
afterEach(function () {
$('source').remove();
window.onTouchBasedDevice = oldOTBD;
state.storage.clear();
state.videoPlayer.destroy();
});
it('qualitychange', function () {

View File

@@ -2,26 +2,27 @@
describe('Video', function () {
var oldOTBD, state;
beforeEach(function () {
jasmine.stubRequests();
});
afterEach(function () {
$('source').remove();
window.VideoState = {};
window.VideoState.id = {};
window.YT = jasmine.YT;
});
describe('constructor', function () {
describe('YT', function () {
beforeEach(function () {
loadFixtures('video.html');
$.cookie.andReturn('0.50');
this.state = jasmine.initializePlayerYouTube('video_html5.html');
$.cookie.and.returnValue('0.50');
});
describe('by default', function () {
beforeEach(function () {
this.state = jasmine.initializePlayerYouTube('video_html5.html');
});
afterEach(function () {
this.state.storage.clear();
this.state.videoPlayer.destroy();
});
@@ -30,7 +31,7 @@
});
it('set the elements', function () {
expect(this.state.el).toBe('#video_id');
expect(this.state.el).toEqual($('#video_id'));
});
it('parse the videos', function () {
@@ -55,13 +56,13 @@
var state;
beforeEach(function () {
$.cookie.andReturn('0.75');
$.cookie.and.returnValue('0.75');
state = jasmine.initializePlayer('video_html5.html');
});
afterEach(function () {
state.storage.clear();
state.videoPlayer.destroy();
state = undefined;
});
describe('by default', function () {
@@ -70,7 +71,7 @@
});
it('set the elements', function () {
expect(state.el).toBe('#video_id');
expect(state.el).toEqual($('#video_id'));
});
it('doesn\'t have `videos` dictionary', function () {
@@ -101,35 +102,34 @@
});
describe('YouTube API is not loaded', function () {
var state;
beforeEach(function () {
window.YT = undefined;
state = jasmine.initializePlayerYouTube();
})
});
afterEach(function () {
state.storage.clear();
state.videoPlayer.destroy();
});
it('callback, to be called after YouTube API loads, exists and is called', function () {
waitsFor(function () {
return state.youtubeApiAvailable === true;
}, 'YouTube API is loaded', 3000);
it('callback, to be called after YouTube API loads, exists and is called', function (done) {
window.YT = jasmine.YT;
// Call the callback that must be called when YouTube API is
// loaded. By specification.
window.onYouTubeIframeAPIReady();
runs(function () {
jasmine.waitUntil(function () {
return state.youtubeApiAvailable === true;
}).done(function(){
// If YouTube API is not loaded, then the code will should create
// a global callback that will be called by API once it is loaded.
expect(window.onYouTubeIframeAPIReady).not.toBeUndefined();
});
}).always(done);
});
});
describe('checking start and end times', function () {
var state;
var miniTestSuite = [
{
itDescription: 'both times are proper',
@@ -159,6 +159,7 @@
];
afterEach(function () {
state.storage.clear();
state.videoPlayer.destroy();
});

View File

@@ -1,17 +1,19 @@
(function (undefined) {
describe('Video HTML5Video', function () {
var STATUS = window.STATUS;
var state, oldOTBD, playbackRates = [0.75, 1.0, 1.25, 1.5];
beforeEach(function () {
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice').andReturn(null);
.createSpy('onTouchBasedDevice').and.returnValue(null);
});
afterEach(function () {
state.storage.clear();
state.videoPlayer.destroy();
$.fn.scrollTo.reset();
$.fn.scrollTo.calls.reset();
$('source').remove();
window.onTouchBasedDevice = oldOTBD;
});
@@ -25,13 +27,13 @@
describe('events:', function () {
beforeEach(function () {
spyOn(state.videoPlayer.player, 'callStateChangeCallback').andCallThrough();
spyOn(state.videoPlayer.player, 'callStateChangeCallback').and.callThrough();
});
describe('[click]', function () {
describe('when player is paused', function () {
beforeEach(function () {
spyOn(state.videoPlayer.player.video, 'play').andCallThrough();
spyOn(state.videoPlayer.player.video, 'play').and.callThrough();
state.videoPlayer.player.playerState = STATUS.PAUSED;
$(state.videoPlayer.player.videoEl).trigger('click');
});
@@ -40,32 +42,25 @@
expect(state.videoPlayer.player.video.play).toHaveBeenCalled();
});
it('player state was changed', function () {
waitsFor(function () {
return state.videoPlayer.player.getPlayerState() !== STATUS.PAUSED;
}, 'Player state should be changed', WAIT_TIMEOUT);
runs(function () {
expect(state.videoPlayer.player.getPlayerState())
.toBe(STATUS.PLAYING);
});
it('player state was changed', function (done) {
jasmine.waitUntil(function () {
return state.videoPlayer.player.getPlayerState() === STATUS.PLAYING;
}).always(done);
});
it('callback was not called', function () {
waitsFor(function () {
// Flaky. Checking the parameters of calls to onStateChange() will likely be more reliable.
xit('callback was not called', function (done) {
jasmine.waitUntil(function () {
return state.videoPlayer.player.getPlayerState() !== STATUS.PAUSED;
}, 'Player state should be changed', WAIT_TIMEOUT);
runs(function () {
expect(state.videoPlayer.player.callStateChangeCallback)
.not.toHaveBeenCalled();
});
}).then(function () {
expect(state.videoPlayer.player.callStateChangeCallback).not.toHaveBeenCalled();
}).always(done);
});
});
describe('[player is playing]', function () {
beforeEach(function () {
spyOn(state.videoPlayer.player.video, 'pause').andCallThrough();
spyOn(state.videoPlayer.player.video, 'pause').and.callThrough();
state.videoPlayer.player.playerState = STATUS.PLAYING;
$(state.videoPlayer.player.videoEl).trigger('click');
});
@@ -74,33 +69,29 @@
expect(state.videoPlayer.player.video.pause).toHaveBeenCalled();
});
it('player state was changed', function () {
waitsFor(function () {
it('player state was changed', function (done) {
jasmine.waitUntil(function () {
return state.videoPlayer.player.getPlayerState() !== STATUS.PLAYING;
}, 'Player state should be changed', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(state.videoPlayer.player.getPlayerState())
.toBe(STATUS.PAUSED);
});
}).always(done);
});
it('callback was not called', function () {
waitsFor(function () {
it('callback was not called', function (done) {
jasmine.waitUntil(function () {
return state.videoPlayer.player.getPlayerState() !== STATUS.PLAYING;
}, 'Player state should be changed', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(state.videoPlayer.player.callStateChangeCallback)
.not.toHaveBeenCalled();
});
}).always(done);
});
});
});
describe('[play]', function () {
beforeEach(function () {
spyOn(state.videoPlayer.player.video, 'play').andCallThrough();
spyOn(state.videoPlayer.player.video, 'play').and.callThrough();
state.videoPlayer.player.playerState = STATUS.PAUSED;
state.videoPlayer.player.playVideo();
});
@@ -110,37 +101,35 @@
});
it('player state was changed', function () {
waitsFor(function () {
it('player state was changed', function (done) {
jasmine.waitUntil(function () {
return state.videoPlayer.player.getPlayerState() !== STATUS.PAUSED;
}, 'Player state should be changed', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(state.videoPlayer.player.getPlayerState())
.toBe(STATUS.BUFFERING);
});
}).always(done);
});
it('callback was called', function () {
waitsFor(function () {
it('callback was called', function (done) {
jasmine.waitUntil(function () {
return state.videoPlayer.player.getPlayerState() !== STATUS.PAUSED;
}, 'Player state should be changed', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(state.videoPlayer.player.callStateChangeCallback)
.toHaveBeenCalled();
});
}).always(done);
});
});
describe('[pause]', function () {
beforeEach(function () {
spyOn(state.videoPlayer.player.video, 'pause').andCallThrough();
beforeEach(function (done) {
spyOn(state.videoPlayer.player.video, 'pause').and.callThrough();
state.videoPlayer.player.playerState = STATUS.UNSTARTED;
state.videoPlayer.player.playVideo();
waitsFor(function () {
jasmine.waitUntil(function () {
return state.videoPlayer.player.getPlayerState() !== STATUS.UNSTARTED;
}, 'Video never started playing', WAIT_TIMEOUT);
}).done(done);
state.videoPlayer.player.pauseVideo();
});
@@ -148,59 +137,54 @@
expect(state.videoPlayer.player.video.pause).toHaveBeenCalled();
});
it('player state was changed', function () {
waitsFor(function () {
it('player state was changed', function (done) {
jasmine.waitUntil(function () {
return state.videoPlayer.player.getPlayerState() !== STATUS.PLAYING;
}, 'Player state should be changed', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(state.videoPlayer.player.getPlayerState())
.toBe(STATUS.PAUSED);
});
}).always(done);
});
it('callback was called', function () {
waitsFor(function () {
it('callback was called', function (done) {
jasmine.waitUntil(function () {
return state.videoPlayer.player.getPlayerState() !== STATUS.PLAYING;
}, 'Player state should be changed', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(state.videoPlayer.player.callStateChangeCallback)
.toHaveBeenCalled();
});
}).always(done);
});
});
describe('[loadedmetadata]', function () {
it(
'player state was changed, start/end was defined, ' +
'onReady called', function ()
'onReady called', function (done)
{
waitsFor(function () {
jasmine.fireEvent(state.videoPlayer.player.video, 'loadedmetadata');
jasmine.waitUntil(function () {
return state.videoPlayer.player.getPlayerState() !== STATUS.UNSTARTED;
}, 'Video cannot be played', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(state.videoPlayer.player.getPlayerState())
.toBe(STATUS.PAUSED);
expect(state.videoPlayer.player.video.currentTime).toBe(0);
expect(state.videoPlayer.player.config.events.onReady)
.toHaveBeenCalled();
});
}).always(done);
});
});
describe('[ended]', function () {
beforeEach(function () {
waitsFor(function () {
beforeEach(function (done) {
state.videoPlayer.player.playVideo();
jasmine.waitUntil(function () {
return state.videoPlayer.player.getPlayerState() !== STATUS.UNSTARTED;
}, 'Video cannot be played', WAIT_TIMEOUT);
}).done(done);
});
it('player state was changed', function () {
runs(function () {
jasmine.fireEvent(state.videoPlayer.player.video, 'ended');
expect(state.videoPlayer.player.getPlayerState()).toBe(STATUS.ENDED);
});
jasmine.fireEvent(state.videoPlayer.player.video, 'ended');
expect(state.videoPlayer.player.getPlayerState()).toBe(STATUS.ENDED);
});
it('callback was called', function () {
@@ -215,98 +199,90 @@
var volume, seek, duration, playbackRate;
beforeEach(function () {
waitsFor(function () {
volume = state.videoPlayer.player.video.volume;
seek = state.videoPlayer.player.video.currentTime;
return state.videoPlayer.player.playerState === STATUS.PAUSED;
}, 'Video cannot be played', WAIT_TIMEOUT);
volume = state.videoPlayer.player.video.volume;
});
it('pauseVideo', function () {
runs(function () {
spyOn(state.videoPlayer.player.video, 'pause').andCallThrough();
state.videoPlayer.player.pauseVideo();
expect(state.videoPlayer.player.video.pause).toHaveBeenCalled();
});
spyOn(state.videoPlayer.player.video, 'pause').and.callThrough();
state.videoPlayer.player.pauseVideo();
expect(state.videoPlayer.player.video.pause).toHaveBeenCalled();
});
describe('seekTo', function () {
it('set new correct value', function () {
runs(function () {
it('set new correct value', function (done) {
state.videoPlayer.player.playVideo();
jasmine.waitUntil(function () {
return state.videoPlayer.player.getPlayerState() === STATUS.PLAYING;
}).then(function() {
state.videoPlayer.player.seekTo(2);
expect(state.videoPlayer.player.getCurrentTime()).toBe(2);
});
}).done(done);
});
it('set new inccorrect values', function () {
runs(function () {
state.videoPlayer.player.seekTo(-50);
expect(state.videoPlayer.player.getCurrentTime()).toBe(seek);
state.videoPlayer.player.seekTo('5');
expect(state.videoPlayer.player.getCurrentTime()).toBe(seek);
state.videoPlayer.player.seekTo(500000);
expect(state.videoPlayer.player.getCurrentTime()).toBe(seek);
});
var seek = state.videoPlayer.player.video.currentTime;
state.videoPlayer.player.seekTo(-50);
expect(state.videoPlayer.player.getCurrentTime()).toBe(seek);
state.videoPlayer.player.seekTo('5');
expect(state.videoPlayer.player.getCurrentTime()).toBe(seek);
state.videoPlayer.player.seekTo(500000);
expect(state.videoPlayer.player.getCurrentTime()).toBe(seek);
});
});
describe('setVolume', function () {
it('set new correct value', function () {
runs(function () {
state.videoPlayer.player.setVolume(50);
expect(state.videoPlayer.player.getVolume()).toBe(50 * 0.01);
});
state.videoPlayer.player.setVolume(50);
expect(state.videoPlayer.player.getVolume()).toBe(50 * 0.01);
});
it('set new incorrect values', function () {
runs(function () {
state.videoPlayer.player.setVolume(-50);
expect(state.videoPlayer.player.getVolume()).toBe(volume);
state.videoPlayer.player.setVolume('5');
expect(state.videoPlayer.player.getVolume()).toBe(volume);
state.videoPlayer.player.setVolume(500000);
expect(state.videoPlayer.player.getVolume()).toBe(volume);
});
});
});
it('getCurrentTime', function () {
runs(function () {
state.videoPlayer.player.video.currentTime = 3;
expect(state.videoPlayer.player.getCurrentTime())
.toBe(state.videoPlayer.player.video.currentTime);
});
});
it('playVideo', function () {
runs(function () {
spyOn(state.videoPlayer.player.video, 'play').andCallThrough();
state.videoPlayer.player.playVideo();
expect(state.videoPlayer.player.video.play).toHaveBeenCalled();
});
});
it('getPlayerState', function () {
runs(function () {
state.videoPlayer.player.playerState = STATUS.PLAYING;
expect(state.videoPlayer.player.getPlayerState()).toBe(STATUS.PLAYING);
state.videoPlayer.player.playerState = STATUS.ENDED;
expect(state.videoPlayer.player.getPlayerState()).toBe(STATUS.ENDED);
});
});
it('getVolume', function () {
runs(function () {
volume = state.videoPlayer.player.video.volume = 0.5;
state.videoPlayer.player.setVolume(-50);
expect(state.videoPlayer.player.getVolume()).toBe(volume);
state.videoPlayer.player.setVolume('5');
expect(state.videoPlayer.player.getVolume()).toBe(volume);
state.videoPlayer.player.setVolume(500000);
expect(state.videoPlayer.player.getVolume()).toBe(volume);
});
});
it('getDuration', function () {
runs(function () {
it('getCurrentTime', function (done) {
state.videoPlayer.player.playVideo();
jasmine.waitUntil(function () {
return state.videoPlayer.player.getPlayerState() === STATUS.PLAYING;
}).then(function() {
state.videoPlayer.player.video.currentTime = 3;
expect(state.videoPlayer.player.getCurrentTime())
.toBe(state.videoPlayer.player.video.currentTime);
}).done(done);
});
it('playVideo', function () {
spyOn(state.videoPlayer.player.video, 'play').and.callThrough();
state.videoPlayer.player.playVideo();
expect(state.videoPlayer.player.video.play).toHaveBeenCalled();
});
it('getPlayerState', function () {
state.videoPlayer.player.playerState = STATUS.PLAYING;
expect(state.videoPlayer.player.getPlayerState()).toBe(STATUS.PLAYING);
state.videoPlayer.player.playerState = STATUS.ENDED;
expect(state.videoPlayer.player.getPlayerState()).toBe(STATUS.ENDED);
});
it('getVolume', function () {
volume = state.videoPlayer.player.video.volume = 0.5;
expect(state.videoPlayer.player.getVolume()).toBe(volume);
});
it('getDuration', function (done) {
state.videoPlayer.player.playVideo();
jasmine.waitUntil(function () {
return state.videoPlayer.player.getPlayerState() === STATUS.PLAYING;
}).then(function () {
duration = state.videoPlayer.player.video.duration;
expect(state.videoPlayer.player.getDuration()).toBe(duration);
});
}).always(done);
});
describe('setPlaybackRate', function () {
@@ -333,18 +309,21 @@
.toEqual(playbackRates);
});
it('_getLogs', function () {
runs(function () {
it('_getLogs', function (done) {
state.videoPlayer.player.playVideo();
jasmine.waitUntil(function () {
return state.videoPlayer.player.getPlayerState() === STATUS.PLAYING;
}).then(function() {
var logs = state.videoPlayer.player._getLogs();
expect(logs).toEqual(jasmine.any(Array));
expect(logs.length).toBeGreaterThan(0);
});
}).done(done);
});
});
});
it('native controls are used on iPhone', function () {
window.onTouchBasedDevice.andReturn(['iPhone']);
window.onTouchBasedDevice.and.returnValue(['iPhone']);
state = jasmine.initializePlayer('video_html5.html');

View File

@@ -82,7 +82,7 @@ function (Initialize) {
'1.50': 'videoId'
},
youtubeId: Initialize.prototype.youtubeId,
isFlashMode: jasmine.createSpy().andReturn(false)
isFlashMode: jasmine.createSpy().and.returnValue(false)
};
});
@@ -100,7 +100,7 @@ function (Initialize) {
it('returns duration for current video', function () {
var expected;
state.isFlashMode.andReturn(true);
state.isFlashMode.and.returnValue(true);
expected = Initialize.prototype.getDuration.call(state);
expect(expected).toEqual(100);
@@ -110,7 +110,7 @@ function (Initialize) {
it(msg, function () {
var expected;
state.isFlashMode.andReturn(true);
state.isFlashMode.and.returnValue(true);
state.speed = '2.0';
expected = Initialize.prototype.getDuration.call(state);
@@ -128,7 +128,7 @@ function (Initialize) {
'1.0': 'cogebirgzzM',
'1.50': 'abcdefghijkl'
},
isFlashMode: jasmine.createSpy().andReturn(false)
isFlashMode: jasmine.createSpy().and.returnValue(false)
};
});
@@ -148,7 +148,7 @@ function (Initialize) {
it('return the video id for current speed', function () {
var expected;
state.isFlashMode.andReturn(true);
state.isFlashMode.and.returnValue(true);
expected = Initialize.prototype.youtubeId.call(state);
expect(expected).toEqual('abcdefghijkl');
@@ -279,7 +279,7 @@ function (Initialize) {
describe('isFlashMode', function () {
it('returns `true` if player in `flash` mode', function () {
var state = {
getPlayerMode: jasmine.createSpy().andReturn('flash'),
getPlayerMode: jasmine.createSpy().and.returnValue('flash'),
},
isFlashMode = Initialize.prototype.isFlashMode,
actual = isFlashMode.call(state);
@@ -289,7 +289,7 @@ function (Initialize) {
it('returns `false` if player is not in `flash` mode', function () {
var state = {
getPlayerMode: jasmine.createSpy().andReturn('html5'),
getPlayerMode: jasmine.createSpy().and.returnValue('html5'),
},
isFlashMode = Initialize.prototype.isFlashMode,
actual = isFlashMode.call(state);
@@ -301,7 +301,7 @@ function (Initialize) {
describe('isHtml5Mode', function () {
it('returns `true` if player in `html5` mode', function () {
var state = {
getPlayerMode: jasmine.createSpy().andReturn('html5'),
getPlayerMode: jasmine.createSpy().and.returnValue('html5'),
},
isHtml5Mode = Initialize.prototype.isHtml5Mode,
actual = isHtml5Mode.call(state);
@@ -311,7 +311,7 @@ function (Initialize) {
it('returns `false` if player is not in `html5` mode', function () {
var state = {
getPlayerMode: jasmine.createSpy().andReturn('flash'),
getPlayerMode: jasmine.createSpy().and.returnValue('flash'),
},
isHtml5Mode = Initialize.prototype.isHtml5Mode,
actual = isHtml5Mode.call(state);

View File

@@ -139,7 +139,7 @@ function (Resizer) {
.align()
.alignByHeightOnly();
expect(spiesList[0].calls.length).toEqual(1);
expect(spiesList[0].calls.count()).toEqual(1);
});
it('all callbacks are removed', function () {
@@ -180,7 +180,7 @@ function (Resizer) {
resizer.callbacks[methodName](arg);
expect(console.error).toHaveBeenCalledWith(errorMessage);
//reset spy
console.log.reset();
console.log.calls.reset();
});
});

View File

@@ -101,7 +101,7 @@
menuList = container.children('ol.a11y-menu-list');
menuItems = menuList.children('li.a11y-menu-item');
menuItemsLinks = menuItems.children('a.a11y-menu-item-link');
spyOn($.fn, 'focus').andCallThrough();
spyOn($.fn, 'focus').and.callThrough();
});
it('open/close the menu on mouseenter/mouseleave', function () {
@@ -173,7 +173,7 @@
}
// Test if each element has been called twice.
expect($.fn.focus.calls.length)
expect($.fn.focus.calls.count())
.toEqual(2*menuItemsLinks.length+1);
});
@@ -258,7 +258,7 @@
beforeEach(function () {
state = jasmine.initializePlayer();
state.videoSpeedControl.setSpeed(1.0);
spyOn(state.videoPlayer, 'onSpeedChange').andCallThrough();
spyOn(state.videoPlayer, 'onSpeedChange').and.callThrough();
$('li[data-speed="0.75"] .speed-link').click();
});

View File

@@ -3,19 +3,19 @@
describe('VideoBumper', function () {
var state, oldOTBD, waitForPlaying;
waitForPlaying = function (state) {
waitsFor(function () {
waitForPlaying = function (state, done) {
jasmine.waitUntil(function () {
return state.el.hasClass('is-playing');
}, 'Player is not playing.', WAIT_TIMEOUT);
}).done(done);
};
beforeEach(function () {
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice').andReturn(null);
.createSpy('onTouchBasedDevice').and.returnValue(null);
state = jasmine.initializePlayer('video_with_bumper.html');
$('.poster .btn-play').click();
jasmine.Clock.useMock();
jasmine.clock().install();
});
afterEach(function () {
@@ -28,45 +28,46 @@
state.videoPlayer.destroy();
}
window.onTouchBasedDevice = oldOTBD;
jasmine.clock().uninstall();
});
it('can render the bumper video', function () {
expect($('.is-bumper')).toExist();
});
it('can show the main video on error', function () {
it('can show the main video on error', function (done) {
state.el.trigger('error');
jasmine.Clock.tick(20);
jasmine.clock().tick(20);
expect($('.is-bumper')).not.toExist();
waitForPlaying(state);
waitForPlaying(state, done);
});
it('can show the main video once bumper ends', function () {
it('can show the main video once bumper ends', function (done) {
state.el.trigger('ended');
jasmine.Clock.tick(20);
jasmine.clock().tick(20);
expect($('.is-bumper')).not.toExist();
waitForPlaying(state);
waitForPlaying(state, done);
});
it('can show the main video on skip', function () {
it('can show the main video on skip', function (done) {
state.bumperState.videoBumper.skip();
jasmine.Clock.tick(20);
jasmine.clock().tick(20);
expect($('.is-bumper')).not.toExist();
waitForPlaying(state);
waitForPlaying(state, done);
});
it('can stop the bumper video playing if it is too long', function () {
it('can stop the bumper video playing if it is too long', function (done) {
state.el.trigger('timeupdate', [state.bumperState.videoBumper.maxBumperDuration + 1]);
jasmine.Clock.tick(20);
jasmine.clock().tick(20);
expect($('.is-bumper')).not.toExist();
waitForPlaying(state);
waitForPlaying(state, done);
});
it('can save appropriate states correctly on ended', function () {
var saveState = jasmine.createSpy('saveState');
state.bumperState.videoSaveStatePlugin.saveState = saveState;
state.el.trigger('ended');
jasmine.Clock.tick(20);
jasmine.clock().tick(20);
expect(saveState).toHaveBeenCalledWith(true, {
bumper_last_view_date: true});
});
@@ -76,7 +77,7 @@
state.bumperState.videoSaveStatePlugin.saveState = saveState;
state.bumperState.videoBumper.skip();
expect(state.storage.getItem('isBumperShown')).toBeTruthy();
jasmine.Clock.tick(20);
jasmine.clock().tick(20);
expect(saveState).toHaveBeenCalledWith(true, {
bumper_last_view_date: true});
});
@@ -86,7 +87,7 @@
state.bumperState.videoSaveStatePlugin.saveState = saveState;
state.el.trigger('error');
expect(state.storage.getItem('isBumperShown')).toBeTruthy();
jasmine.Clock.tick(20);
jasmine.clock().tick(20);
expect(saveState).toHaveBeenCalledWith(true, {
bumper_last_view_date: true});
});
@@ -96,7 +97,7 @@
state.bumperState.videoSaveStatePlugin.saveState = saveState;
state.bumperState.videoBumper.skipAndDoNotShowAgain();
expect(state.storage.getItem('isBumperShown')).toBeTruthy();
jasmine.Clock.tick(20);
jasmine.clock().tick(20);
expect(saveState).toHaveBeenCalledWith(true, {
bumper_last_view_date: true, bumper_do_not_show_again: true});
});

View File

@@ -1,13 +1,16 @@
(function (undefined) {
describe('VideoCaption', function () {
var state, oldOTBD;
var parseIntAttribute = function (element, attrName) {
return parseInt(element.attr(attrName));
};
beforeEach(function () {
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice')
.andReturn(null);
.and.returnValue(null);
$.fn.scrollTo.reset();
$.fn.scrollTo.calls.reset();
});
afterEach(function () {
@@ -15,7 +18,7 @@
// had before. Removing of `source` tag, not `video` tag, stops
// loading video source and clears the memory.
$('source').remove();
$.fn.scrollTo.reset();
$.fn.scrollTo.calls.reset();
state.storage.clear();
state.videoPlayer.destroy();
@@ -27,17 +30,17 @@
describe('always', function () {
beforeEach(function () {
spyOn($, 'ajaxWithPrefix').andCallThrough();
spyOn($, 'ajaxWithPrefix').and.callThrough();
});
it('create the transcript element', function () {
state = jasmine.initializePlayer();
expect($('.video')).toContain('.subtitles');
expect($('.video')).toContainElement('.subtitles');
});
it('add transcript control to video player', function () {
state = jasmine.initializePlayer();
expect($('.video')).toContain('.toggle-transcript');
expect($('.video')).toContainElement('.toggle-transcript');
});
it('add ARIA attributes to transcript control', function () {
@@ -50,20 +53,16 @@
it('adds the captioning control to the video player', function() {
state = jasmine.initializePlayer();
expect($('.video')).toContain('.toggle-captions');
expect($('.video')).toContain('.closed-captions');
expect($('.video')).toContainElement('.toggle-captions');
expect($('.video')).toContainElement('.closed-captions');
});
it('fetch the transcript in HTML5 mode', function () {
runs(function () {
state = jasmine.initializePlayer();
});
it('fetch the transcript in HTML5 mode', function (done) {
state = jasmine.initializePlayer();
waitsFor(function () {
jasmine.waitUntil(function () {
return state.videoCaption.loaded;
}, 'Expect transcript to be loaded.', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect($.ajaxWithPrefix).toHaveBeenCalledWith({
url: '/transcript/translation/en',
notifyOnError: false,
@@ -71,23 +70,19 @@
success: jasmine.any(Function),
error: jasmine.any(Function)
});
expect($.ajaxWithPrefix.mostRecentCall.args[0].data)
expect($.ajaxWithPrefix.calls.mostRecent().args[0].data)
.toBeUndefined();
});
}).always(done);
});
it('fetch the transcript in Flash mode', function () {
runs(function () {
state = jasmine.initializePlayerYouTube();
spyOn(state, 'isFlashMode').andReturn(true);
state.videoCaption.fetchCaption();
});
it('fetch the transcript in Flash mode', function (done) {
state = jasmine.initializePlayerYouTube();
spyOn(state, 'isFlashMode').and.returnValue(true);
state.videoCaption.fetchCaption();
waitsFor(function () {
jasmine.waitUntil(function () {
return state.videoCaption.loaded;
}, 'Expect transcript to be loaded.', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect($.ajaxWithPrefix).toHaveBeenCalledWith({
url: '/transcript/translation/en',
notifyOnError: false,
@@ -95,23 +90,19 @@
success: jasmine.any(Function),
error: jasmine.any(Function)
});
expect($.ajaxWithPrefix.mostRecentCall.args[0].data)
expect($.ajaxWithPrefix.calls.mostRecent().args[0].data)
.toEqual({
videoId: 'cogebirgzzM'
});
});
}).always(done);
});
it('fetch the transcript in Youtube mode', function () {
runs(function () {
state = jasmine.initializePlayerYouTube();
});
it('fetch the transcript in Youtube mode', function (done) {
state = jasmine.initializePlayerYouTube();
waitsFor(function () {
jasmine.waitUntil(function () {
return state.videoCaption.loaded;
}, 'Expect transcript to be loaded.', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect($.ajaxWithPrefix).toHaveBeenCalledWith({
url: '/transcript/translation/en',
notifyOnError: false,
@@ -119,11 +110,11 @@
success: jasmine.any(Function),
error: jasmine.any(Function)
});
expect($.ajaxWithPrefix.mostRecentCall.args[0].data)
expect($.ajaxWithPrefix.calls.mostRecent().args[0].data)
.toEqual({
videoId: 'cogebirgzzM'
});
});
}).always(done);
});
it('bind the mouse movement', function () {
@@ -148,7 +139,7 @@
state = jasmine.initializePlayer();
var plugin = state.videoCaption;
spyOn($.fn, 'off').andCallThrough();
spyOn($.fn, 'off').and.callThrough();
state.videoCaption.destroy();
expect(state.videoCaption).toBeUndefined();
@@ -316,104 +307,90 @@
});
describe('when on a non touch-based device', function () {
beforeEach(function () {
runs(function () {
state = jasmine.initializePlayer();
});
beforeEach(function (done) {
state = jasmine.initializePlayer();
waitsFor(function () {
jasmine.waitUntil(function () {
return state.videoCaption.rendered;
}, 'Transcripts are not rendered', WAIT_TIMEOUT);
}).then(done);
});
it('render the transcript', function () {
runs(function () {
var captionsData = jasmine.stubbedCaption,
items = $('.subtitles li[data-index]');
var captionsData = jasmine.stubbedCaption,
items = $('.subtitles li[data-index]');
_.each(captionsData.text, function (text, index) {
var item = items.eq(index);
_.each(captionsData.text, function (text, index) {
var item = items.eq(index);
expect(item).toHaveData('index', index);
expect(item).toHaveData(
'start', captionsData.start[index]
);
expect(item).toHaveAttr('tabindex', 0);
expect(item).toHaveText(text);
});
expect(parseIntAttribute(item, 'data-index')).toEqual(index);
expect(parseIntAttribute(item, 'data-start')).toEqual(captionsData.start[index]);
expect(item.attr('tabindex')).toEqual(0);
expect(item.text().trim()).toEqual(captionsData.text[index]);
});
});
it('add a padding element to transcript', function () {
runs(function () {
expect($('.subtitles li:first').hasClass('spacing'))
.toBe(true);
expect($('.subtitles li:last').hasClass('spacing'))
.toBe(true);
});
expect($('.subtitles li:first').hasClass('spacing'))
.toBe(true);
expect($('.subtitles li:last').hasClass('spacing'))
.toBe(true);
});
it('bind all the transcript link', function () {
runs(function () {
var handlerList = ['captionMouseOverOut', 'captionClick',
'captionMouseDown', 'captionFocus', 'captionBlur',
'captionKeyDown'
];
var handlerList = ['captionMouseOverOut', 'captionClick',
'captionMouseDown', 'captionFocus', 'captionBlur',
'captionKeyDown'
];
$.each(handlerList, function(index, handler) {
spyOn(state.videoCaption, handler);
});
$('.subtitles li[data-index]').each(
function (index, link) {
$.each(handlerList, function(index, handler) {
spyOn(state.videoCaption, handler);
});
$('.subtitles li[data-index]').each(
function (index, link) {
$(link).trigger('mouseover');
expect(state.videoCaption.captionMouseOverOut).toHaveBeenCalled();
$(link).trigger('mouseover');
expect(state.videoCaption.captionMouseOverOut).toHaveBeenCalled();
state.videoCaption.captionMouseOverOut.reset();
$(link).trigger('mouseout');
expect(state.videoCaption.captionMouseOverOut).toHaveBeenCalled();
state.videoCaption.captionMouseOverOut.calls.reset();
$(link).trigger('mouseout');
expect(state.videoCaption.captionMouseOverOut).toHaveBeenCalled();
$(this).click();
expect(state.videoCaption.captionClick).toHaveBeenCalled();
$(this).click();
expect(state.videoCaption.captionClick).toHaveBeenCalled();
$(this).trigger('mousedown');
expect(state.videoCaption.captionMouseDown).toHaveBeenCalled();
$(this).trigger('mousedown');
expect(state.videoCaption.captionMouseDown).toHaveBeenCalled();
$(this).trigger('focus');
expect(state.videoCaption.captionFocus).toHaveBeenCalled();
$(this).trigger('focus');
expect(state.videoCaption.captionFocus).toHaveBeenCalled();
$(this).trigger('blur');
expect(state.videoCaption.captionBlur).toHaveBeenCalled();
$(this).trigger('blur');
expect(state.videoCaption.captionBlur).toHaveBeenCalled();
$(this).trigger('keydown');
expect(state.videoCaption.captionKeyDown).toHaveBeenCalled();
});
$(this).trigger('keydown');
expect(state.videoCaption.captionKeyDown).toHaveBeenCalled();
});
});
it('set rendered to true', function () {
runs(function () {
state = jasmine.initializePlayer();
});
it('set rendered to true', function (done) {
state = jasmine.initializePlayer();
waitsFor(function () {
jasmine.waitUntil(function () {
return state.videoCaption.rendered;
}, 'Transcripts are not rendered', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(state.videoCaption.rendered).toBeTruthy();
});
}).always(done);
});
});
describe('when on a touch-based device', function () {
beforeEach(function () {
window.onTouchBasedDevice.andReturn(['iPad']);
window.onTouchBasedDevice.and.returnValue(['iPad']);
state = jasmine.initializePlayer();
$.fn.scrollTo.reset();
$.fn.scrollTo.calls.reset();
});
it('show explanation message', function () {
@@ -422,30 +399,24 @@
);
});
it('show transcript on play', function () {
runs(function () {
state.el.trigger('play');
});
it('show transcript on play', function (done) {
state.el.trigger('play');
waitsFor(function () {
jasmine.waitUntil(function () {
return state.videoCaption.rendered;
}, 'Transcripts are not rendered', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
var captionsData = jasmine.stubbedCaption,
items = $('.subtitles li[data-index]');
_.each(captionsData.text, function (text, index) {
var item = items.eq(index);
expect(item).toHaveData('index', index);
expect(item).toHaveData(
'start', captionsData.start[index]
);
expect(item).toHaveAttr('tabindex', 0);
expect(item).toHaveText(text);
expect(parseIntAttribute(item, 'data-index')).toEqual(index);
expect(parseIntAttribute(item, 'data-start')).toEqual(captionsData.start[index]);
expect(item.attr('tabindex')).toEqual(0);
expect(item.text().trim()).toEqual(text);
});
});
}).always(done);
});
it('does not set rendered to true', function () {
@@ -467,62 +438,58 @@
});
});
var originalClearTimeout;
describe('mouse movement', function () {
beforeEach(function () {
jasmine.Clock.useMock();
spyOn(window, 'clearTimeout');
runs(function () {
state = jasmine.initializePlayer();
jasmine.Clock.tick(50);
});
waitsFor(function () {
beforeEach(function (done) {
jasmine.clock().install();
state = jasmine.initializePlayer();
jasmine.clock().tick(50);
jasmine.waitUntil(function () {
return state.videoCaption.rendered;
}, 'Transcripts are not rendered', WAIT_TIMEOUT);
}).then(done);
// Why we can't use spyOn(): https://github.com/jasmine/jasmine/issues/826
originalClearTimeout = window.clearTimeout;
window.clearTimeout = jasmine.createSpy().and.callFake(originalClearTimeout);
});
afterEach(function () {
window.clearTimeout = originalClearTimeout;
jasmine.clock().uninstall();
});
describe('when cursor is outside of the transcript box', function () {
it('does not set freezing timeout', function () {
runs(function () {
expect(state.videoCaption.frozen).toBeFalsy();
});
expect(state.videoCaption.frozen).toBeFalsy();
});
});
describe('when cursor is in the transcript box', function () {
beforeEach(function () {
spyOn(state.videoCaption, 'onMouseLeave');
runs(function () {
$(window).trigger(jQuery.Event('mousemove'));
jasmine.Clock.tick(state.config.captionsFreezeTime);
$('.subtitles-menu').trigger(jQuery.Event('mouseenter'));
jasmine.Clock.tick(state.config.captionsFreezeTime);
});
$(window).trigger(jQuery.Event('mousemove'));
jasmine.clock().tick(state.config.captionsFreezeTime);
$('.subtitles-menu').trigger(jQuery.Event('mouseenter'));
jasmine.clock().tick(state.config.captionsFreezeTime);
});
it('set the freezing timeout', function () {
runs(function () {
expect(state.videoCaption.frozen).not.toBeFalsy();
expect(state.videoCaption.onMouseLeave).toHaveBeenCalled();
});
expect(state.videoCaption.frozen).not.toBeFalsy();
expect(state.videoCaption.onMouseLeave).toHaveBeenCalled();
});
describe('when the cursor is moving', function () {
it('reset the freezing timeout', function () {
runs(function () {
$('.subtitles-menu').trigger(jQuery.Event('mousemove'));
expect(window.clearTimeout).toHaveBeenCalled();
});
$('.subtitles-menu').trigger(jQuery.Event('mousemove'));
expect(window.clearTimeout).toHaveBeenCalled();
});
});
describe('when the mouse is scrolling', function () {
it('reset the freezing timeout', function () {
runs(function () {
$('.subtitles-menu').trigger(jQuery.Event('mousewheel'));
expect(window.clearTimeout).toHaveBeenCalled();
});
$('.subtitles-menu').trigger(jQuery.Event('mousewheel'));
expect(window.clearTimeout).toHaveBeenCalled();
});
});
});
@@ -533,7 +500,7 @@
beforeEach(function () {
state.videoCaption.frozen = 100;
$.fn.scrollTo.reset();
$.fn.scrollTo.calls.reset();
});
describe('always', function () {
@@ -582,12 +549,12 @@
beforeEach(function () {
state = jasmine.initializePlayer();
Caption = state.videoCaption;
spyOn($, 'ajaxWithPrefix').andCallThrough();
spyOn($, 'ajaxWithPrefix').and.callThrough();
spyOn(Caption, 'renderCaption');
spyOn(Caption, 'bindHandlers');
spyOn(Caption, 'updatePlayTime');
spyOn(Caption, 'hideCaptions');
spyOn(state, 'youtubeId').andReturn('Z5KLxerq05Y');
spyOn(state, 'youtubeId').and.returnValue('Z5KLxerq05Y');
});
it('show transcript on language change', function () {
@@ -609,7 +576,7 @@
expect(Caption.hideCaptions).toHaveBeenCalledWith(false, false);
Caption.loaded = false;
Caption.hideCaptions.reset();
Caption.hideCaptions.calls.reset();
state.hide_captions = true;
Caption.fetchCaption();
@@ -683,7 +650,7 @@
msg = 'on error: transcripts are hidden if there are no transcripts';
it(msg, function () {
spyOn(Caption, 'fetchAvailableTranslations');
$.ajax.andCallFake(function (settings) {
$.ajax.and.callFake(function (settings) {
_.result(settings, 'error');
});
@@ -693,7 +660,7 @@
expect($.ajaxWithPrefix).toHaveBeenCalled();
expect(Caption.fetchAvailableTranslations).not.toHaveBeenCalled();
expect(Caption.hideCaptions.mostRecentCall.args)
expect(Caption.hideCaptions.calls.mostRecent().args)
.toEqual([true, false]);
});
@@ -701,8 +668,8 @@
'with youtubeId if there are no additional transcripts';
it(msg, function () {
spyOn(Caption, 'fetchAvailableTranslations');
spyOn(Caption, 'fetchCaption').andCallThrough();
$.ajax.andCallFake(function (settings) {
spyOn(Caption, 'fetchCaption').and.callThrough();
$.ajax.and.callFake(function (settings) {
_.result(settings, 'error');
});
@@ -712,19 +679,19 @@
Caption.fetchCaption();
expect(Caption.fetchAvailableTranslations).not.toHaveBeenCalled();
expect($.ajaxWithPrefix.mostRecentCall.args[0]['data'])
expect($.ajaxWithPrefix.calls.mostRecent().args[0].data)
.toEqual({'videoId':'Z5KLxerq05Y'});
expect(Caption.hideCaptions.mostRecentCall.args)
expect(Caption.hideCaptions.calls.mostRecent().args)
.toEqual([true, false]);
expect(Caption.fetchCaption.mostRecentCall.args[0]).toEqual(true);
expect(Caption.fetchCaption.callCount).toEqual(2);
expect(Caption.fetchCaption.calls.mostRecent().args[0]).toEqual(true);
expect(Caption.fetchCaption.calls.count()).toEqual(2);
});
msg = 'on success: when fetchCaption called with fetch_with_youtubeId to ' +
'get transcript with youtubeId for html5';
it(msg, function () {
spyOn(Caption, 'fetchAvailableTranslations');
spyOn(Caption, 'fetchCaption').andCallThrough();
spyOn(Caption, 'fetchCaption').and.callThrough();
Caption.loaded = true;
state.config.transcriptLanguages = {};
@@ -733,18 +700,18 @@
Caption.fetchCaption(true);
expect(Caption.fetchAvailableTranslations).not.toHaveBeenCalled();
expect($.ajaxWithPrefix.mostRecentCall.args[0]['data'])
expect($.ajaxWithPrefix.calls.mostRecent().args[0].data)
.toEqual({'videoId':'Z5KLxerq05Y'});
expect(Caption.hideCaptions).toHaveBeenCalledWith(false);
expect(Caption.fetchCaption.mostRecentCall.args[0]).toEqual(true);
expect(Caption.fetchCaption.callCount).toEqual(1);
expect(Caption.fetchCaption.calls.mostRecent().args[0]).toEqual(true);
expect(Caption.fetchCaption.calls.count()).toEqual(1);
});
msg = 'on error: fetch available translations if there are ' +
'additional transcripts';
it(msg, function () {
$.ajax
.andCallFake(function (settings) {
.and.callFake(function (settings) {
_.result(settings, 'error');
});
@@ -767,7 +734,7 @@
beforeEach(function () {
state = jasmine.initializePlayer();
Caption = state.videoCaption;
spyOn($, 'ajaxWithPrefix').andCallThrough();
spyOn($, 'ajaxWithPrefix').and.callThrough();
spyOn(Caption, 'hideCaptions');
spyOn(Caption, 'fetchCaption');
spyOn(Caption, 'renderLanguageMenu');
@@ -821,7 +788,7 @@
msg = 'on error: transcripts are hidden if there are no transcript';
it(msg, function () {
$.ajax.andCallFake(function (settings) {
$.ajax.and.callFake(function (settings) {
_.result(settings, 'error');
});
Caption.fetchAvailableTranslations();
@@ -834,55 +801,44 @@
describe('play', function () {
describe('when the transcript was not rendered', function () {
beforeEach(function () {
window.onTouchBasedDevice.andReturn(['iPad']);
beforeEach(function (done) {
window.onTouchBasedDevice.and.returnValue(['iPad']);
runs(function () {
state = jasmine.initializePlayer();
state.videoCaption.play();
});
state = jasmine.initializePlayer();
state.videoCaption.play();
waitsFor(function () {
jasmine.waitUntil(function () {
return state.videoCaption.rendered;
}, 'Transcripts are not rendered', WAIT_TIMEOUT);
}).then(function(){
done();
});
});
it('render the transcript', function () {
runs(function () {
var captionsData;
var captionsData;
captionsData = jasmine.stubbedCaption;
$('.subtitles li[data-index]').each(
function (index, link) {
captionsData = jasmine.stubbedCaption;
expect($(link)).toHaveData('index', index);
expect($(link)).toHaveData(
'start', captionsData.start[index]
);
expect($(link)).toHaveAttr('tabindex', 0);
expect($(link)).toHaveText(captionsData.text[index]);
});
$('.subtitles li[data-index]').each(
function (index, item) {
expect(parseIntAttribute($(item), 'data-index')).toEqual(index);
expect(parseIntAttribute($(item), 'data-start')).toEqual(captionsData.start[index]);
expect($(item).attr('tabindex')).toEqual(0);
expect($(item).text().trim()).toEqual(captionsData.text[index]);
});
});
it('add a padding element to transcript', function () {
runs(function () {
expect($('.subtitles li:first')).toBe('.spacing');
expect($('.subtitles li:last')).toBe('.spacing');
});
expect($('.subtitles li:first')).toHaveClass('spacing');
expect($('.subtitles li:last')).toHaveClass('spacing');
});
it('set rendered to true', function () {
runs(function () {
expect(state.videoCaption.rendered).toBeTruthy();
});
expect(state.videoCaption.rendered).toBeTruthy();
});
it('set playing to true', function () {
runs(function () {
expect(state.videoCaption.playing).toBeTruthy();
});
expect(state.videoCaption.playing).toBeTruthy();
});
});
});
@@ -900,178 +856,148 @@
});
describe('updatePlayTime', function () {
beforeEach(function () {
runs(function () {
state = jasmine.initializePlayer();
});
beforeEach(function (done) {
state = jasmine.initializePlayer();
waitsFor(function () {
jasmine.waitUntil(function () {
return state.videoCaption.rendered;
}, 'Transcripts are not rendered', WAIT_TIMEOUT);
}).then(done);
});
describe('when the video speed is 1.0x', function () {
it('search the caption based on time', function () {
runs(function () {
state.videoCaption.updatePlayTime(25.000);
expect(state.videoCaption.currentIndex).toEqual(5);
state.videoCaption.updatePlayTime(25.000);
expect(state.videoCaption.currentIndex).toEqual(5);
// Flash mode
spyOn(state, 'isFlashMode').andReturn(true);
state.speed = '1.0';
state.videoCaption.updatePlayTime(25.000);
expect(state.videoCaption.currentIndex).toEqual(5);
});
// Flash mode
spyOn(state, 'isFlashMode').and.returnValue(true);
state.speed = '1.0';
state.videoCaption.updatePlayTime(25.000);
expect(state.videoCaption.currentIndex).toEqual(5);
});
});
describe('when the video speed is not 1.0x', function () {
it('search the transcript based on 1.0x speed', function () {
runs(function () {
state.videoCaption.updatePlayTime(25.000);
expect(state.videoCaption.currentIndex).toEqual(5);
state.videoCaption.updatePlayTime(25.000);
expect(state.videoCaption.currentIndex).toEqual(5);
// To test speed, don't use start / end times.
state.config.startTime = 0;
state.config.endTime = null;
// To test speed, don't use start / end times.
state.config.startTime = 0;
state.config.endTime = null;
// Flash mode
state.speed = '2.0';
spyOn(state, 'isFlashMode').andReturn(true);
state.videoCaption.updatePlayTime(25.000);
expect(state.videoCaption.currentIndex).toEqual(9);
state.speed = '0.75';
state.videoCaption.updatePlayTime(25.000);
expect(state.videoCaption.currentIndex).toEqual(3);
});
// Flash mode
state.speed = '2.0';
spyOn(state, 'isFlashMode').and.returnValue(true);
state.videoCaption.updatePlayTime(25.000);
expect(state.videoCaption.currentIndex).toEqual(9);
state.speed = '0.75';
state.videoCaption.updatePlayTime(25.000);
expect(state.videoCaption.currentIndex).toEqual(3);
});
});
describe('when the index is not the same', function () {
beforeEach(function () {
runs(function () {
state.videoCaption.currentIndex = 1;
$('.subtitles li[data-index=5]').addClass('current');
state.videoCaption.updatePlayTime(25.000);
});
state.videoCaption.currentIndex = 1;
$('.subtitles li[data-index=5]').addClass('current');
state.videoCaption.updatePlayTime(25.000);
});
it('deactivate the previous transcript', function () {
runs(function () {
expect($('.subtitles li[data-index=1]'))
.not.toHaveClass('current');
});
expect($('.subtitles li[data-index=1]'))
.not.toHaveClass('current');
});
it('activate new transcript', function () {
runs(function () {
expect($('.subtitles li[data-index=5]'))
.toHaveClass('current');
});
expect($('.subtitles li[data-index=5]'))
.toHaveClass('current');
});
it('save new index', function () {
runs(function () {
expect(state.videoCaption.currentIndex).toEqual(5);
});
expect(state.videoCaption.currentIndex).toEqual(5);
});
it('scroll transcript to new position', function () {
runs(function () {
expect($.fn.scrollTo).toHaveBeenCalled();
});
expect($.fn.scrollTo).toHaveBeenCalled();
});
});
describe('when the index is the same', function () {
it('does not change current subtitle', function () {
runs(function () {
state.videoCaption.currentIndex = 1;
$('.subtitles li[data-index=3]').addClass('current');
state.videoCaption.updatePlayTime(15.000);
expect($('.subtitles li[data-index=3]'))
.toHaveClass('current');
});
state.videoCaption.currentIndex = 1;
$('.subtitles li[data-index=3]').addClass('current');
state.videoCaption.updatePlayTime(15.000);
expect($('.subtitles li[data-index=3]'))
.toHaveClass('current');
});
});
});
describe('resize', function () {
beforeEach(function () {
runs(function () {
state = jasmine.initializePlayer();
});
beforeEach(function (done) {
state = jasmine.initializePlayer();
waitsFor(function () {
jasmine.waitUntil(function () {
return state.videoCaption.rendered;
}, 'Transcripts are not rendered', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
videoControl = state.videoControl;
$('.subtitles li[data-index=1]').addClass('current');
state.videoCaption.onResize();
});
}).always(done);
});
describe('set the height of transcript container', function () {
it('when transcript button is enabled', function () {
runs(function () {
var realHeight = parseInt(
$('.subtitles').css('maxHeight'), 10
),
shouldBeHeight = $('.video-wrapper').height();
var realHeight = parseInt(
$('.subtitles').css('maxHeight'), 10
),
shouldBeHeight = $('.video-wrapper').height();
// Because of some problems with rounding on different
// environments: Linux * Mac * FF * Chrome
expect(realHeight).toBeCloseTo(shouldBeHeight, 2);
});
// Because of some problems with rounding on different
// environments: Linux * Mac * FF * Chrome
expect(realHeight).toBeCloseTo(shouldBeHeight, 2);
});
it('when transcript button is disabled ', function () {
runs(function () {
var realHeight, videoWrapperHeight, progressSliderHeight,
controlHeight, shouldBeHeight;
var realHeight, videoWrapperHeight, progressSliderHeight,
controlHeight, shouldBeHeight;
state.captionsHidden = true;
state.videoCaption.setSubtitlesHeight();
state.captionsHidden = true;
state.videoCaption.setSubtitlesHeight();
realHeight = parseInt(
$('.subtitles').css('maxHeight'), 10
);
videoWrapperHeight = $('.video-wrapper').height();
progressSliderHeight = state.el.find('.slider').height();
controlHeight = state.el.find('.video-controls').height();
shouldBeHeight = videoWrapperHeight -
0.5 * progressSliderHeight -
controlHeight;
realHeight = parseInt(
$('.subtitles').css('maxHeight'), 10
);
videoWrapperHeight = $('.video-wrapper').height();
progressSliderHeight = state.el.find('.slider').height();
controlHeight = state.el.find('.video-controls').height();
shouldBeHeight = videoWrapperHeight -
0.5 * progressSliderHeight -
controlHeight;
expect(realHeight).toBe(shouldBeHeight);
});
expect(realHeight).toBe(shouldBeHeight);
});
});
it('set the height of transcript spacing', function () {
runs(function () {
var firstSpacing, lastSpacing;
var firstSpacing, lastSpacing;
firstSpacing = Math.abs(parseInt(
$('.subtitles .spacing:first').css('height'), 10
));
lastSpacing = Math.abs(parseInt(
$('.subtitles .spacing:last').css('height'), 10
));
firstSpacing = Math.abs(parseInt(
$('.subtitles .spacing:first').css('height'), 10
));
lastSpacing = Math.abs(parseInt(
$('.subtitles .spacing:last').css('height'), 10
));
expect(firstSpacing - state.videoCaption.topSpacingHeight())
.toBeLessThan(1);
expect(lastSpacing - state.videoCaption.bottomSpacingHeight())
.toBeLessThan(1);
});
expect(firstSpacing - state.videoCaption.topSpacingHeight())
.toBeLessThan(1);
expect(lastSpacing - state.videoCaption.bottomSpacingHeight())
.toBeLessThan(1);
});
it('scroll transcript to new position', function () {
runs(function () {
expect($.fn.scrollTo).toHaveBeenCalled();
});
expect($.fn.scrollTo).toHaveBeenCalled();
});
});
@@ -1193,7 +1119,11 @@
beforeEach(function () {
state.el.addClass('closed');
state.videoCaption.toggle(jQuery.Event('click'));
jasmine.Clock.useMock();
jasmine.clock().install();
});
afterEach(function () {
jasmine.clock().uninstall();
});
it('show the transcript', function () {
@@ -1204,7 +1134,7 @@
xit('scroll the transcript', function () {
// After transcripts are shown, and the video plays for a
// bit.
jasmine.Clock.tick(1000);
jasmine.clock().tick(1000);
// The transcripts should have advanced by at least one
// position. When they advance, the list scrolls. The
@@ -1218,60 +1148,46 @@
});
describe('transcript accessibility', function () {
beforeEach(function () {
runs(function () {
state = jasmine.initializePlayer();
});
beforeEach(function (done) {
state = jasmine.initializePlayer();
waitsFor(function () {
jasmine.waitUntil(function () {
return state.videoCaption.rendered;
}, 'Transcripts are not rendered', WAIT_TIMEOUT);
}).then(done);
});
describe('when getting focus through TAB key', function () {
beforeEach(function () {
runs(function () {
state.videoCaption.isMouseFocus = false;
$('.subtitles li[data-index=0]').trigger(
jQuery.Event('focus')
);
});
state.videoCaption.isMouseFocus = false;
$('.subtitles li[data-index=0]').trigger(
jQuery.Event('focus')
);
});
it('shows an outline around the transcript', function () {
runs(function () {
expect($('.subtitles li[data-index=0]'))
.toHaveClass('focused');
});
expect($('.subtitles li[data-index=0]'))
.toHaveClass('focused');
});
it('has automatic scrolling disabled', function () {
runs(function () {
expect(state.videoCaption.autoScrolling).toBe(false);
});
expect(state.videoCaption.autoScrolling).toBe(false);
});
});
describe('when loosing focus through TAB key', function () {
beforeEach(function () {
runs(function () {
$('.subtitles li[data-index=0]').trigger(
jQuery.Event('blur')
);
});
$('.subtitles li[data-index=0]').trigger(
jQuery.Event('blur')
);
});
it('does not show an outline around the transcript', function () {
runs(function () {
expect($('.subtitles li[data-index=0]'))
.not.toHaveClass('focused');
});
expect($('.subtitles li[data-index=0]'))
.not.toHaveClass('focused');
});
it('has automatic scrolling enabled', function () {
runs(function () {
expect(state.videoCaption.autoScrolling).toBe(true);
});
expect(state.videoCaption.autoScrolling).toBe(true);
});
});
@@ -1281,26 +1197,20 @@
function () {
beforeEach(function () {
runs(function () {
state.videoCaption.isMouseFocus = false;
$('.subtitles li[data-index=0]')
.trigger(jQuery.Event('focus'));
$('.subtitles li[data-index=0]')
.trigger(jQuery.Event('mousedown'));
});
state.videoCaption.isMouseFocus = false;
$('.subtitles li[data-index=0]')
.trigger(jQuery.Event('focus'));
$('.subtitles li[data-index=0]')
.trigger(jQuery.Event('mousedown'));
});
it('does not show an outline around it', function () {
runs(function () {
expect($('.subtitles li[data-index=0]'))
.not.toHaveClass('focused');
});
expect($('.subtitles li[data-index=0]'))
.not.toHaveClass('focused');
});
it('has automatic scrolling enabled', function () {
runs(function () {
expect(state.videoCaption.autoScrolling).toBe(true);
});
expect(state.videoCaption.autoScrolling).toBe(true);
});
});
@@ -1312,37 +1222,29 @@
var subDataLiIdx__0, subDataLiIdx__1;
beforeEach(function () {
runs(function () {
subDataLiIdx__0 = $('.subtitles li[data-index=0]');
subDataLiIdx__1 = $('.subtitles li[data-index=1]');
subDataLiIdx__0 = $('.subtitles li[data-index=0]');
subDataLiIdx__1 = $('.subtitles li[data-index=1]');
state.videoCaption.isMouseFocus = false;
state.videoCaption.isMouseFocus = false;
subDataLiIdx__0.trigger(jQuery.Event('focus'));
subDataLiIdx__0.trigger(jQuery.Event('blur'));
subDataLiIdx__0.trigger(jQuery.Event('focus'));
subDataLiIdx__0.trigger(jQuery.Event('blur'));
state.videoCaption.isMouseFocus = true;
state.videoCaption.isMouseFocus = true;
subDataLiIdx__1.trigger(jQuery.Event('mousedown'));
});
subDataLiIdx__1.trigger(jQuery.Event('mousedown'));
});
it('does not show an outline around the first', function () {
runs(function () {
expect(subDataLiIdx__0).not.toHaveClass('focused');
});
expect(subDataLiIdx__0).not.toHaveClass('focused');
});
it('does not show an outline around the second', function () {
runs(function () {
expect(subDataLiIdx__1).not.toHaveClass('focused');
});
expect(subDataLiIdx__1).not.toHaveClass('focused');
});
it('has automatic scrolling enabled', function () {
runs(function () {
expect(state.videoCaption.autoScrolling).toBe(true);
});
expect(state.videoCaption.autoScrolling).toBe(true);
});
});
});

View File

@@ -6,7 +6,6 @@
openMenu = function () {
var container = $('.video');
jasmine.Clock.useMock();
container.find('video').trigger('contextmenu');
menu = container.children('.contextmenu');
menuItems = menu.children('.menu-item').not('.submenu-item');
@@ -23,19 +22,19 @@
openSubmenuMouse = function (menuSubmenuItem) {
menuSubmenuItem.mouseover();
jasmine.Clock.tick(200);
jasmine.clock().tick(200);
expect(menuSubmenuItem).toHaveClass('is-opened');
};
openSubmenuKeyboard = function (menuSubmenuItem, keyCode) {
menuSubmenuItem.focus().trigger(keyPressEvent(keyCode || $.ui.keyCode.RIGHT));
expect(menuSubmenuItem).toHaveClass('is-opened');
expect(menuSubmenuItem.children().first()).toBeFocused();
expect(menuSubmenuItem.children().last().children().first()).toBeFocused();
};
closeSubmenuMouse = function (menuSubmenuItem) {
menuSubmenuItem.mouseleave();
jasmine.Clock.tick(200);
jasmine.clock().tick(200);
expect(menuSubmenuItem).not.toHaveClass('is-opened');
};
@@ -46,20 +45,20 @@
};
beforeEach(function () {
jasmine.clock().install();
// $.cookie is mocked, make sure we have a state with an unmuted volume.
$.cookie.andReturn('100');
this.addMatchers({
toBeFocused: function () {
$.cookie.and.returnValue('100');
jasmine.addMatchers({
toHaveCorrectLabels: function () {
return {
compare: function (actual) {
return { pass: $(actual)[0] === $(actual)[0].ownerDocument.activeElement };
compare: function (actual, labelsList) {
return {
pass: _.difference(labelsList, _.map(actual, function (item) {
return $(item).text();
})).length === 0
};
}
};
},
toHaveCorrectLabels: function (labelsList) {
return _.difference(labelsList, _.map(this.actual, function (item) {
return $(item).text();
})).length === 0;
}
});
});
@@ -69,6 +68,7 @@
_.result(state.storage, 'clear');
_.result($('video').data('contextmenu'), 'destroy');
_.result(state.videoPlayer, 'destroy');
jasmine.clock().uninstall();
});
describe('constructor', function () {
@@ -89,7 +89,7 @@
*/
// Only one context menu per video container
expect(menu).toExist();
expect(menu).toBeInDOM();
expect(menu).toHaveClass('is-opened');
expect(menuItems).toHaveCorrectLabels(['Play', 'Mute', 'Fill browser']);
expect(menuSubmenuItem.children('span')).toHaveText('Speed');
@@ -141,8 +141,8 @@
menuEvents = ['keydown', 'contextmenu', 'mouseleave', 'mouseover'];
menu.data('menu').destroy();
expect(menu).not.toExist();
expect(overlay).not.toExist();
expect(menu).not.toBeInDOM();
expect(overlay).not.toBeInDOM();
_.each(menuitemEvents, function (eventName) {
expect(menuItems.first()).not.toHandle(eventName);
})
@@ -177,7 +177,7 @@
it('context menu opens', function () {
expect(menu).toHaveClass('is-opened');
expect(overlay).toExist();
expect(overlay).toBeInDOM();
});
it('mouseover and mouseleave behave as expected', function () {
@@ -193,25 +193,25 @@
// Left-click outside of open menu, for example on Play button
playButton.click();
expect(menu).not.toHaveClass('is-opened');
expect(overlay).not.toExist();
expect(overlay).not.toBeInDOM();
});
it('mouse right-clicking outside of video will close it', function () {
// Right-click outside of open menu for example on Play button
playButton.trigger('contextmenu');
expect(menu).not.toHaveClass('is-opened');
expect(overlay).not.toExist();
expect(overlay).not.toBeInDOM();
});
it('mouse right-clicking inside video but outside of context menu will not close it', function () {
spyOn(menu.data('menu'), 'pointInContainerBox').andReturn(true);
spyOn(menu.data('menu'), 'pointInContainerBox').and.returnValue(true);
overlay.trigger('contextmenu');
expect(menu).toHaveClass('is-opened');
expect(overlay).toExist();
expect(overlay).toBeInDOM();
});
it('mouse right-clicking inside video but outside of context menu will close submenus', function () {
spyOn(menu.data('menu'), 'pointInContainerBox').andReturn(true);
spyOn(menu.data('menu'), 'pointInContainerBox').and.returnValue(true);
openSubmenuMouse(menuSubmenuItem);
expect(menuSubmenuItem).toHaveClass('is-opened');
overlay.trigger('contextmenu');
@@ -221,12 +221,12 @@
it('mouse left/right-clicking behaves as expected on play/pause menu item', function () {
var menuItem = menuItems.first();
spyOn(state.videoPlayer, 'isPlaying');
spyOn(state.videoPlayer, 'play').andCallFake(function () {
state.videoPlayer.isPlaying.andReturn(true);
spyOn(state.videoPlayer, 'play').and.callFake(function () {
state.videoPlayer.isPlaying.and.returnValue(true);
state.el.trigger('play');
});
spyOn(state.videoPlayer, 'pause').andCallFake(function () {
state.videoPlayer.isPlaying.andReturn(false);
spyOn(state.videoPlayer, 'pause').and.callFake(function () {
state.videoPlayer.isPlaying.and.returnValue(false);
state.el.trigger('pause');
});
// Left-click on play
@@ -238,7 +238,7 @@
menuItem.click();
expect(state.videoPlayer.pause).toHaveBeenCalled();
expect(menuItem).toHaveText('Play');
state.videoPlayer.play.reset();
state.videoPlayer.play.calls.reset();
// Right-click on play
menuItem.trigger('contextmenu');
expect(state.videoPlayer.play).toHaveBeenCalled();
@@ -355,14 +355,14 @@
it('close the menu on ESCAPE keydown', function () {
menu.trigger(keyPressEvent($.ui.keyCode.ESCAPE));
expect(menu).not.toHaveClass('is-opened');
expect(overlay).not.toExist();
expect(overlay).not.toBeInDOM();
});
it('close the submenu on ESCAPE keydown', function () {
openSubmenuKeyboard(menuSubmenuItem);
menuSubmenuItem.trigger(keyPressEvent($.ui.keyCode.ESCAPE));
expect(menuSubmenuItem).not.toHaveClass('is-opened');
expect(overlay).not.toExist();
expect(overlay).not.toBeInDOM();
});
it('close the submenu on LEFT keydown on submenu items', function () {
@@ -395,9 +395,9 @@
menuItems.eq(0).trigger(keyPressEvent($.ui.keyCode.UP));
expect(menuSubmenuItem).toBeFocused(); // Speed
menuSubmenuItem.trigger(keyPressEvent($.ui.keyCode.UP));
// Check if hidden item can be skipped correctly.
menuItems.eq(2).hide(); // hide Fullscreen item
menuSubmenuItem.trigger(keyPressEvent($.ui.keyCode.UP));
expect(menuItems.eq(1)).toBeFocused(); // Mute
menuItems.eq(1).trigger(keyPressEvent($.ui.keyCode.UP));
expect(menuItems.eq(0)).toBeFocused(); // Play

View File

@@ -7,7 +7,7 @@
beforeEach(function () {
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice').andReturn(null);
.createSpy('onTouchBasedDevice').and.returnValue(null);
});
afterEach(function () {
@@ -24,7 +24,7 @@
});
it('render the video controls', function () {
expect($('.video-controls')).toContain(
expect($('.video-controls')).toContainElement(
[
'.slider',
'ul.vcr',
@@ -41,61 +41,52 @@
describe('constructor with start-time', function () {
it(
'saved position is 0, timer slider and VCR set to start-time',
function ()
function (done)
{
var duration, sliderEl, expectedValue;
runs(function () {
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
savedVideoPosition: 0
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').andReturn(60);
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
savedVideoPosition: 0
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
return isFinite(duration) && duration > 0 &&
isFinite(state.videoPlayer.startTime);
}, 'duration is set', WAIT_TIMEOUT);
runs(function () {
return isFinite(duration) && duration > 0 && isFinite(state.videoPlayer.startTime);
}).then(function () {
expectedValue = $('.video-controls').find('.vidtime');
expect(expectedValue).toHaveText('0:10 / 1:00');
expectedValue = sliderEl.slider('option', 'value');
expect(expectedValue).toBe(10);
});
}).always(done);
});
it(
'saved position is after start-time, ' +
'timer slider and VCR set to saved position',
function ()
function (done)
{
var duration, sliderEl, expectedValue;
runs(function () {
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
savedVideoPosition: 15
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').andReturn(60);
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
savedVideoPosition: 15
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
return isFinite(duration) && duration > 0 &&
isFinite(state.videoPlayer.startTime);
}, 'duration is set', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expectedValue = $('.video-controls').find('.vidtime');
expect(expectedValue).toHaveText('0:15 / 1:00');
@@ -103,34 +94,30 @@
expect(expectedValue).toBe(15);
state.storage.clear();
});
}).always(done);
});
it(
'saved position is negative, ' +
'timer slider and VCR set to start-time',
function ()
function (done)
{
var duration, sliderEl, expectedValue;
runs(function () {
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
savedVideoPosition: -15
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').andReturn(60);
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
savedVideoPosition: -15
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
return isFinite(duration) && duration > 0 &&
isFinite(state.videoPlayer.startTime);
}, 'duration is set', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expectedValue = $('.video-controls').find('.vidtime');
expect(expectedValue).toHaveText('0:10 / 1:00');
@@ -138,34 +125,30 @@
expect(expectedValue).toBe(10);
state.storage.clear();
});
}).always(done);
});
it(
'saved position is not a number, ' +
'timer slider and VCR set to start-time',
function ()
function (done)
{
var duration, sliderEl, expectedValue;
runs(function () {
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
savedVideoPosition: 'a'
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').andReturn(60);
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
savedVideoPosition: 'a'
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
return isFinite(duration) && duration > 0 &&
isFinite(state.videoPlayer.startTime);
}, 'duration is set', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expectedValue = $('.video-controls').find('.vidtime');
expect(expectedValue).toHaveText('0:10 / 1:00');
@@ -173,34 +156,30 @@
expect(expectedValue).toBe(10);
state.storage.clear();
});
}).always(done);
});
it(
'saved position is greater than end-time, ' +
'timer slider and VCR set to start-time',
function ()
function (done)
{
var duration, sliderEl, expectedValue;
runs(function () {
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
savedVideoPosition: 10000
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').andReturn(60);
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
savedVideoPosition: 10000
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
return isFinite(duration) && duration > 0 &&
isFinite(state.videoPlayer.startTime);
}, 'duration is set', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expectedValue = $('.video-controls').find('.vidtime');
expect(expectedValue).toHaveText('0:10 / 1:00');
@@ -208,7 +187,7 @@
expect(expectedValue).toBe(10);
state.storage.clear();
});
}).always(done);
});
});
@@ -216,28 +195,24 @@
it(
'saved position is 0, timer slider and VCR set to 0:00 ' +
'and ending at specified end-time',
function ()
function (done)
{
var duration, sliderEl, expectedValue;
runs(function () {
window.VideoState = {};
state = jasmine.initializePlayer({
end: 20,
savedVideoPosition: 0
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').andReturn(60);
window.VideoState = {};
state = jasmine.initializePlayer({
end: 20,
savedVideoPosition: 0
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
return isFinite(duration) && duration > 0 &&
isFinite(state.videoPlayer.startTime);
}, 'duration is set', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expectedValue = $('.video-controls').find('.vidtime');
expect(expectedValue).toHaveText('0:00 / 0:20');
@@ -245,34 +220,30 @@
expect(expectedValue).toBe(0);
state.storage.clear();
});
}).always(done);
});
it(
'saved position is after start-time, ' +
'timer slider and VCR set to saved position',
function ()
function (done)
{
var duration, sliderEl, expectedValue;
runs(function () {
window.VideoState = {};
state = jasmine.initializePlayer({
end: 20,
savedVideoPosition: 15
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').andReturn(60);
window.VideoState = {};
state = jasmine.initializePlayer({
end: 20,
savedVideoPosition: 15
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
return isFinite(duration) && duration > 0 &&
isFinite(state.videoPlayer.startTime);
}, 'duration is set', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expectedValue = $('.video-controls').find('.vidtime');
expect(expectedValue).toHaveText('0:15 / 0:20');
@@ -280,34 +251,30 @@
expect(expectedValue).toBe(15);
state.storage.clear();
});
}).always(done);
});
// TODO: Fix!
it(
'saved position is negative, timer slider and VCR set to 0:00',
function ()
function (done)
{
var duration, sliderEl, expectedValue;
runs(function () {
window.VideoState = {};
state = jasmine.initializePlayer({
end: 20,
savedVideoPosition: -15
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').andReturn(60);
window.VideoState = {};
state = jasmine.initializePlayer({
end: 20,
savedVideoPosition: -15
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
return isFinite(duration) && duration > 0 &&
isFinite(state.videoPlayer.startTime);
}, 'duration is set', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expectedValue = $('.video-controls').find('.vidtime');
expect(expectedValue).toHaveText('0:00 / 0:20');
@@ -315,34 +282,30 @@
expect(expectedValue).toBe(0);
state.storage.clear();
});
}).always(done);
});
it(
'saved position is not a number, ' +
'timer slider and VCR set to 0:00',
function ()
function (done)
{
var duration, sliderEl, expectedValue;
runs(function () {
window.VideoState = {};
state = jasmine.initializePlayer({
end: 20,
savedVideoPosition: 'a'
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').andReturn(60);
window.VideoState = {};
state = jasmine.initializePlayer({
end: 20,
savedVideoPosition: 'a'
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
return isFinite(duration) && duration > 0 &&
isFinite(state.videoPlayer.startTime);
}, 'duration is set', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expectedValue = $('.video-controls').find('.vidtime');
expect(expectedValue).toHaveText('0:00 / 0:20');
@@ -350,35 +313,31 @@
expect(expectedValue).toBe(0);
state.storage.clear();
});
}).always(done);
});
// TODO: Fix!
it(
'saved position is greater than end-time, ' +
'timer slider and VCR set to 0:00',
function ()
function (done)
{
var duration, sliderEl, expectedValue;
runs(function () {
window.VideoState = {};
state = jasmine.initializePlayer({
end: 20,
savedVideoPosition: 10000
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').andReturn(60);
window.VideoState = {};
state = jasmine.initializePlayer({
end: 20,
savedVideoPosition: 10000
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
return isFinite(duration) && duration > 0 &&
isFinite(state.videoPlayer.startTime);
}, 'duration is set', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expectedValue = $('.video-controls').find('.vidtime');
expect(expectedValue).toHaveText('0:00 / 0:20');
@@ -386,36 +345,32 @@
expect(expectedValue).toBe(0);
state.storage.clear();
});
}).always(done);
});
});
describe('constructor with start-time and end-time', function () {
it(
'saved position is 0, timer slider and VCR set to appropriate start and end times',
function ()
function (done)
{
var duration, sliderEl, expectedValue;
runs(function () {
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
end: 20,
savedVideoPosition: 0
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').andReturn(60);
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
end: 20,
savedVideoPosition: 0
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
return isFinite(duration) && duration > 0 &&
isFinite(state.videoPlayer.startTime);
}, 'duration is set', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expectedValue = $('.video-controls').find('.vidtime');
expect(expectedValue).toHaveText('0:10 / 0:20');
@@ -423,35 +378,31 @@
expect(expectedValue).toBe(10);
state.storage.clear();
});
}).always(done);
});
it(
'saved position is after start-time, ' +
'timer slider and VCR set to saved position',
function ()
function (done)
{
var duration, sliderEl, expectedValue;
runs(function () {
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
end: 20,
savedVideoPosition: 15
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').andReturn(60);
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
end: 20,
savedVideoPosition: 15
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
return isFinite(duration) && duration > 0 &&
isFinite(state.videoPlayer.startTime);
}, 'duration is set', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expectedValue = $('.video-controls').find('.vidtime');
expect(expectedValue).toHaveText('0:15 / 0:20');
@@ -459,35 +410,31 @@
expect(expectedValue).toBe(15);
state.storage.clear();
});
}).always(done);
});
it(
'saved position is negative, ' +
'timer slider and VCR set to start-time',
function ()
function (done)
{
var duration, sliderEl, expectedValue;
runs(function () {
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
end: 20,
savedVideoPosition: -15
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').andReturn(60);
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
end: 20,
savedVideoPosition: -15
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
return isFinite(duration) && duration > 0 &&
isFinite(state.videoPlayer.startTime);
}, 'duration is set', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expectedValue = $('.video-controls').find('.vidtime');
expect(expectedValue).toHaveText('0:10 / 0:20');
@@ -495,35 +442,31 @@
expect(expectedValue).toBe(10);
state.storage.clear();
});
}).always(done);
});
it(
'saved position is not a number, ' +
'timer slider and VCR set to start-time',
function ()
function (done)
{
var duration, sliderEl, expectedValue;
runs(function () {
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
end: 20,
savedVideoPosition: 'a'
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').andReturn(60);
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
end: 20,
savedVideoPosition: 'a'
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
return isFinite(duration) && duration > 0 &&
isFinite(state.videoPlayer.startTime);
}, 'duration is set', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expectedValue = $('.video-controls').find('.vidtime');
expect(expectedValue).toHaveText('0:10 / 0:20');
@@ -531,35 +474,31 @@
expect(expectedValue).toBe(10);
state.storage.clear();
});
}).always(done);
});
it(
'saved position is greater than end-time, ' +
'timer slider and VCR set to start-time',
function ()
function (done)
{
var duration, sliderEl, expectedValue;
runs(function () {
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
end: 20,
savedVideoPosition: 10000
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').andReturn(60);
window.VideoState = {};
state = jasmine.initializePlayer({
start: 10,
end: 20,
savedVideoPosition: 10000
});
sliderEl = state.videoProgressSlider.slider;
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
return isFinite(duration) && duration > 0 &&
isFinite(state.videoPlayer.startTime);
}, 'duration is set', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expectedValue = $('.video-controls').find('.vidtime');
expect(expectedValue).toHaveText('0:10 / 0:20');
@@ -567,7 +506,7 @@
expect(expectedValue).toBe(10);
state.storage.clear();
});
}).always(done);
});
});
@@ -587,16 +526,15 @@
expect(state.videoControl).toBeUndefined();
});
it('can focus the first control', function () {
it('can focus the first control', function (done) {
var btnPlay;
state = jasmine.initializePlayer({focusFirstControl: true});
btnPlay = state.el.find('.video-controls .play');
waitsFor(function () {
jasmine.waitUntil(function () {
return state.el.hasClass('is-initialized');
}, 'Player is not initialized', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(btnPlay).toBeFocused();
});
}).always(done);
});
});
}).call(this, window.WAIT_TIMEOUT);

View File

@@ -1,20 +1,20 @@
(function (undefined) {
'use strict';
describe('VideoPlayer Events Bumper plugin', function () {
var Logger = window.Logger;
var state, oldOTBD;
beforeEach(function () {
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice')
.andReturn(null);
.and.returnValue(null);
jasmine.stubRequests();
state = jasmine.initializePlayer('video_with_bumper.html');
spyOn(Logger, 'log');
$('.poster .btn-play').click();
spyOn(state.bumperState.videoEventsBumperPlugin, 'getCurrentTime').andReturn(10);
spyOn(state.bumperState.videoEventsBumperPlugin, 'getDuration').andReturn(20);
spyOn(state.bumperState.videoEventsBumperPlugin, 'getCurrentTime').and.returnValue(10);
spyOn(state.bumperState.videoEventsBumperPlugin, 'getDuration').and.returnValue(20);
});
afterEach(function () {
@@ -33,7 +33,7 @@
state.el.trigger('ready');
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.loaded', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
duration: 20
});
@@ -43,7 +43,7 @@
state.el.trigger('play');
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.played', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
currentTime: 10,
duration: 20
@@ -54,17 +54,17 @@
state.el.trigger('ended');
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.stopped', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
currentTime: 10,
duration: 20
});
Logger.log.reset();
Logger.log.calls.reset();
state.el.trigger('stop');
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.stopped', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
currentTime: 10,
duration: 20
@@ -75,7 +75,7 @@
state.el.trigger('skip', [false]);
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.skipped', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
currentTime: 10,
duration: 20
@@ -86,7 +86,7 @@
state.el.trigger('skip', [true]);
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.dismissed', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
currentTime: 10,
duration: 20
@@ -97,7 +97,7 @@
state.el.trigger('language_menu:show');
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.transcript.menu.shown', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
duration: 20
});
@@ -107,7 +107,7 @@
state.el.trigger('language_menu:hide');
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.transcript.menu.hidden', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
duration: 20
});
@@ -117,7 +117,7 @@
state.el.trigger('captions:show');
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.transcript.shown', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
currentTime: 10,
duration: 20
@@ -128,7 +128,7 @@
state.el.trigger('captions:hide');
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.transcript.hidden', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
currentTime: 10,
duration: 20
@@ -137,7 +137,7 @@
it('can destroy itself', function () {
var plugin = state.bumperState.videoEventsBumperPlugin;
spyOn($.fn, 'off').andCallThrough();
spyOn($.fn, 'off').and.callThrough();
plugin.destroy();
expect(state.bumperState.videoEventsBumperPlugin).toBeUndefined();
expect($.fn.off).toHaveBeenCalledWith({

View File

@@ -7,12 +7,11 @@
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice')
.andReturn(null);
.and.returnValue(null);
jasmine.stubRequests();
state = jasmine.initializePlayer();
spyOn(Logger, 'log');
spyOn(state.videoEventsPlugin, 'getCurrentTime').andReturn(10);
spyOn(state.videoEventsPlugin, 'getCurrentTime').and.returnValue(10);
});
afterEach(function () {
@@ -90,7 +89,7 @@
});
expect(state.videoEventsPlugin.emitPlayVideoEvent).toBeTruthy();
Logger.log.reset();
Logger.log.calls.reset();
state.el.trigger('stop');
expect(Logger.log).toHaveBeenCalledWith('stop_video', {
id: 'id',
@@ -155,7 +154,7 @@
it('can destroy itself', function () {
var plugin = state.videoEventsPlugin;
spyOn($.fn, 'off').andCallThrough();
spyOn($.fn, 'off').and.callThrough();
state.videoEventsPlugin.destroy();
expect(state.videoEventsPlugin).toBeUndefined();
expect($.fn.off).toHaveBeenCalledWith({

View File

@@ -15,17 +15,19 @@
// stack.
jQuery.fx.off = true;
jasmine.stubRequests();
loadFixtures('video_html5.html');
state = new Video('#example');
spyOnEvent(state.el, 'mousemove');
spyOn(state.focusGrabber, 'disableFocusGrabber').andCallThrough();
spyOn(state.focusGrabber, 'enableFocusGrabber').andCallThrough();
spyOn(state.focusGrabber, 'disableFocusGrabber').and.callThrough();
spyOn(state.focusGrabber, 'enableFocusGrabber').and.callThrough();
});
afterEach(function () {
// Turn jQuery animations back on.
jQuery.fx.off = true;
state.storage.clear();
state.videoPlayer.destroy();
});

View File

@@ -6,7 +6,7 @@
beforeEach(function () {
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice').andReturn(null);
.createSpy('onTouchBasedDevice').and.returnValue(null);
});
afterEach(function () {
@@ -83,7 +83,7 @@
});
it('Controls height is actual on switch to fullscreen', function () {
spyOn($.fn, 'height').andCallFake(function (val) {
spyOn($.fn, 'height').and.callFake(function (val) {
return _.isUndefined(val) ? 100: this;
});

View File

@@ -6,7 +6,7 @@
beforeEach(function () {
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice').andReturn(null);
.createSpy('onTouchBasedDevice').and.returnValue(null);
state = jasmine.initializePlayer();
spyOn(state.videoCommands, 'execute');
spyOn(state.videoSaveStatePlugin, 'saveState');

View File

@@ -6,7 +6,7 @@
beforeEach(function () {
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice').andReturn(['iPad']);
.createSpy('onTouchBasedDevice').and.returnValue(['iPad']);
state = jasmine.initializePlayer();
spyOn(state.videoCommands, 'execute');
@@ -41,7 +41,7 @@
beforeEach(function () {
jasmine.stubRequests();
spyOn(window.YT, 'Player').andCallThrough();
spyOn(window.YT, 'Player').and.callThrough();
});
it ('works correctly on calling proper methods', function () {
@@ -77,7 +77,7 @@
it(message, function () {
var btnPlay;
window.onTouchBasedDevice.andReturn(data.isTouch);
window.onTouchBasedDevice.and.returnValue(data.isTouch);
state = jasmine.initializePlayer();
btnPlay = state.el.find('.btn-play');
@@ -97,7 +97,7 @@
{
var btnPlay;
window.onTouchBasedDevice.andReturn([device]);
window.onTouchBasedDevice.and.returnValue([device]);
state = jasmine.initializePlayer();
btnPlay = state.el.find('.btn-play');
@@ -113,7 +113,7 @@
{
var btnPlay;
window.onTouchBasedDevice.andReturn([device]);
window.onTouchBasedDevice.and.returnValue([device]);
state = jasmine.initializePlayer();
btnPlay = state.el.find('.btn-play');
@@ -128,7 +128,7 @@
{
var btnPlay;
window.onTouchBasedDevice.andReturn([device]);
window.onTouchBasedDevice.and.returnValue([device]);
state = jasmine.initializePlayerYouTube();
btnPlay = state.el.find('.btn-play');

View File

@@ -6,7 +6,7 @@
beforeEach(function () {
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice').andReturn(null);
.createSpy('onTouchBasedDevice').and.returnValue(null);
state = jasmine.initializePlayer('video_with_bumper.html');
$('.poster .btn-play').click();
spyOn(state.bumperState.videoCommands, 'execute');
@@ -19,16 +19,19 @@
state.bumperState.videoPlayer.destroy();
}
window.onTouchBasedDevice = oldOTBD;
if (state.videoPlayer) {
_.result(state.videoPlayer, 'destroy');
}
});
it('can render the control', function () {
expect($('.video_control.play')).toExist();
expect($('.video_control.play')).toBeInDOM();
});
it('can update state on play', function () {
state.el.trigger('play');
expect($('.video_control.play')).not.toExist();
expect($('.video_control.skip')).toExist();
expect($('.video_control.play')).not.toBeInDOM();
expect($('.video_control.skip')).toBeInDOM();
});
it('can start video playing on click', function () {
@@ -38,7 +41,7 @@
it('can skip the video on click', function () {
state.el.trigger('play');
spyOn(state.bumperState.videoPlayer, 'isPlaying').andReturn(true);
spyOn(state.bumperState.videoPlayer, 'isPlaying').and.returnValue(true);
$('.video_control.skip').first().click();
expect(state.bumperState.videoCommands.execute).toHaveBeenCalledWith('skip');
});
@@ -46,10 +49,10 @@
it('can destroy itself', function () {
var plugin = state.bumperState.videoPlaySkipControl,
el = plugin.el;
spyOn($.fn, 'off').andCallThrough();
spyOn($.fn, 'off').and.callThrough();
plugin.destroy();
expect(state.bumperState.videoPlaySkipControl).toBeUndefined();
expect(el).not.toExist();
expect(el).not.toBeInDOM();
expect($.fn.off).toHaveBeenCalledWith('destroy', plugin.destroy);
});
});

View File

@@ -5,12 +5,16 @@ require(
['video/03_video_player.js'],
function (VideoPlayer) {
describe('VideoPlayer', function () {
var state, oldOTBD;
var state, oldOTBD, empty_arguments;
(function () {
empty_arguments = arguments;
})();
beforeEach(function () {
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice')
.andReturn(null);
.and.returnValue(null);
});
afterEach(function () {
@@ -73,7 +77,7 @@ function (VideoPlayer) {
var events;
jasmine.stubRequests();
spyOn(window.YT, 'Player').andCallThrough();
spyOn(window.YT, 'Player').and.callThrough();
state = jasmine.initializePlayerYouTube();
state.videoEl = $('video, iframe');
@@ -107,9 +111,9 @@ function (VideoPlayer) {
state = jasmine.initializePlayerYouTube();
state.videoEl = state.el.find('video, iframe').width(100);
player = state.videoPlayer.player;
player.getAvailablePlaybackRates.andReturn([1]);
player.getAvailablePlaybackRates.and.returnValue([1]);
state.currentPlayerMode = 'html5';
spyOn(window.YT, 'Player').andCallThrough();
spyOn(window.YT, 'Player').and.callThrough();
state.videoPlayer.onReady();
expect(YT.Player).toHaveBeenCalledWith('id', {
@@ -137,7 +141,7 @@ function (VideoPlayer) {
describe('when on a touch based device', function () {
$.each(['iPad', 'Android'], function (index, device) {
it('create video volume control on' + device, function () {
window.onTouchBasedDevice.andReturn([device]);
window.onTouchBasedDevice.and.returnValue([device]);
state = jasmine.initializePlayer();
state.videoEl = $('video, iframe');
@@ -167,7 +171,7 @@ function (VideoPlayer) {
state = jasmine.initializePlayer();
state.videoEl = $('video, iframe');
spyOn(state.videoPlayer, 'play').andCallThrough();
spyOn(state.videoPlayer, 'play').and.callThrough();
state.videoPlayer.onReady();
});
@@ -204,7 +208,7 @@ function (VideoPlayer) {
state = jasmine.initializePlayerYouTube();
state.videoEl = $('video, iframe');
spyOn($.fn, 'trigger').andCallThrough();
spyOn($.fn, 'trigger').and.callThrough();
state.videoPlayer.onStateChange({
data: YT.PlayerState.ENDED
});
@@ -215,8 +219,8 @@ function (VideoPlayer) {
});
it('trigger pause and ended events', function () {
expect($.fn.trigger).toHaveBeenCalledWith('pause', {});
expect($.fn.trigger).toHaveBeenCalledWith('ended', {});
expect($.fn.trigger).toHaveBeenCalledWith('pause', empty_arguments);
expect($.fn.trigger).toHaveBeenCalledWith('ended', empty_arguments);
});
});
});
@@ -226,7 +230,7 @@ function (VideoPlayer) {
beforeEach(function () {
state = jasmine.initializePlayer();
state.videoEl = $('video, iframe');
spyOn($.fn, 'trigger').andCallThrough();
spyOn($.fn, 'trigger').and.callThrough();
state.videoPlayer.onStateChange({
data: YT.PlayerState.PAUSED
@@ -238,7 +242,7 @@ function (VideoPlayer) {
});
it('pause the video caption', function () {
expect($.fn.trigger).toHaveBeenCalledWith('pause', {});
expect($.fn.trigger).toHaveBeenCalledWith('pause', empty_arguments);
});
});
@@ -250,15 +254,15 @@ function (VideoPlayer) {
state = jasmine.initializePlayer();
oldState = state;
spyOn(oldState.videoPlayer, 'onPause').andCallThrough();
spyOn(oldState.videoPlayer, 'onPause').and.callThrough();
// Now initialize a second instance.
state = jasmine.initializePlayer();
state.videoEl = $('video, iframe');
spyOn(window, 'setInterval').andReturn(100);
spyOn($.fn, 'trigger').andCallThrough();
spyOn(window, 'setInterval').and.returnValue(100);
spyOn($.fn, 'trigger').and.callThrough();
state.videoPlayer.onStateChange({
data: YT.PlayerState.PLAYING
@@ -277,7 +281,7 @@ function (VideoPlayer) {
});
it('play the video caption', function () {
expect($.fn.trigger).toHaveBeenCalledWith('play', {});
expect($.fn.trigger).toHaveBeenCalledWith('play', empty_arguments);
});
});
@@ -289,7 +293,7 @@ function (VideoPlayer) {
state.videoEl = $('video, iframe');
spyOn($.fn, 'trigger').andCallThrough();
spyOn($.fn, 'trigger').and.callThrough();
state.videoPlayer.onStateChange({
data: YT.PlayerState.PLAYING
});
@@ -310,7 +314,7 @@ function (VideoPlayer) {
});
it('pause the video caption', function () {
expect($.fn.trigger).toHaveBeenCalledWith('pause', {});
expect($.fn.trigger).toHaveBeenCalledWith('pause', empty_arguments);
});
});
@@ -319,7 +323,7 @@ function (VideoPlayer) {
state = jasmine.initializePlayer();
state.videoEl = $('video, iframe');
spyOn($.fn, 'trigger').andCallThrough();
spyOn($.fn, 'trigger').and.callThrough();
state.videoPlayer.onStateChange({
data: YT.PlayerState.ENDED
});
@@ -330,7 +334,7 @@ function (VideoPlayer) {
});
it('pause the video caption', function () {
expect($.fn.trigger).toHaveBeenCalledWith('ended', {});
expect($.fn.trigger).toHaveBeenCalledWith('ended', empty_arguments);
});
});
});
@@ -362,59 +366,51 @@ function (VideoPlayer) {
describe('onSeek', function () {
beforeEach(function () {
// jasmine.Clock can't be used to fake out debounce with newer versions of underscore
spyOn(_, 'debounce').andCallFake(function (func) {
spyOn(_, 'debounce').and.callFake(function (func) {
return function () {
func.apply(this, arguments);
};
});
state = jasmine.initializePlayer();
state.videoEl = $('video, iframe');
spyOn(state.videoPlayer, 'duration').andReturn(120);
spyOn(state.videoPlayer, 'duration').and.returnValue(120);
});
describe('when the video is playing', function () {
beforeEach(function () {
runs(function () {
state.videoPlayer.play();
});
beforeEach(function (done) {
state.videoPlayer.play();
waitsFor(function () {
jasmine.waitUntil(function() {
return state.videoPlayer.isPlaying();
}, 'video didn\'t start playing', WAIT_TIMEOUT);
}).done(done);
});
it('call runTimer in seekTo on player', function () {
runs(function () {
spyOn(state.videoPlayer, 'stopTimer');
spyOn(state.videoPlayer, 'runTimer');
state.videoPlayer.seekTo(10);
expect(state.videoPlayer.currentTime).toBe(10);
expect(state.videoPlayer.stopTimer).toHaveBeenCalled();
expect(state.videoPlayer.runTimer).toHaveBeenCalled();
});
spyOn(state.videoPlayer, 'stopTimer').and.callThrough();
spyOn(state.videoPlayer, 'runTimer').and.callThrough();
state.videoPlayer.seekTo(10);
expect(state.videoPlayer.currentTime).toBe(10);
expect(state.videoPlayer.stopTimer).toHaveBeenCalled();
expect(state.videoPlayer.runTimer).toHaveBeenCalled();
});
it('seek the player', function () {
runs(function () {
spyOn(state.videoPlayer.player, 'seekTo').andCallThrough();
state.videoProgressSlider.onSlide(
jQuery.Event('slide'), { value: 30 }
);
expect(state.videoPlayer.currentTime).toBe(30);
expect(state.videoPlayer.player.seekTo).toHaveBeenCalledWith(30, true);
});
spyOn(state.videoPlayer.player, 'seekTo').and.callThrough();
state.videoProgressSlider.onSlide(
jQuery.Event('slide'), { value: 30 }
);
expect(state.videoPlayer.currentTime).toBe(30);
expect(state.videoPlayer.player.seekTo).toHaveBeenCalledWith(30, true);
});
it('call updatePlayTime on player', function () {
runs(function () {
spyOn(state.videoPlayer, 'updatePlayTime').andCallThrough();
state.videoProgressSlider.onSlide(
jQuery.Event('slide'), { value: 30 }
);
expect(state.videoPlayer.currentTime).toBe(30);
expect(state.videoPlayer.updatePlayTime).toHaveBeenCalledWith(30, true);
});
spyOn(state.videoPlayer, 'updatePlayTime').and.callThrough();
state.videoProgressSlider.onSlide(
jQuery.Event('slide'), { value: 30 }
);
expect(state.videoPlayer.currentTime).toBe(30);
expect(state.videoPlayer.updatePlayTime).toHaveBeenCalledWith(30, true);
});
});
@@ -433,7 +429,7 @@ function (VideoPlayer) {
describe('when the video is not playing', function () {
beforeEach(function () {
spyOn(state.videoPlayer, 'setPlaybackRate')
.andCallThrough();
.and.callThrough();
});
it('video has a correct speed', function () {
@@ -442,7 +438,7 @@ function (VideoPlayer) {
expect(state.videoPlayer.setPlaybackRate)
.toHaveBeenCalledWith('2.0', true);
state.videoPlayer.onPlay();
expect(state.videoPlayer.setPlaybackRate.calls.length)
expect(state.videoPlayer.setPlaybackRate.calls.count())
.toEqual(1);
});
});
@@ -483,7 +479,7 @@ function (VideoPlayer) {
state.videoEl = $('video, iframe');
spyOn(state.videoPlayer, 'updatePlayTime').andCallThrough();
spyOn(state.videoPlayer, 'updatePlayTime').and.callThrough();
});
describe(
@@ -535,29 +531,26 @@ function (VideoPlayer) {
state.videoEl = $('video, iframe');
spyOn(state.videoPlayer, 'update').andCallThrough();
spyOn(state.videoPlayer, 'pause').andCallThrough();
spyOn(state.videoPlayer, 'update').and.callThrough();
spyOn(state.videoPlayer, 'pause').and.callThrough();
spyOn(state.videoProgressSlider, 'notifyThroughHandleEnd')
.andCallThrough();
.and.callThrough();
});
it(
'video is paused on first endTime, start & end time are reset',
function ()
function (done)
{
var duration;
state.videoProgressSlider.notifyThroughHandleEnd.reset();
state.videoPlayer.pause.reset();
state.videoProgressSlider.notifyThroughHandleEnd.calls.reset();
state.videoPlayer.pause.calls.reset();
state.videoPlayer.play();
waitsFor(function () {
jasmine.waitUntil(function () {
duration = Math.round(state.videoPlayer.currentTime);
return state.videoPlayer.pause.calls.length === 1;
}, 'pause() has been called', WAIT_TIMEOUT);
runs(function () {
return state.videoPlayer.pause.calls.count() === 1;
}).then(function () {
expect(state.videoPlayer.startTime).toBe(0);
expect(state.videoPlayer.endTime).toBe(null);
@@ -565,7 +558,7 @@ function (VideoPlayer) {
expect(state.videoProgressSlider.notifyThroughHandleEnd)
.toHaveBeenCalledWith({end: true});
});
}).always(done);
});
});
@@ -573,14 +566,14 @@ function (VideoPlayer) {
beforeEach(function () {
state = jasmine.initializePlayerYouTube();
state.videoEl = $('video, iframe');
spyOn(state.videoCaption, 'updatePlayTime').andCallThrough();
spyOn(state.videoProgressSlider, 'updatePlayTime').andCallThrough();
spyOn(state.videoCaption, 'updatePlayTime').and.callThrough();
spyOn(state.videoProgressSlider, 'updatePlayTime').and.callThrough();
});
it('update the video playback time', function () {
it('update the video playback time', function (done) {
var duration = 0;
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
if (duration > 0) {
@@ -588,40 +581,34 @@ function (VideoPlayer) {
}
return false;
}, 'Video is fully loaded.', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
state.videoPlayer.goToStartTime = false;
state.videoPlayer.updatePlayTime(60);
expect($('.vidtime')).toHaveHtml('1:00 / 1:00');
});
}).always(done);
});
it('update the playback time on caption', function () {
waitsFor(function () {
it('update the playback time on caption', function (done) {
jasmine.waitUntil(function () {
return state.videoPlayer.duration() > 0;
}, 'Video is fully loaded.', WAIT_TIMEOUT);
runs(function () {
}, 1000).then(function () {
state.videoPlayer.goToStartTime = false;
state.videoPlayer.updatePlayTime(60);
expect(state.videoCaption.updatePlayTime)
.toHaveBeenCalledWith(60);
});
}).always(done);
});
it('update the playback time on progress slider', function () {
it('update the playback time on progress slider', function (done) {
var duration = 0;
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
return duration > 0;
}, 'Video is fully loaded.', WAIT_TIMEOUT);
runs(function () {
}, 1000).then(function () {
state.videoPlayer.goToStartTime = false;
state.videoPlayer.updatePlayTime(60);
@@ -630,7 +617,7 @@ function (VideoPlayer) {
time: 60,
duration: duration
});
});
}).always(done);
});
});
@@ -652,15 +639,15 @@ function (VideoPlayer) {
state.videoEl = $('video, iframe');
spyOn(state.videoPlayer, 'updatePlayTime').andCallThrough();
spyOn(state.videoPlayer.player, 'seekTo').andCallThrough();
spyOn(state.videoPlayer, 'updatePlayTime').and.callThrough();
spyOn(state.videoPlayer.player, 'seekTo').and.callThrough();
spyOn(state.videoProgressSlider, 'updateStartEndTimeRegion')
.andCallThrough();
.and.callThrough();
});
it(
'when duration becomes available, updatePlayTime() is called',
function ()
function (done)
{
var duration;
@@ -669,14 +656,12 @@ function (VideoPlayer) {
state.videoPlayer.play();
waitsFor(function () {
jasmine.waitUntil(function () {
duration = state.videoPlayer.duration();
return state.videoPlayer.isPlaying() &&
state.videoPlayer.initialSeekToStartTime === false;
}, 'duration becomes available', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(state.videoPlayer.startTime).toBe(START_TIME);
expect(state.videoPlayer.endTime).toBe(END_TIME);
@@ -688,7 +673,7 @@ function (VideoPlayer) {
expect(state.videoPlayer.seekToStartTimeOldSpeed)
.toBe(state.speed);
});
}).always(done);
});
});
@@ -708,7 +693,7 @@ function (VideoPlayer) {
seekTo: function () {}
},
figureOutStartEndTime: jasmine.createSpy(),
figureOutStartingTime: jasmine.createSpy().andReturn(0)
figureOutStartingTime: jasmine.createSpy().and.returnValue(0)
},
config: {
savedVideoPosition: 0,
@@ -723,7 +708,7 @@ function (VideoPlayer) {
currentPlayerMode: 'html5',
trigger: function () {},
browserIsFirefox: false,
isFlashMode: jasmine.createSpy().andReturn(false)
isFlashMode: jasmine.createSpy().and.returnValue(false)
};
});
});
@@ -733,7 +718,7 @@ function (VideoPlayer) {
beforeEach(function () {
state = jasmine.initializePlayer();
state.videoEl = $('video, iframe');
spyOn($.fn, 'trigger').andCallThrough();
spyOn($.fn, 'trigger').and.callThrough();
$('.add-fullscreen').click();
});
@@ -752,7 +737,7 @@ function (VideoPlayer) {
beforeEach(function () {
state = jasmine.initializePlayer();
state.videoEl = $('video, iframe');
spyOn($.fn, 'trigger').andCallThrough();
spyOn($.fn, 'trigger').and.callThrough();
state.el.addClass('video-fullscreen');
state.videoFullScreen.fullScreenState = true;
state.videoFullScreen.isFullScreen = true;
@@ -779,7 +764,7 @@ function (VideoPlayer) {
state.videoEl = $('video, iframe');
spyOn(state.videoPlayer.player, 'getDuration').andCallThrough();
spyOn(state.videoPlayer.player, 'getDuration').and.callThrough();
state.videoPlayer.duration();
});
@@ -801,11 +786,11 @@ function (VideoPlayer) {
state.videoEl = $('video, iframe');
spyOn(state, 'getDuration').andCallThrough();
spyOn(state, 'getDuration').and.callThrough();
// When `state.videoPlayer.player.getDuration()` returns a `0`,
// the fall-back function `state.getDuration()` will be called.
state.videoPlayer.player.getDuration.andReturn(0);
state.videoPlayer.player.getDuration.and.returnValue(0);
});
it('getDuration is called as a fall-back', function () {
@@ -821,7 +806,7 @@ function (VideoPlayer) {
state.videoEl = $('video, iframe');
spyOn(state.videoPlayer.player, 'getVolume').andCallThrough();
spyOn(state.videoPlayer.player, 'getVolume').and.callThrough();
});
it('set the player volume', function () {
@@ -841,7 +826,7 @@ function (VideoPlayer) {
['iPad', 'Android', 'iPhone'],
function (index, device)
{
window.onTouchBasedDevice.andReturn([device]);
window.onTouchBasedDevice.and.returnValue([device]);
state = jasmine.initializePlayer();
state.videoEl = $('video, iframe');
@@ -851,7 +836,7 @@ function (VideoPlayer) {
});
it('modules are not initialized on iPhone', function () {
window.onTouchBasedDevice.andReturn(['iPhone']);
window.onTouchBasedDevice.and.returnValue(['iPhone']);
state = jasmine.initializePlayer();
state.videoEl = $('video, iframe');
@@ -870,34 +855,28 @@ function (VideoPlayer) {
var message = 'controls become visible after playing starts ' +
'on ' + device;
it(message, function () {
it(message, function (done) {
var controls;
window.onTouchBasedDevice.andReturn([device]);
window.onTouchBasedDevice.and.returnValue([device]);
runs(function () {
state = jasmine.initializePlayer();
state.videoEl = $('video, iframe');
controls = state.el.find('.video-controls');
});
state = jasmine.initializePlayer();
state.videoEl = $('video, iframe');
controls = state.el.find('.video-controls');
waitsFor(function () {
jasmine.waitUntil(function () {
return state.el.hasClass('is-initialized');
},'Video is not initialized.' , WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(controls).toHaveClass('is-hidden');
state.videoPlayer.play();
});
waitsFor(function () {
var duration = state.videoPlayer.duration();
return duration > 0 && state.videoPlayer.isPlaying();
},'Video does not play.' , WAIT_TIMEOUT);
runs(function () {
expect(controls).not.toHaveClass('is-hidden');
jasmine.waitUntil(function () {
// Firefox does not return duration for videos until they have reached the end.
// var duration = state.videoPlayer.duration();
// return duration > 0 && state.videoPlayer.isPlaying();
return state.videoPlayer.isPlaying();
}).then(function () {
expect(controls).not.toHaveClass('is-hidden');
}).always(done);
});
});
});
@@ -916,13 +895,13 @@ function (VideoPlayer) {
setPlaybackRate: jasmine.createSpy(),
player: jasmine.createSpyObj('player', ['setPlaybackRate'])
},
isFlashMode: jasmine.createSpy().andReturn(false)
isFlashMode: jasmine.createSpy().and.returnValue(false)
};
});
describe('always', function () {
it('convert the current time to the new speed', function () {
state.isFlashMode.andReturn(true);
state.isFlashMode.and.returnValue(true);
VideoPlayer.prototype.onSpeedChange.call(state, '0.75', false);
expect(state.videoPlayer.currentTime).toBe('120.000');
});
@@ -939,17 +918,17 @@ function (VideoPlayer) {
describe('setPlaybackRate', function () {
beforeEach(function () {
state = {
youtubeId: jasmine.createSpy().andReturn('videoId'),
isFlashMode: jasmine.createSpy().andReturn(false),
isHtml5Mode: jasmine.createSpy().andReturn(true),
isYoutubeType: jasmine.createSpy().andReturn(true),
youtubeId: jasmine.createSpy().and.returnValue('videoId'),
isFlashMode: jasmine.createSpy().and.returnValue(false),
isHtml5Mode: jasmine.createSpy().and.returnValue(true),
isYoutubeType: jasmine.createSpy().and.returnValue(true),
setPlayerMode: jasmine.createSpy(),
trigger: jasmine.createSpy(),
videoPlayer: {
currentTime: 60,
isPlaying: jasmine.createSpy(),
seekTo: jasmine.createSpy(),
duration: jasmine.createSpy().andReturn(60),
duration: jasmine.createSpy().and.returnValue(60),
updatePlayTime: jasmine.createSpy(),
setPlaybackRate: jasmine.createSpy(),
player: jasmine.createSpyObj('player', [
@@ -960,9 +939,9 @@ function (VideoPlayer) {
});
it('in Flash mode and video is playing', function () {
state.isFlashMode.andReturn(true);
state.isHtml5Mode.andReturn(false);
state.videoPlayer.isPlaying.andReturn(true);
state.isFlashMode.and.returnValue(true);
state.isHtml5Mode.and.returnValue(false);
state.videoPlayer.isPlaying.and.returnValue(true);
VideoPlayer.prototype.setPlaybackRate.call(state, '0.75');
expect(state.videoPlayer.updatePlayTime).toHaveBeenCalledWith(60);
expect(state.videoPlayer.player.loadVideoById)
@@ -970,9 +949,9 @@ function (VideoPlayer) {
});
it('in Flash mode and video not started', function () {
state.isFlashMode.andReturn(true);
state.isHtml5Mode.andReturn(false);
state.videoPlayer.isPlaying.andReturn(false);
state.isFlashMode.and.returnValue(true);
state.isHtml5Mode.and.returnValue(false);
state.videoPlayer.isPlaying.and.returnValue(false);
VideoPlayer.prototype.setPlaybackRate.call(state, '0.75');
expect(state.videoPlayer.updatePlayTime).toHaveBeenCalledWith(60);
expect(state.videoPlayer.seekTo).toHaveBeenCalledWith(60);
@@ -986,7 +965,7 @@ function (VideoPlayer) {
});
it('in HTML5 mode', function () {
state.isYoutubeType.andReturn(false);
state.isYoutubeType.and.returnValue(false);
VideoPlayer.prototype.setPlaybackRate.call(state, '0.75');
expect(state.videoPlayer.player.setPlaybackRate).toHaveBeenCalledWith('0.75');
});
@@ -994,7 +973,7 @@ function (VideoPlayer) {
it('Youtube video in FF, with new speed equal 1.0', function () {
state.browserIsFirefox = true;
state.videoPlayer.isPlaying.andReturn(false);
state.videoPlayer.isPlaying.and.returnValue(false);
VideoPlayer.prototype.setPlaybackRate.call(state, '1.0');
expect(state.videoPlayer.updatePlayTime).toHaveBeenCalledWith(60);
expect(state.videoPlayer.player.cueVideoById)

View File

@@ -6,7 +6,7 @@
beforeEach(function () {
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice').andReturn(null);
.createSpy('onTouchBasedDevice').and.returnValue(null);
state = jasmine.initializePlayer('video_with_bumper.html');
});
@@ -27,11 +27,11 @@
expect($('.btn-play')).toExist();
});
it('can start playing the video on click', function () {
it('can start playing the video on click', function (done) {
$('.btn-play').click();
waitsFor(function () {
jasmine.waitUntil(function() {
return state.el.hasClass('is-playing');
}, 'Player is not playing.', WAIT_TIMEOUT);
}).done(done);
});
it('destroy itself on "play" event', function () {

View File

@@ -5,7 +5,7 @@
beforeEach(function () {
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice')
.andReturn(null);
.and.returnValue(null);
});
afterEach(function () {
@@ -18,26 +18,25 @@
describe('constructor', function () {
describe('on a non-touch based device', function () {
beforeEach(function () {
spyOn($.fn, 'slider').andCallThrough();
spyOn($.fn, 'slider').and.callThrough();
state = jasmine.initializePlayer();
});
it('build the slider', function () {
expect(state.videoProgressSlider.slider).toBe('.slider');
expect($('.slider')).toContain(state.videoProgressSlider.slider);
expect($.fn.slider).toHaveBeenCalledWith({
range: 'min',
min: 0,
max: null,
change: state.videoProgressSlider.onChange,
slide: state.videoProgressSlider.onSlide,
stop: state.videoProgressSlider.onStop
});
});
it('build the seek handle', function () {
expect(state.videoProgressSlider.handle)
.toBe('.slider .ui-slider-handle');
expect($('.ui-slider-handle'))
.toContain(state.videoProgressSlider.handle);
});
it('add ARIA attributes to time control', function () {
@@ -56,7 +55,7 @@
describe('on a touch-based device', function () {
it('does not build the slider on iPhone', function () {
window.onTouchBasedDevice.andReturn(['iPhone']);
window.onTouchBasedDevice.and.returnValue(['iPhone']);
state = jasmine.initializePlayer();
@@ -67,7 +66,7 @@
});
$.each(['iPad', 'Android'], function (index, device) {
it('build the slider on ' + device, function () {
window.onTouchBasedDevice.andReturn([device]);
window.onTouchBasedDevice.and.returnValue([device]);
state = jasmine.initializePlayer();
@@ -87,12 +86,12 @@
beforeEach(function () {
spy = spyOn(state.videoProgressSlider, 'buildSlider');
spy.andCallThrough();
spy.and.callThrough();
state.videoPlayer.play();
});
it('does not build the slider', function () {
expect(spy.callCount).toEqual(0);
expect(spy.calls.count()).toEqual(0);
});
});
@@ -106,7 +105,7 @@
describe('when frozen', function () {
beforeEach(function () {
spyOn($.fn, 'slider').andCallThrough();
spyOn($.fn, 'slider').and.callThrough();
state.videoProgressSlider.frozen = true;
state.videoProgressSlider.updatePlayTime(20, 120);
});
@@ -118,7 +117,7 @@
describe('when not frozen', function () {
beforeEach(function () {
spyOn($.fn, 'slider').andCallThrough();
spyOn($.fn, 'slider').and.callThrough();
state.videoProgressSlider.frozen = false;
state.videoProgressSlider.updatePlayTime({
time: 20,
@@ -149,8 +148,8 @@
beforeEach(function () {
state = jasmine.initializePlayer();
spyOn($.fn, 'slider').andCallThrough();
spyOn(state.videoPlayer, 'onSlideSeek').andCallThrough();
spyOn($.fn, 'slider').and.callThrough();
spyOn(state.videoPlayer, 'onSlideSeek').and.callThrough();
});
// Disabled 12/30/13 due to flakiness in master
@@ -175,11 +174,15 @@
describe('onStop', function () {
beforeEach(function () {
jasmine.Clock.useMock();
jasmine.clock().install();
state = jasmine.initializePlayer();
spyOn(state.videoPlayer, 'onSlideSeek').andCallThrough();
spyOn(state.videoPlayer, 'onSlideSeek').and.callThrough();
});
afterEach(function () {
jasmine.clock().uninstall();
});
// Disabled 12/30/13 due to flakiness in master
@@ -206,7 +209,7 @@
jQuery.Event('stop'), { value: 20 }
);
jasmine.Clock.tick(200);
jasmine.clock().tick(200);
expect(state.videoProgressSlider.frozen).toBeFalsy();
});
@@ -255,7 +258,7 @@
spyOnEvent(state.videoProgressSlider.handle, 'focus');
spyOn(state.videoProgressSlider, 'notifyThroughHandleEnd')
.andCallThrough();
.and.callThrough();
});
it('params.end = true', function () {
@@ -280,17 +283,14 @@
);
});
it('is called when video plays', function () {
it('is called when video plays', function (done) {
state.videoPlayer.play();
waitsFor(function () {
jasmine.waitUntil(function() {
return state.videoPlayer.isPlaying();
}, 'duration is set, video is playing', 5000);
}).done(function() {
expect(state.videoProgressSlider.notifyThroughHandleEnd).toHaveBeenCalledWith({end: false});
}).always(done);
runs(function () {
expect(state.videoProgressSlider.notifyThroughHandleEnd)
.toHaveBeenCalledWith({end: false});
});
});
});

View File

@@ -19,7 +19,7 @@
// Define empty methods in YouTube stub
player.quality = 'large';
player.setPlaybackQuality.andCallFake(function (quality){
player.setPlaybackQuality.and.callFake(function (quality){
player.quality = quality;
});
});
@@ -46,13 +46,13 @@
});
it('calls fetchAvailableQualities only once', function () {
expect(player.getAvailableQualityLevels.calls.length)
expect(player.getAvailableQualityLevels.calls.count())
.toEqual(0);
videoPlayer.onPlay();
videoPlayer.onPlay();
expect(player.getAvailableQualityLevels.calls.length)
expect(player.getAvailableQualityLevels.calls.count())
.toEqual(1);
});
@@ -71,7 +71,7 @@
it('leaves quality control hidden on play if HD is not available',
function () {
player.getAvailableQualityLevels.andReturn(
player.getAvailableQualityLevels.and.returnValue(
['large', 'medium', 'small']
);
@@ -94,7 +94,7 @@
it('quality control is active if HD is available',
function () {
player.getAvailableQualityLevels.andReturn(
player.getAvailableQualityLevels.and.returnValue(
['highres', 'hd1080', 'hd720']
);

View File

@@ -7,14 +7,14 @@
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice')
.andReturn(null);
.and.returnValue(null);
jasmine.stubRequests();
state = jasmine.initializePlayer();
spyOn(state.storage, 'setItem');
});
afterEach(function () {
$('source').remove();
window.onTouchBasedDevice = oldOTBD;
state.storage.clear();
@@ -41,7 +41,7 @@
beforeEach(function () {
state.videoPlayer.currentTime = videoPlayerCurrentTime;
spyOn(Time, 'formatFull').andCallThrough();
spyOn(window.Time, 'formatFull').and.callThrough();
});
it('data is not an object, async is true', function () {
@@ -172,7 +172,7 @@
});
it('can save state on page unload', function () {
$.ajax.reset();
$.ajax.calls.reset();
state.videoSaveStatePlugin.onUnload();
expect($.ajax).toHaveBeenCalledWith({
url: state.config.saveStateUrl,
@@ -212,7 +212,7 @@
it('can destroy itself', function () {
var plugin = state.videoSaveStatePlugin;
spyOn($.fn, 'off').andCallThrough();
spyOn($.fn, 'off').and.callThrough();
state.videoSaveStatePlugin.destroy();
expect(state.videoSaveStatePlugin).toBeUndefined();
expect($.fn.off).toHaveBeenCalledWith({

View File

@@ -6,10 +6,10 @@
beforeEach(function () {
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice').andReturn(null);
.createSpy('onTouchBasedDevice').and.returnValue(null);
state = jasmine.initializePlayer('video_with_bumper.html');
$('.poster .btn-play').click();
spyOn(state.bumperState.videoCommands, 'execute').andCallThrough();
spyOn(state.bumperState.videoCommands, 'execute').and.callThrough();
});
afterEach(function () {

View File

@@ -6,7 +6,7 @@
beforeEach(function () {
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice')
.andReturn(null);
.and.returnValue(null);
});
afterEach(function () {
@@ -26,8 +26,8 @@
var secondaryControls = $('.secondary-controls'),
li = secondaryControls.find('.video-speeds li');
expect(secondaryControls).toContain('.speeds');
expect(secondaryControls).toContain('.video-speeds');
expect(secondaryControls).toContainElement('.speeds');
expect(secondaryControls).toContainElement('.video-speeds');
expect(secondaryControls.find('.value').text())
.toBe('1.50x');
expect(li.filter('.is-active')).toHaveData(
@@ -36,9 +36,7 @@
expect(li.length).toBe(state.speeds.length);
$.each(li.toArray().reverse(), function (index, link) {
expect($(link)).toHaveData(
'speed', state.speeds[index]
);
expect($(link).attr('data-speed')).toEqual(state.speeds[index]);
expect($(link).find('.speed-option').text()).toBe(
state.speeds[index] + 'x'
);
@@ -49,7 +47,7 @@
describe('when running on touch based device', function () {
$.each(['iPad', 'Android'], function (index, device) {
it('is not rendered on' + device, function () {
window.onTouchBasedDevice.andReturn([device]);
window.onTouchBasedDevice.and.returnValue([device]);
state = jasmine.initializePlayer();
expect(state.el.find('.speeds')).not.toExist();

View File

@@ -19,7 +19,7 @@ function (VideoStorage) {
});
it('without namespace and id', function () {
spyOn(Number.prototype, 'toString').andReturn('0.abcdedg');
spyOn(Number.prototype, 'toString').and.returnValue('0.abcdedg');
var storage = VideoStorage();
expect(window.VideoStorage).toBeDefined();

View File

@@ -12,7 +12,7 @@ describe('VideoVolumeControl', function () {
beforeEach(function () {
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice')
.andReturn(null);
.and.returnValue(null);
});
afterEach(function () {
@@ -23,7 +23,7 @@ describe('VideoVolumeControl', function () {
});
it('Volume level has correct value even if cookie is broken', function () {
$.cookie.andReturn('broken_cookie');
$.cookie.and.returnValue('broken_cookie');
state = jasmine.initializePlayer();
volumeControl = state.videoVolumeControl;
expect(volumeControl.volume).toEqual(100);
@@ -31,8 +31,8 @@ describe('VideoVolumeControl', function () {
describe('constructor', function () {
beforeEach(function () {
spyOn($.fn, 'slider').andCallThrough();
$.cookie.andReturn('75');
spyOn($.fn, 'slider').and.callThrough();
$.cookie.and.returnValue('75');
state = jasmine.initializePlayer();
volumeControl = state.videoVolumeControl;
});
@@ -46,7 +46,7 @@ describe('VideoVolumeControl', function () {
});
it('create the slider', function () {
expect($.fn.slider.calls[2].args).toEqual([{
expect($.fn.slider.calls.argsFor(2)).toEqual([{
orientation: 'vertical',
range: 'min',
min: 0,
@@ -94,16 +94,23 @@ describe('VideoVolumeControl', function () {
state = jasmine.initializePlayer();
volumeControl = state.videoVolumeControl;
this.addMatchers({
assertLiveRegionState: function (volume, expectation) {
var region = $('.video-live-region');
jasmine.addMatchers({
assertLiveRegionState: function () {
return {
compare: function (actual, volume, expectation) {
var region = $('.video-live-region');
var getExpectedText = function (text) {
return text + ' Volume.';
var getExpectedText = function (text) {
return text + ' Volume.';
};
actual.setVolume(volume, true, true);
return {
pass: region.text() === getExpectedText(expectation)
};
}
};
this.actual.setVolume(volume, true, true);
return region.text() === getExpectedText(expectation);
}
});
});

View File

@@ -36,7 +36,7 @@
window.Video = jasmine.createSpy('Video');
removeVideo = true;
}
window.Video.andReturn(videoModule);
window.Video.and.returnValue(videoModule);
editCallback = jasmine.createSpy('editCallback');
$(document).on('XModule.loaded.edit', editCallback);
@@ -171,7 +171,7 @@
el = 'dummy object';
obj = new XModule.Descriptor(el);
spyOn(obj, 'save').andCallThrough();
spyOn(obj, 'save').and.callThrough();
});
afterEach(function () {
@@ -225,7 +225,7 @@
obj.onUpdate(callback1);
obj.onUpdate(callback2);
obj.save.andReturn(testValue);
obj.save.and.returnValue(testValue);
obj.update();
expect(callback1).toHaveBeenCalledWith(testValue);

View File

@@ -13,7 +13,7 @@ class @DiscussionSpecHelper
DiscussionUtil.roleIds["Moderator"].push(parseInt(DiscussionUtil.getUser().id))
@makeAjaxSpy = (fakeAjax) ->
spyOn($, "ajax").andCallFake(
spyOn($, "ajax").and.callFake(
(params) ->
fakeAjax(params)
{always: ->}

View File

@@ -6,8 +6,8 @@ describe 'DiscussionUtil', ->
it "calls through to safeAjax with correct params, and reverts the model in case of failure", ->
deferred = $.Deferred()
spyOn($, "ajax").andReturn(deferred)
spyOn(DiscussionUtil, "safeAjax").andCallThrough()
spyOn($, "ajax").and.returnValue(deferred)
spyOn(DiscussionUtil, "safeAjax").and.callThrough()
model = new Backbone.Model({hello: false, number: 42})
updates = {hello: "world"}
@@ -19,7 +19,7 @@ describe 'DiscussionUtil', ->
# the error message callback should be set up correctly
spyOn(DiscussionUtil, "discussionAlert")
DiscussionUtil.safeAjax.mostRecentCall.args[0].error()
DiscussionUtil.safeAjax.calls.mostRecent().args[0].error()
expect(DiscussionUtil.discussionAlert).toHaveBeenCalledWith("Sorry", "error message")
# if the ajax call ends in failure, the model state should be reverted
@@ -27,7 +27,7 @@ describe 'DiscussionUtil', ->
expect(model.attributes).toEqual({hello: false, number: 42})
it "rolls back the changes if the associated element is disabled", ->
spyOn(DiscussionUtil, "safeAjax").andCallThrough()
spyOn(DiscussionUtil, "safeAjax").and.callThrough()
model = new Backbone.Model({hello: false, number: 42})
updates = {hello: "world"}
@@ -35,7 +35,7 @@ describe 'DiscussionUtil', ->
# This is the element that is disabled/enabled while the ajax request is
# in progress
$elem = jasmine.createSpyObj('$elem', ['attr'])
$elem.attr.andReturn(true)
$elem.attr.and.returnValue(true)
res = DiscussionUtil.updateWithUndo(model, updates, {foo: "bar", $elem:$elem}, "error message")

View File

@@ -27,7 +27,7 @@
});
testUpdate = function(view, thread, newTopicId, newTopicName) {
spyOn($, 'ajax').andCallFake(function(params) {
spyOn($, 'ajax').and.callFake(function(params) {
expect(params.url.path()).toEqual(DiscussionUtil.urlFor('update_thread', 'dummy_id'));
expect(params.data.thread_type).toBe('discussion');
expect(params.data.commentable_id).toBe(newTopicId);
@@ -35,7 +35,10 @@
params.success();
return {always: function() {}};
});
view.$el.find('a.topic-title[data-discussion-id="'+newTopicId+'"]').click(); // set new topic
view.$el.find('a.topic-title').filter(function (idx, el) {
return $(el).data('discussionId') === newTopicId;
}).click(); // set new topic
view.$('.edit-post-title').val('changed thread title'); // set new title
view.$("label[for$='post-type-discussion']").click(); // set new thread type
view.$('.post-update').click();
@@ -62,7 +65,7 @@
testCancel = function(view) {
view.$('.post-cancel').click();
expect($('.edit-post-form')).not.toExist();
}
};
it('can close the view in tab mode', function() {
this.createEditView();
@@ -104,11 +107,11 @@
it('can save new data correctly for current discussion id with dots', function () {
this.createEditView({topicId: "6.00.1x_General"});
testUpdate(this.view, this.thread, "6>00'1x\"Basic_Question", "Basic Question");
testUpdate(this.view, this.thread, "6>00\'1x\"Basic_Question", "Basic Question");
});
it('can save new data correctly for current discussion id with special characters', function () {
this.createEditView({topicId: "6>00'1x\"Basic_Question"});
this.createEditView({topicId: "6>00\'1x\"Basic_Question"});
testUpdate(this.view, this.thread, "6.00.1x_General", "General");
});
});

View File

@@ -131,8 +131,8 @@ describe "DiscussionThreadListView", ->
created_at: '2013-04-03T20:05:39Z',
}),
]
spyOn($, "ajax")
deferred = $.Deferred()
spyOn($, "ajax").and.returnValue(deferred);
@discussion = new Discussion([])
@view = new DiscussionThreadListView(
@@ -143,7 +143,7 @@ describe "DiscussionThreadListView", ->
@view.render()
setupAjax = (callback) ->
$.ajax.andCallFake(
$.ajax.and.callFake(
(params) =>
if callback
callback(params)
@@ -162,7 +162,7 @@ describe "DiscussionThreadListView", ->
)
expectFilter = (filterVal) ->
$.ajax.andCallFake((params) ->
$.ajax.and.callFake((params) ->
_.each(["unread", "unanswered", "flagged"], (paramName)->
if paramName == filterVal
expect(params.data[paramName]).toEqual(true)
@@ -199,7 +199,7 @@ describe "DiscussionThreadListView", ->
expectedGroupId = optionInfo.expectedGroupId
@view.$(".forum-nav-filter-cohort-control").val(optionInfo.val).change()
expect($.ajax).toHaveBeenCalled()
$.ajax.reset()
$.ajax.calls.reset()
)
it "search should clear filter", ->
@@ -255,7 +255,7 @@ describe "DiscussionThreadListView", ->
sorted_threads = [threads[0], threads[3], threads[2], threads[1]]
else if new_type == 'votes'
sorted_threads = [threads[3], threads[0], threads[1], threads[2]]
$.ajax.andCallFake((params) =>
$.ajax.and.callFake((params) =>
params.success(
{"discussion_data":sorted_threads, page:1, num_pages:1}
)
@@ -307,7 +307,7 @@ describe "DiscussionThreadListView", ->
testCorrection = (view, correctedText) ->
spyOn(view, "addSearchAlert")
$.ajax.andCallFake(
$.ajax.and.callFake(
(params) =>
params.success(
{discussion_data: [], page: 42, num_pages: 99, corrected_text: correctedText}, 'success'
@@ -319,13 +319,13 @@ describe "DiscussionThreadListView", ->
it "adds a search alert when an alternate term was searched", ->
testCorrection(@view, "foo")
expect(@view.addSearchAlert.callCount).toEqual(1)
expect(@view.addSearchAlert.mostRecentCall.args[0]).toMatch(/foo/)
expect(@view.addSearchAlert.calls.count()).toEqual(1)
expect(@view.addSearchAlert.calls.mostRecent().args[0]).toMatch(/foo/)
it "does not add a search alert when no alternate term was searched", ->
testCorrection(@view, null)
expect(@view.addSearchAlert.callCount).toEqual(1)
expect(@view.addSearchAlert.mostRecentCall.args[0]).toMatch(/no threads matched/i)
expect(@view.addSearchAlert.calls.count()).toEqual(1)
expect(@view.addSearchAlert.calls.mostRecent().args[0]).toMatch(/no threads matched/i)
it "clears search alerts when a new search is performed", ->
spyOn(@view, "clearSearchAlerts")
@@ -356,7 +356,7 @@ describe "DiscussionThreadListView", ->
describe "username search", ->
it "makes correct ajax calls", ->
$.ajax.andCallFake(
$.ajax.and.callFake(
(params) =>
expect(params.data.username).toEqual("testing-username")
expect(params.url.path()).toEqual(DiscussionUtil.urlFor("users"))
@@ -371,7 +371,7 @@ describe "DiscussionThreadListView", ->
setAjaxResults = (threadSuccess, userResult) ->
# threadSuccess is a boolean indicating whether the thread search ajax call should succeed
# userResult is the value that should be returned as data from the username search ajax call
$.ajax.andCallFake(
$.ajax.and.callFake(
(params) =>
if params.data.text and threadSuccess
params.success(
@@ -387,14 +387,14 @@ describe "DiscussionThreadListView", ->
)
it "gets called after a thread search succeeds", ->
spyOn(@view, "searchForUser").andCallThrough()
spyOn(@view, "searchForUser").and.callThrough()
setAjaxResults(true, [])
@view.searchFor("gizmo")
expect(@view.searchForUser).toHaveBeenCalled()
expect($.ajax.mostRecentCall.args[0].data.username).toEqual("gizmo")
expect($.ajax.calls.mostRecent().args[0].data.username).toEqual("gizmo")
it "does not get called after a thread search fails", ->
spyOn(@view, "searchForUser").andCallThrough()
spyOn(@view, "searchForUser").and.callThrough()
setAjaxResults(false, [])
@view.searchFor("gizmo")
expect(@view.searchForUser).not.toHaveBeenCalled()
@@ -405,7 +405,7 @@ describe "DiscussionThreadListView", ->
@view.searchForUser("dummy")
expect($.ajax).toHaveBeenCalled()
expect(@view.addSearchAlert).toHaveBeenCalled()
expect(@view.addSearchAlert.mostRecentCall.args[0]).toMatch(/gizmo/)
expect(@view.addSearchAlert.calls.mostRecent().args[0]).toMatch(/gizmo/)
it "does not add a search alert when no username was matched", ->
spyOn(@view, "addSearchAlert")
@@ -581,7 +581,7 @@ describe "DiscussionThreadListView", ->
,
"Following"
)
expect($.ajax.mostRecentCall.args[0].data.group_id).toBeUndefined();
expect($.ajax.calls.mostRecent().args[0].data.group_id).toBeUndefined();
it "should get threads for the selected leaf", ->
testSelectionRequest(

View File

@@ -27,7 +27,7 @@ describe "DiscussionThreadProfileView", ->
return thread
spyConvertMath = (view) ->
spyOn(view, "convertMath").andCallFake( ->
spyOn(view, "convertMath").and.callFake( ->
@model.set('markdownBody', @model.get('body'))
)

View File

@@ -22,7 +22,7 @@ describe "DiscussionThreadShowView", ->
@thread = new Thread(@threadData)
@view = new DiscussionThreadShowView({ model: @thread })
@view.setElement($("#fixture-element"))
@spyOn(@view, "convertMath")
spyOn(@view, "convertMath")
describe "voting", ->

View File

@@ -3,11 +3,12 @@ describe "DiscussionThreadView", ->
DiscussionSpecHelper.setUpGlobals()
DiscussionSpecHelper.setUnderscoreFixtures()
jasmine.Clock.useMock()
jasmine.clock().install()
@threadData = DiscussionViewSpecHelper.makeThreadWithProps({})
@thread = new Thread(@threadData)
@discussion = new Discussion(@thread)
spyOn($, "ajax")
deferred = $.Deferred();
spyOn($, "ajax").and.returnValue(deferred);
# Avoid unnecessary boilerplate
spyOn(DiscussionThreadShowView.prototype, "convertMath")
spyOn(DiscussionContentView.prototype, "makeWmdEditor")
@@ -15,8 +16,12 @@ describe "DiscussionThreadView", ->
spyOn(DiscussionUtil, "setWmdContent")
spyOn(ThreadResponseShowView.prototype, "convertMath")
afterEach ->
$.ajax.calls.reset()
jasmine.clock().uninstall()
renderWithContent = (view, content) ->
$.ajax.andCallFake((params) =>
$.ajax.and.callFake((params) =>
params.success(
createAjaxResponseJson(content, false),
'success'
@@ -24,7 +29,7 @@ describe "DiscussionThreadView", ->
{always: ->}
)
view.render()
jasmine.Clock.tick(100)
jasmine.clock().tick(100)
renderWithTestResponses = (view, count, options) ->
renderWithContent(
@@ -85,8 +90,8 @@ describe "DiscussionThreadView", ->
postResponse = (view, index) ->
testResponseJson = createTestResponseJson(index)
responseText = testResponseJson.body
spyOn(view, "getWmdContent").andReturn(responseText)
$.ajax.andCallFake((params) =>
spyOn(view, "getWmdContent").and.returnValue(responseText)
$.ajax.and.callFake((params) =>
expect(params.type).toEqual("POST")
expect(params.data.body).toEqual(responseText)
params.success(
@@ -112,7 +117,7 @@ describe "DiscussionThreadView", ->
renderWithTestResponses(view, 1)
if mode == "inline"
view.expand()
spyOn(DiscussionUtil, "updateWithUndo").andCallFake(
spyOn(DiscussionUtil, "updateWithUndo").and.callFake(
(model, updates, safeAjaxParams, errorMsg) ->
model.set(updates)
)
@@ -240,16 +245,18 @@ describe "DiscussionThreadView", ->
expect(@view.$el.find(".responses li").length).toEqual(0)
describe "focus", ->
it "sends focus to the conversation when opened", ->
it "sends focus to the conversation when opened", (done) ->
DiscussionViewSpecHelper.setNextResponseContent({resp_total: 0, children: []})
@view.render()
@view.expand()
waitsFor (->
self = @
jasmine.waitUntil(->
# This is the implementation of "toBeFocused". However, simply calling that method
# with no wait seems to be flaky.
article = @view.$el.find('.discussion-article')
article = self.view.$el.find('.discussion-article')
return article[0] == article[0].ownerDocument.activeElement
), "conversation did not receive focus", 3000
).then ->
done()
describe "expand/collapse", ->
it "shows/hides appropriate content", ->
@@ -269,12 +276,12 @@ describe "DiscussionThreadView", ->
@view.render()
expect($(".post-body").text()).toEqual(expectedAbbreviation)
expect(DiscussionThreadShowView.prototype.convertMath).toHaveBeenCalled()
DiscussionThreadShowView.prototype.convertMath.reset()
DiscussionThreadShowView.prototype.convertMath.calls.reset()
@view.expand()
expect($(".post-body").text()).toEqual(longBody)
expect(DiscussionThreadShowView.prototype.convertMath).toHaveBeenCalled()
DiscussionThreadShowView.prototype.convertMath.reset()
DiscussionThreadShowView.prototype.convertMath.calls.reset()
@view.collapse()
expect($(".post-body").text()).toEqual(expectedAbbreviation)

View File

@@ -193,10 +193,11 @@ describe "DiscussionUserProfileView", ->
describe "pagination interaction", ->
beforeEach ->
@view = makeView(makeThreads(3), 1, 2)
spyOn($, "ajax")
deferred = $.Deferred();
spyOn($, "ajax").and.returnValue(deferred);
it "causes updated rendering", ->
$.ajax.andCallFake(
$.ajax.and.callFake(
(params) =>
params.success(
discussion_data: [{id: "on_page_42", body: "dummy body"}]
@@ -211,7 +212,7 @@ describe "DiscussionUserProfileView", ->
it "handles AJAX errors", ->
spyOn(DiscussionUtil, "discussionAlert")
$.ajax.andCallFake(
$.ajax.and.callFake(
(params) =>
params.error()
{always: ->}

View File

@@ -50,7 +50,7 @@ class @DiscussionViewSpecHelper
triggerVoteEvent = (view, event, expectedUrl) ->
deferred = $.Deferred()
spyOn($, "ajax").andCallFake((params) =>
spyOn($, "ajax").and.callFake((params) =>
expect(params.url.toString()).toEqual(expectedUrl)
return deferred
)
@@ -80,10 +80,10 @@ class @DiscussionViewSpecHelper
button.click()
expect(spy).toHaveBeenCalled()
spy.reset()
spy.calls.reset()
button.trigger($.Event("keydown", {which: 13}))
expect(spy).not.toHaveBeenCalled()
spy.reset()
spy.calls.reset()
button.trigger($.Event("keydown", {which: 32}))
expect(spy).toHaveBeenCalled()
@@ -91,7 +91,7 @@ class @DiscussionViewSpecHelper
@checkButtonEvents(view, "toggleVote", ".action-vote")
@setNextResponseContent = (content) ->
$.ajax.andCallFake(
$.ajax.and.callFake(
(params) =>
params.success({"content": content})
{always: ->}

View File

@@ -4,7 +4,7 @@ describe "NewPostView", ->
DiscussionSpecHelper.setUpGlobals()
DiscussionSpecHelper.setUnderscoreFixtures()
window.$$course_id = "edX/999/test"
spyOn(DiscussionUtil, "makeWmdEditor").andCallFake(
spyOn(DiscussionUtil, "makeWmdEditor").and.callFake(
($content, $local, cls_identifier) ->
$local("." + cls_identifier).html("<textarea></textarea>")
)
@@ -91,7 +91,7 @@ describe "NewPostView", ->
@view.$(".js-post-body textarea").val("dummy body")
@view.$(".forum-new-post-form").submit()
expect($.ajax).toHaveBeenCalled()
$.ajax.reset()
$.ajax.calls.reset()
)
describe "always cohort inline discussions ", ->
@@ -209,7 +209,7 @@ describe "NewPostView", ->
it "posts to the correct URL", ->
topicId = "test_topic"
spyOn($, "ajax").andCallFake(
spyOn($, "ajax").and.callFake(
(params) ->
expect(params.url.path()).toEqual(DiscussionUtil.urlFor("create_thread", topicId))
{always: ->}

View File

@@ -25,14 +25,14 @@ describe 'ResponseCommentView', ->
spyOn(@view.$el, "remove")
setAjaxResult = (isSuccess) ->
spyOn($, "ajax").andCallFake(
spyOn($, "ajax").and.callFake(
(params) =>
(if isSuccess then params.success else params.error) {}
{always: ->}
)
it 'requires confirmation before deleting', ->
spyOn(window, "confirm").andReturn(false)
spyOn(window, "confirm").and.returnValue(false)
setAjaxResult(true)
@view._delete(@event)
expect(window.confirm).toHaveBeenCalled()
@@ -50,7 +50,7 @@ describe 'ResponseCommentView', ->
@view._delete(@event)
expect(@event.preventDefault).toHaveBeenCalled()
expect($.ajax).toHaveBeenCalled()
expect($.ajax.mostRecentCall.args[0].url._parts.path).toEqual('/courses/edX/999/test/discussion/comments/01234567/delete')
expect($.ajax.calls.mostRecent().args[0].url._parts.path).toEqual('/courses/edX/999/test/discussion/comments/01234567/delete')
it 'handles ajax errors', ->
spyOn(DiscussionUtil, "discussionAlert")
@@ -125,7 +125,7 @@ describe 'ResponseCommentView', ->
@view.$el.find(".edit-comment-body").html($("<textarea></textarea>"))
@view.$el.find(".edit-comment-body textarea").val(@updatedBody)
spyOn(@view, 'cancelEdit')
spyOn($, "ajax").andCallFake(
spyOn($, "ajax").and.callFake(
(params) =>
if @ajaxSucceed
params.success()
@@ -138,8 +138,8 @@ describe 'ResponseCommentView', ->
@ajaxSucceed = true
@view.update(DiscussionSpecHelper.makeEventSpy())
expect($.ajax).toHaveBeenCalled()
expect($.ajax.mostRecentCall.args[0].url._parts.path).toEqual('/courses/edX/999/test/discussion/comments/01234567/update')
expect($.ajax.mostRecentCall.args[0].data.body).toEqual(@updatedBody)
expect($.ajax.calls.mostRecent().args[0].url._parts.path).toEqual('/courses/edX/999/test/discussion/comments/01234567/update')
expect($.ajax.calls.mostRecent().args[0].data.body).toEqual(@updatedBody)
expect(@view.model.get("body")).toEqual(@updatedBody)
expect(@view.cancelEdit).toHaveBeenCalled()
@@ -148,8 +148,8 @@ describe 'ResponseCommentView', ->
@ajaxSucceed = false
@view.update(DiscussionSpecHelper.makeEventSpy())
expect($.ajax).toHaveBeenCalled()
expect($.ajax.mostRecentCall.args[0].url._parts.path).toEqual('/courses/edX/999/test/discussion/comments/01234567/update')
expect($.ajax.mostRecentCall.args[0].data.body).toEqual(@updatedBody)
expect($.ajax.calls.mostRecent().args[0].url._parts.path).toEqual('/courses/edX/999/test/discussion/comments/01234567/update')
expect($.ajax.calls.mostRecent().args[0].data.body).toEqual(@updatedBody)
expect(@view.model.get("body")).toEqual(originalBody)
expect(@view.cancelEdit).not.toHaveBeenCalled()
expect(@view.$(".edit-comment-form-errors *").length).toEqual(1)

View File

@@ -108,6 +108,7 @@ describe "ThreadResponseShowView", ->
expect(@view.$(".posted-details").text()).not.toMatch("\sby\s")
it "re-renders correctly when endorsement changes", ->
spyOn($, "ajax").and.returnValue($.Deferred())
DiscussionUtil.loadRoles({"Moderator": [parseInt(window.user.id)]})
@thread.set("thread_type", "question")
@view.render()
@@ -118,6 +119,7 @@ describe "ThreadResponseShowView", ->
expect(@view.$(".posted-details").text()).not.toMatch("marked as answer")
it "allows a moderator to mark an answer in a question thread", ->
spyOn($, "ajax").and.returnValue($.Deferred())
DiscussionUtil.loadRoles({"Moderator": [parseInt(window.user.id)]})
@thread.set({
"thread_type": "question",
@@ -131,6 +133,7 @@ describe "ThreadResponseShowView", ->
expect(endorseButton).toHaveClass("is-checked")
it "allows the author of a question thread to mark an answer", ->
spyOn($, "ajax").and.returnValue($.Deferred())
@thread.set({
"thread_type": "question",
"user_id": window.user.id
@@ -199,7 +202,7 @@ describe "ThreadResponseShowView", ->
"username": "test_endorser",
"time": new Date().toISOString()
})
spyOn(DiscussionUtil, 'urlFor').andReturn('test_endorser_url')
spyOn(DiscussionUtil, 'urlFor').and.returnValue('test_endorser_url')
checkUserLink = (element, is_ta, is_staff) ->
expect(element.find('a.username').length).toEqual(1)
@@ -217,11 +220,11 @@ describe "ThreadResponseShowView", ->
checkUserLink($el, false, false)
it "renders correctly for a community TA-endorsed response", ->
spyOn(DiscussionUtil, 'isTA').andReturn(true)
spyOn(DiscussionUtil, 'isTA').and.returnValue(true)
$el = $('#fixture-element').html(@view.getEndorserDisplay())
checkUserLink($el, true, false)
it "renders correctly for a staff-endorsed response", ->
spyOn(DiscussionUtil, 'isStaff').andReturn(true)
spyOn(DiscussionUtil, 'isStaff').and.returnValue(true)
$el = $('#fixture-element').html(@view.getEndorserDisplay())
checkUserLink($el, false, true)

View File

@@ -28,14 +28,14 @@ describe "XBlock", ->
window.TestRuntime = {}
@runtimeA = {name: 'runtimeA'}
@runtimeZ = {name: 'runtimeZ'}
TestRuntime.vA = jasmine.createSpy().andReturn(@runtimeA)
TestRuntime.vZ = jasmine.createSpy().andReturn(@runtimeZ)
TestRuntime.vA = jasmine.createSpy().and.returnValue(@runtimeA)
TestRuntime.vZ = jasmine.createSpy().and.returnValue(@runtimeZ)
window.initFnA = jasmine.createSpy()
window.initFnZ = jasmine.createSpy()
@fakeChildren = ['list', 'of', 'children']
spyOn(XBlock, 'initializeXBlocks').andReturn(@fakeChildren)
spyOn(XBlock, 'initializeXBlocks').and.returnValue(@fakeChildren)
@vANode = $('#vA')[0]
@vZNode = $('#vZ')[0]
@@ -54,11 +54,11 @@ describe "XBlock", ->
expect(window.initFnZ).toHaveBeenCalledWith(@runtimeZ, @vZNode, {})
it "loads when missing versions", ->
expect(@missingVersionBlock.element).toBe($('#missing-version'))
expect(@missingVersionBlock.element).toBe($('#missing-version')[0])
expect(@missingVersionBlock.name).toBe('no-version')
it "loads when missing init fn", ->
expect(@missingInitBlock.element).toBe($('#missing-init'))
expect(@missingInitBlock.element).toBe($('#missing-init')[0])
expect(@missingInitBlock.name).toBe('no-init')
it "adds names to blocks", ->

View File

@@ -1,10 +1,17 @@
// Generated by CoffeeScript 1.6.1
(function() {
define(["jquery", "common/js/components/views/feedback", "common/js/components/views/feedback_notification", "common/js/components/views/feedback_alert", "common/js/components/views/feedback_prompt", 'common/js/spec_helpers/view_helpers', "sinon", "jquery.simulate"],
'use strict';
define(["jquery", "common/js/components/views/feedback", "common/js/components/views/feedback_notification",
"common/js/components/views/feedback_alert", "common/js/components/views/feedback_prompt",
'common/js/spec_helpers/view_helpers', "sinon", "jquery.simulate", "jasmine-waituntil"],
function($, SystemFeedback, NotificationView, AlertView, PromptView, ViewHelpers, sinon) {
var tpl;
tpl = readFixtures('system-feedback.underscore');
tpl = readFixtures('common/templates/components/system-feedback.underscore');
var isFocused = function(actual) {
return $(actual)[0] === $(actual)[0].ownerDocument.activeElement;
};
beforeEach(function() {
setFixtures(sandbox({
id: "page-alert"
@@ -19,30 +26,24 @@
id: "system-feedback-tpl",
type: "text/template"
}).text(tpl));
return this.addMatchers({
return jasmine.addMatchers({
toBeShown: function() {
return this.actual.hasClass("is-shown") && !this.actual.hasClass("is-hiding");
return {
compare: function (actual) {
return {
pass: actual.hasClass("is-shown") && !actual.hasClass("is-hiding")
};
}
};
},
toBeHiding: function() {
return this.actual.hasClass("is-hiding") && !this.actual.hasClass("is-shown");
},
toContainText: function(text) {
var trimmedText;
trimmedText = $.trim(this.actual.text());
if (text && $.isFunction(text.test)) {
return text.test(trimmedText);
} else {
return trimmedText.indexOf(text) !== -1;
}
},
toHaveBeenPrevented: function() {
var eventName, selector;
eventName = this.actual.eventName;
selector = this.actual.selector;
this.message = function() {
return ["Expected event " + eventName + " to have been prevented on " + selector, "Expected event " + eventName + " not to have been prevented on " + selector];
return {
compare: function (actual) {
return {
pass: actual.hasClass("is-hiding") && !actual.hasClass("is-shown")
};
}
};
return jasmine.JQuery.events.wasPrevented(selector, eventName);
}
});
});
@@ -52,9 +53,9 @@
title: "Portal",
message: "Welcome to the Aperture Science Computer-Aided Enrichment Center"
};
this.renderSpy = spyOn(AlertView.Confirmation.prototype, 'render').andCallThrough();
this.showSpy = spyOn(AlertView.Confirmation.prototype, 'show').andCallThrough();
this.hideSpy = spyOn(AlertView.Confirmation.prototype, 'hide').andCallThrough();
this.renderSpy = spyOn(AlertView.Confirmation.prototype, 'render').and.callThrough();
this.showSpy = spyOn(AlertView.Confirmation.prototype, 'show').and.callThrough();
this.hideSpy = spyOn(AlertView.Confirmation.prototype, 'hide').and.callThrough();
return this.clock = sinon.useFakeTimers();
});
afterEach(function() {
@@ -122,30 +123,35 @@
actions: {
primary: {
text: "Yes, I'm sure.",
"class": "confirm-button",
"class": "confirm-button"
},
secondary: {
text: "Cancel",
"class": "cancel-button",
"class": "cancel-button"
}
}
}
this.inFocusSpy = spyOn(PromptView.Confirmation.prototype, 'inFocus').andCallThrough();
return this.outFocusSpy = spyOn(PromptView.Confirmation.prototype, 'outFocus').andCallThrough();
};
this.inFocusSpy = spyOn(PromptView.Confirmation.prototype, 'inFocus').and.callThrough();
this.outFocusSpy = spyOn(PromptView.Confirmation.prototype, 'outFocus').and.callThrough();
});
it("is focused on show", function() {
it("is focused on show", function(done) {
var view;
view = new PromptView.Confirmation(this.options).show();
expect(this.inFocusSpy).toHaveBeenCalled();
return ViewHelpers.verifyElementInFocus(view, ".wrapper-prompt")
jasmine.waitUntil(function () {
return isFocused(view.$(".wrapper-prompt"));
}).always(done);
});
it("is not focused on hide", function() {
it("is not focused on hide", function(done) {
var view;
view = new PromptView.Confirmation(this.options).hide();
expect(this.outFocusSpy).toHaveBeenCalled();
return ViewHelpers.verifyElementNotInFocus(view, ".wrapper-prompt")
jasmine.waitUntil(function () {
return !isFocused(view.$(".wrapper-prompt"));
}).always(done);
});
it("traps keyboard focus when moving forward", function() {
it("traps keyboard focus when moving forward", function(done) {
var view;
view = new PromptView.Confirmation(this.options).show();
expect(this.inFocusSpy).toHaveBeenCalled();
@@ -153,9 +159,12 @@
"keydown",
{ keyCode: $.simulate.keyCode.TAB }
);
return ViewHelpers.verifyElementInFocus(view, ".action-primary")
jasmine.waitUntil(function () {
return isFocused(view.$(".action-primary"));
}).always(done);
});
it("traps keyboard focus when moving backward", function() {
it("traps keyboard focus when moving backward", function(done) {
var view;
view = new PromptView.Confirmation(this.options).show();
expect(this.inFocusSpy).toHaveBeenCalled();
@@ -163,7 +172,9 @@
"keydown",
{ keyCode: $.simulate.keyCode.TAB, shiftKey: true }
);
return ViewHelpers.verifyElementInFocus(view, ".action-secondary")
jasmine.waitUntil(function () {
return isFocused(view.$(".action-secondary"));
}).always(done);
});
return it("changes class on body", function() {
var view;
@@ -175,14 +186,15 @@
});
});
describe("NotificationView.Mini", function() {
var view;
beforeEach(function() {
return this.view = new NotificationView.Mini();
view = new NotificationView.Mini();
});
it("should have minShown set to 1250 by default", function() {
return expect(this.view.options.minShown).toEqual(1250);
return expect(view.options.minShown).toEqual(1250);
});
return it("should have closeIcon set to false by default", function() {
return expect(this.view.options.closeIcon).toBeFalsy();
return expect(view.options.closeIcon).toBeFalsy();
});
});
xdescribe("SystemFeedback click events", function() {
@@ -301,9 +313,9 @@
return describe("NotificationView minShown and maxShown", function() {
beforeEach(function() {
this.showSpy = spyOn(NotificationView.Confirmation.prototype, 'show');
this.showSpy.andCallThrough();
this.showSpy.and.callThrough();
this.hideSpy = spyOn(NotificationView.Confirmation.prototype, 'hide');
this.hideSpy.andCallThrough();
this.hideSpy.and.callThrough();
return this.clock = sinon.useFakeTimers();
});
afterEach(function() {

View File

@@ -36,7 +36,9 @@
'edxicons': 'edx-pattern-library/js/edx-icons',
'draggabilly': 'js/vendor/draggabilly',
'jasmine-stealth': 'js/libs/jasmine-stealth',
'jasmine-waituntil': 'js/libs/jasmine-waituntil'
'jasmine-waituntil': 'js/libs/jasmine-waituntil',
'jasmine-extensions': 'js/libs/jasmine-extensions',
'URI': 'js/vendor/URI.min'
},
shim: {
'gettext': {
@@ -145,6 +147,9 @@
'jasmine-waituntil': {
deps: ['jquery']
},
'jasmine-extensions': {
deps: ['jquery']
},
"sinon": {
exports: "sinon"
},

View File

@@ -28,10 +28,12 @@ define(['sinon', 'underscore', 'URI'], function(sinon, _, URI) {
* Get a reference to the mocked server, and respond
* to all requests with the specified statusCode.
*/
fakeServer = function (that, response) {
fakeServer = function (response) {
var server = sinon.fakeServer.create();
that.after(function() {
server.restore();
afterEach(function() {
if (server) {
server.restore();
}
});
server.respondWith(response);
return server;
@@ -42,16 +44,19 @@ define(['sinon', 'underscore', 'URI'], function(sinon, _, URI) {
* return a reference to the Array. This allows tests
* to respond for individual requests.
*/
fakeRequests = function (that) {
fakeRequests = function () {
var requests = [],
xhr = sinon.useFakeXMLHttpRequest();
xhr = sinon.useFakeXMLHttpRequest();
requests.currentIndex = 0;
xhr.onCreate = function(request) {
requests.push(request);
};
that.after(function() {
xhr.restore();
afterEach(function() {
if (xhr && xhr.hasOwnProperty('restore')) {
xhr.restore();
}
});
return requests;
};
@@ -88,11 +93,12 @@ define(['sinon', 'underscore', 'URI'], function(sinon, _, URI) {
};
expectJsonRequest = function(requests, method, url, jsonRequest) {
jsonRequest = jsonRequest || null;
var request = currentRequest(requests);
expect(request.readyState).toEqual(XML_HTTP_READY_STATES.OPENED);
expect(request.url).toEqual(url);
expect(request.method).toEqual(method);
expect(JSON.parse(request.requestBody)).toEqual(jsonRequest);
expect(JSON.parse(request.requestBody)).toEqual(jsonRequest === undefined ? null : jsonRequest);
};
/**

View File

@@ -32,12 +32,12 @@ define(["backbone"],
};
// Stub out the Backbone router so that the browser doesn't actually navigate
spyOn(Backbone.history, '_updateHash').andCallFake(function (location, fragment, replace) {
spyOn(Backbone.history, '_updateHash').and.callFake(function (location, fragment) {
history.currentFragment = fragment;
});
// Stub out getHash so that Backbone thinks that the browser has navigated
spyOn(Backbone.history, 'getHash').andCallFake(function () {
spyOn(Backbone.history, 'getHash').and.callFake(function () {
return history.currentFragment;
});
};

View File

@@ -10,16 +10,18 @@ define(["jquery", "common/js/components/views/feedback_notification", "common/js
verifyFeedbackHidden, createNotificationSpy, verifyNotificationShowing,
verifyNotificationHidden, createPromptSpy, confirmPrompt, inlineEdit, verifyInlineEditChange,
installMockAnalytics, removeMockAnalytics, verifyPromptShowing, verifyPromptHidden,
clickDeleteItem, patchAndVerifyRequest, submitAndVerifyFormSuccess, submitAndVerifyFormError,
verifyElementInFocus, verifyElementNotInFocus;
clickDeleteItem, patchAndVerifyRequest, submitAndVerifyFormSuccess, submitAndVerifyFormError;
installViewTemplates = function() {
appendSetFixtures('<div id="page-notification"></div>');
};
createFeedbackSpy = function(type, intent) {
var feedbackSpy = spyOnConstructor(type, intent, ['show', 'hide']);
feedbackSpy.show.andReturn(feedbackSpy);
var feedbackSpy = jasmine.stealth.spyOnConstructor(type, intent, ['show', 'hide']);
feedbackSpy.show.and.returnValue(feedbackSpy);
if (afterEach) {
afterEach(jasmine.stealth.clearSpies);
}
return feedbackSpy;
};
@@ -28,7 +30,7 @@ define(["jquery", "common/js/components/views/feedback_notification", "common/js
expect(feedbackSpy.constructor).toHaveBeenCalled();
expect(feedbackSpy.show).toHaveBeenCalled();
expect(feedbackSpy.hide).not.toHaveBeenCalled();
options = feedbackSpy.constructor.mostRecentCall.args[0];
options = feedbackSpy.constructor.calls.mostRecent().args[0];
expect(options.title).toMatch(text);
};
@@ -55,9 +57,9 @@ define(["jquery", "common/js/components/views/feedback_notification", "common/js
confirmPrompt = function(promptSpy, pressSecondaryButton) {
expect(promptSpy.constructor).toHaveBeenCalled();
if (pressSecondaryButton) {
promptSpy.constructor.mostRecentCall.args[0].actions.secondary.click(promptSpy);
promptSpy.constructor.calls.mostRecent().args[0].actions.secondary.click(promptSpy);
} else {
promptSpy.constructor.mostRecentCall.args[0].actions.primary.click(promptSpy);
promptSpy.constructor.calls.mostRecent().args[0].actions.primary.click(promptSpy);
}
};
@@ -128,22 +130,6 @@ define(["jquery", "common/js/components/views/feedback_notification", "common/js
verifyNotificationShowing(notificationSpy, /Saving/);
};
verifyElementInFocus = function(view, selector) {
waitsFor(
function() { return view.$(selector + ':focus').length === 1; },
"element to have focus: " + selector,
500
);
};
verifyElementNotInFocus = function(view, selector) {
waitsFor(
function() { return view.$(selector + ':focus').length === 0; },
"element to not have focus: " + selector,
500
);
};
return {
'installViewTemplates': installViewTemplates,
'createNotificationSpy': createNotificationSpy,
@@ -160,9 +146,7 @@ define(["jquery", "common/js/components/views/feedback_notification", "common/js
'clickDeleteItem': clickDeleteItem,
'patchAndVerifyRequest': patchAndVerifyRequest,
'submitAndVerifyFormSuccess': submitAndVerifyFormSuccess,
'submitAndVerifyFormError': submitAndVerifyFormError,
'verifyElementInFocus': verifyElementInFocus,
'verifyElementNotInFocus': verifyElementNotInFocus
'submitAndVerifyFormError': submitAndVerifyFormError
};
});
}).call(this, define || RequireJS.define);

View File

@@ -1,15 +1,6 @@
function callPeriodicallyUntil(block, delay, condition, i) { // i is optional
i = i || 0;
block(i);
waits(delay);
runs(function () {
if (!condition()) {
callPeriodicallyUntil(block, delay, condition, i + 1);
}
});
}
describe("Formula Equation Preview", function () {
'use strict';
var formulaEquationPreview = window.formulaEquationPreview;
beforeEach(function () {
// Simulate an environment conducive to a FormulaEquationInput
var $fixture = this.$fixture = $('\
@@ -37,7 +28,7 @@ describe("Formula Equation Preview", function () {
// Call old function.
return old$find.apply(this, arguments);
}
};
$.find.matchesSelector = old$find.matchesSelector;
this.oldDGEBI = document.getElementById;
@@ -50,8 +41,8 @@ describe("Formula Equation Preview", function () {
this.oldProblem = window.Problem;
window.Problem = {};
Problem.inputAjax = jasmine.createSpy('Problem.inputAjax')
.andCallFake(function () {
window.Problem.inputAjax = jasmine.createSpy('Problem.inputAjax')
.and.callFake(function () {
ajaxTimes.push(Date.now());
});
@@ -60,19 +51,19 @@ describe("Formula Equation Preview", function () {
this.oldMathJax = window.MathJax;
window.MathJax = {Hub: {}};
MathJax.Hub.getAllJax = jasmine.createSpy('MathJax.Hub.getAllJax')
.andReturn([this.jax]);
MathJax.Hub.Queue = function (callback) {
window.MathJax.Hub.getAllJax = jasmine.createSpy('MathJax.Hub.getAllJax')
.and.returnValue([this.jax]);
window.MathJax.Hub.Queue = function (callback) {
if (typeof (callback) == 'function') {
callback();
}
}
spyOn(MathJax.Hub, 'Queue').andCallThrough()
MathJax.Hub.Startup = jasmine.createSpy('MathJax.Hub.Startup');
MathJax.Hub.Startup.signal = jasmine.createSpy('MathJax.Hub.Startup.signal');
MathJax.Hub.Startup.signal.Interest = function (callback) {
};
spyOn(window.MathJax.Hub, 'Queue').and.callThrough();
window.MathJax.Hub.Startup = jasmine.createSpy('MathJax.Hub.Startup');
window.MathJax.Hub.Startup.signal = jasmine.createSpy('MathJax.Hub.Startup.signal');
window.MathJax.Hub.Startup.signal.Interest = function (callback) {
callback('End');
}
};
});
it('(the test) is able to swap out the behavior of $', function () {
@@ -90,22 +81,22 @@ describe("Formula Equation Preview", function () {
});
describe('Ajax requests', function () {
beforeEach(function () {
beforeEach(function (done) {
// This is common to all tests on ajax requests.
formulaEquationPreview.enable();
// This part may be asynchronous, so wait.
waitsFor(function () {
return Problem.inputAjax.wasCalled;
}, "AJAX never called initially", 1000);
jasmine.waitUntil(function () {
return window.Problem.inputAjax.calls.count() > 0;
}).then(done);
});
it('has an initial request with the correct parameters', function () {
expect(Problem.inputAjax.callCount).toEqual(1);
expect(window.Problem.inputAjax.calls.count()).toEqual(1);
// Use `.toEqual` rather than `.toHaveBeenCalledWith`
// since it supports `jasmine.any`.
expect(Problem.inputAjax.mostRecentCall.args).toEqual([
expect(window.Problem.inputAjax.calls.mostRecent().args).toEqual([
"THE_URL",
"THE_ID",
"preview_formcalc",
@@ -115,65 +106,59 @@ describe("Formula Equation Preview", function () {
]);
});
it('does not request again if the initial request has already been made', function () {
it('does not request again if the initial request has already been made', function (done) {
// jshint undef:false
expect(Problem.inputAjax.callCount).toEqual(1);
expect(window.Problem.inputAjax.calls.count()).toEqual(1);
// Reset the spy in order to check calls again.
Problem.inputAjax.reset();
window.Problem.inputAjax.calls.reset();
// Enabling the formulaEquationPreview again to see if this will
// reinitialize input request once again.
formulaEquationPreview.enable();
// This part may be asynchronous, so wait.
waitsFor(function () {
return !Problem.inputAjax.wasCalled;
}, "times out in case of AJAX call", 1000);
// Expect Problem.inputAjax was not called as input request was
// initialized before.
expect(Problem.inputAjax).not.toHaveBeenCalled();
jasmine.waitUntil(function () {
return window.Problem.inputAjax.calls.count() === 0;
}).then(function () {
// Expect window.Problem.inputAjax was not called as input request was
// initialized before.
expect(window.Problem.inputAjax).not.toHaveBeenCalled();
}).always(done);
});
it('makes a request on user input', function () {
Problem.inputAjax.reset();
it('makes a request on user input', function (done) {
window.Problem.inputAjax.calls.reset();
$('#input_THE_ID').val('user_input').trigger('input');
// This part is probably asynchronous
waitsFor(function () {
return Problem.inputAjax.wasCalled;
}, "AJAX never called on user input", 1000);
runs(function () {
expect(Problem.inputAjax.mostRecentCall.args[3].formula
).toEqual('user_input');
});
jasmine.waitUntil(function () {
return window.Problem.inputAjax.calls.count() > 0;
}).then(function () {
expect(window.Problem.inputAjax.calls.mostRecent().args[3].formula).toEqual('user_input');
}).always(done);
});
it("isn't requested for empty input", function () {
Problem.inputAjax.reset();
it("isn't requested for empty input", function (done) {
window.Problem.inputAjax.calls.reset();
// When we make an input of '',
$('#input_THE_ID').val('').trigger('input');
// Either it makes a request or jumps straight into displaying ''.
waitsFor(function () {
jasmine.waitUntil(function () {
// (Short circuit if `inputAjax` is indeed called)
return Problem.inputAjax.wasCalled || // jshint ignore:line
MathJax.Hub.Queue.wasCalled;
}, "AJAX never called on user input", 1000);
runs(function () {
return window.Problem.inputAjax.calls.count() > 0 ||
window.MathJax.Hub.Queue.calls.count() > 0;
}).then(function () {
// Expect the request not to have been called.
expect(Problem.inputAjax).not.toHaveBeenCalled();
});
expect(window.Problem.inputAjax).not.toHaveBeenCalled();
}).always(done);
});
it('limits the number of requests per second', function () {
it('limits the number of requests per second', function (done) {
var minDelay = formulaEquationPreview.minDelay;
var end = Date.now() + minDelay * 1.1;
var step = 10; // ms
var $input = $('#input_THE_ID');
var value;
@@ -182,41 +167,42 @@ describe("Formula Equation Preview", function () {
$input.val(value).trigger('input');
}
callPeriodicallyUntil(inputAnother, step, function () {
var self = this;
var iter = 0;
jasmine.waitUntil(function () {
inputAnother(iter++);
return Date.now() > end; // Stop when we get to `end`.
});
}).then(function () {
jasmine.waitUntil(function () {
return window.Problem.inputAjax.calls.count() > 0 &&
window.Problem.inputAjax.calls.mostRecent().args[3].formula === value;
}).then(_.bind(function () {
// There should be 2 or 3 calls (depending on leading edge).
expect(window.Problem.inputAjax.calls.count()).not.toBeGreaterThan(3);
waitsFor(function () {
return Problem.inputAjax.wasCalled &&
Problem.inputAjax.mostRecentCall.args[3].formula == value;
}, "AJAX never called with final value from input", 1000);
runs(function () {
// There should be 2 or 3 calls (depending on leading edge).
expect(Problem.inputAjax.callCount).not.toBeGreaterThan(3);
// The calls should happen approximately `minDelay` apart.
for (var i =1; i < this.ajaxTimes.length; i ++) {
var diff = this.ajaxTimes[i] - this.ajaxTimes[i - 1];
expect(diff).toBeGreaterThan(minDelay - 10);
}
// The calls should happen approximately `minDelay` apart.
for (var i =1; i < this.ajaxTimes.length; i ++) {
var diff = this.ajaxTimes[i] - this.ajaxTimes[i - 1];
expect(diff).toBeGreaterThan(minDelay - 10);
}
}, self)).then(function () {
done();
});
});
});
});
describe("Visible results (icon and mathjax)", function () {
it('displays a loading icon when requests are open', function () {
it('displays a loading icon when requests are open', function (done) {
var $img = $("img.loading");
expect($img.css('visibility')).toEqual('hidden');
formulaEquationPreview.enable();
expect($img.css('visibility')).toEqual('visible');
// This part could be asynchronous
waitsFor(function () {
return Problem.inputAjax.wasCalled;
}, "AJAX never called initially", 1000);
runs(function () {
jasmine.waitUntil(function () {
return window.Problem.inputAjax.calls.count() > 0;
}).then(function () {
expect($img.css('visibility')).toEqual('visible');
// Reset and send another request.
@@ -224,23 +210,23 @@ describe("Formula Equation Preview", function () {
$("#input_THE_ID").val("different").trigger('input');
expect($img.css('visibility')).toEqual('visible');
});
// Don't let it fail later.
waitsFor(function () {
var args = Problem.inputAjax.mostRecentCall.args;
return args[3].formula == "different";
}).then(function () {
return jasmine.waitUntil(function () {
var args = window.Problem.inputAjax.calls.mostRecent().args;
return args[3].formula === "different";
}).then(done);
});
});
it('updates MathJax and loading icon on callback', function () {
it('updates MathJax and loading icon on callback', function (done) {
formulaEquationPreview.enable();
waitsFor(function () {
return Problem.inputAjax.wasCalled;
}, "AJAX never called initially", 1000);
runs(function () {
var args = Problem.inputAjax.mostRecentCall.args;
var jax = this.jax;
jasmine.waitUntil(function () {
return window.Problem.inputAjax.calls.count() > 0;
}).then(function () {
var args = window.Problem.inputAjax.calls.mostRecent().args;
var callback = args[4];
callback({
preview: 'THE_FORMULA',
@@ -252,29 +238,27 @@ describe("Formula Equation Preview", function () {
// We should look in the preview div for the MathJax.
var previewDiv = $("#input_THE_ID_preview")[0];
expect(MathJax.Hub.getAllJax).toHaveBeenCalledWith(previewDiv);
expect(window.MathJax.Hub.getAllJax).toHaveBeenCalledWith(previewDiv);
// Refresh the MathJax.
expect(MathJax.Hub.Queue).toHaveBeenCalledWith(
['Text', this.jax, 'THE_FORMULA']
expect(window.MathJax.Hub.Queue).toHaveBeenCalledWith(
['Text', jax, 'THE_FORMULA']
);
});
}).always(done);
});
it('finds alternatives if MathJax hasn\'t finished loading', function () {
it('finds alternatives if MathJax hasn\'t finished loading', function (done) {
formulaEquationPreview.enable();
$('#input_THE_ID').val('user_input').trigger('input');
waitsFor(function () {
return Problem.inputAjax.wasCalled;
}, "AJAX never called initially", 1000);
runs(function () {
var args = Problem.inputAjax.mostRecentCall.args;
jasmine.waitUntil(function () {
return window.Problem.inputAjax.calls.count() > 0;
}).then(function () {
var args = window.Problem.inputAjax.calls.mostRecent().args;
var callback = args[4];
// Cannot find MathJax.
MathJax.Hub.getAllJax.andReturn([]);
window.MathJax.Hub.getAllJax.and.returnValue([]);
spyOn(console, 'log');
callback({
@@ -290,74 +274,68 @@ describe("Formula Equation Preview", function () {
expect(previewElement.firstChild.data).toEqual("\\(THE_FORMULA\\)");
// Refresh the MathJax.
expect(MathJax.Hub.Queue).toHaveBeenCalledWith(
expect(window.MathJax.Hub.Queue).toHaveBeenCalledWith(
['Typeset', jasmine.any(Object), jasmine.any(Element)]
);
});
}).always(done);
});
it('displays errors from the server well', function () {
it('displays errors from the server well', function (done) {
var $img = $("img.loading");
formulaEquationPreview.enable();
waitsFor(function () {
return Problem.inputAjax.wasCalled;
}, "AJAX never called initially", 1000);
var jax = this.jax;
runs(function () {
var args = Problem.inputAjax.mostRecentCall.args;
formulaEquationPreview.enable();
jasmine.waitUntil(function () {
return window.Problem.inputAjax.calls.count() > 0;
}).then(function () {
var args = window.Problem.inputAjax.calls.mostRecent().args;
var callback = args[4];
callback({
error: 'OOPSIE',
request_start: args[3].request_start
});
expect(MathJax.Hub.Queue).not.toHaveBeenCalled();
expect(window.MathJax.Hub.Queue).not.toHaveBeenCalled();
expect($img.css('visibility')).toEqual('visible');
});
var errorDelay = formulaEquationPreview.errorDelay * 1.1;
waitsFor(function () {
return MathJax.Hub.Queue.wasCalled;
}, "Error message never displayed", 2000);
runs(function () {
// Refresh the MathJax.
expect(MathJax.Hub.Queue).toHaveBeenCalledWith(
['Text', this.jax, '\\text{OOPSIE}']
);
expect($img.css('visibility')).toEqual('hidden');
}).then(function () {
jasmine.waitUntil(function () {
return window.MathJax.Hub.Queue.calls.count() > 0;
}).then(function () {
// Refresh the MathJax.
expect(window.MathJax.Hub.Queue).toHaveBeenCalledWith(
['Text', jax, '\\text{OOPSIE}']
);
expect($img.css('visibility')).toEqual('hidden');
}).then(done);
});
});
});
describe('Multiple callbacks', function () {
beforeEach(function () {
beforeEach(function (done) {
formulaEquationPreview.enable();
waitsFor(function () {
return Problem.inputAjax.wasCalled;
});
runs(function () {
var self = this;
jasmine.waitUntil(function () {
return window.Problem.inputAjax.calls.count() > 0;
}).then(function () {
$('#input_THE_ID').val('different').trigger('input');
});
jasmine.waitUntil(function () {
return window.Problem.inputAjax.calls.count() > 1;
}).then(_.bind(function () {
var args0 = window.Problem.inputAjax.calls.argsFor(0);
var args1 = window.Problem.inputAjax.calls.argsFor(1);
var response0 = {
preview: 'THE_FORMULA_0',
request_start: args0[3].request_start
};
var response1 = {
preview: 'THE_FORMULA_1',
request_start: args1[3].request_start
};
waitsFor(function () {
return Problem.inputAjax.callCount > 1;
});
runs(function () {
var args = Problem.inputAjax.argsForCall;
var response0 = {
preview: 'THE_FORMULA_0',
request_start: args[0][3].request_start
};
var response1 = {
preview: 'THE_FORMULA_1',
request_start: args[1][3].request_start
};
this.callbacks = [args[0][4], args[1][4]];
this.responses = [response0, response1];
this.callbacks = [args0[4], args0[4]];
this.responses = [response0, response1];
}, self)).then(done);
});
});
@@ -367,13 +345,13 @@ describe("Formula Equation Preview", function () {
expect($img.css('visibility')).toEqual('visible');
this.callbacks[0](this.responses[0]);
expect(MathJax.Hub.Queue).toHaveBeenCalledWith(
expect(window.MathJax.Hub.Queue).toHaveBeenCalledWith(
['Text', this.jax, 'THE_FORMULA_0']
);
expect($img.css('visibility')).toEqual('visible');
this.callbacks[1](this.responses[1]);
expect(MathJax.Hub.Queue).toHaveBeenCalledWith(
expect(window.MathJax.Hub.Queue).toHaveBeenCalledWith(
['Text', this.jax, 'THE_FORMULA_1']
);
expect($img.css('visibility')).toEqual('hidden');
@@ -386,40 +364,38 @@ describe("Formula Equation Preview", function () {
// Switch the order (1 returns before 0)
this.callbacks[1](this.responses[1]);
expect(MathJax.Hub.Queue).toHaveBeenCalledWith(
expect(window.MathJax.Hub.Queue).toHaveBeenCalledWith(
['Text', this.jax, 'THE_FORMULA_1']
);
expect($img.css('visibility')).toEqual('hidden');
MathJax.Hub.Queue.reset();
window.MathJax.Hub.Queue.calls.reset();
this.callbacks[0](this.responses[0]);
expect(MathJax.Hub.Queue).not.toHaveBeenCalled();
expect(window.MathJax.Hub.Queue).not.toHaveBeenCalled();
expect($img.css('visibility')).toEqual('hidden');
});
it("doesn't show an error if the responses are close together",
function () {
this.callbacks[0]({
error: 'OOPSIE',
request_start: this.responses[0].request_start
});
expect(MathJax.Hub.Queue).not.toHaveBeenCalled();
// Error message waiting to be displayed
it("doesn't show an error if the responses are close together", function (done) {
this.callbacks[0]({
error: 'OOPSIE',
request_start: this.responses[0].request_start
});
expect(window.MathJax.Hub.Queue).not.toHaveBeenCalled();
this.callbacks[1](this.responses[1]);
expect(MathJax.Hub.Queue).toHaveBeenCalledWith(
['Text', this.jax, 'THE_FORMULA_1']
);
// Error message waiting to be displayed
this.callbacks[1](this.responses[1]);
expect(window.MathJax.Hub.Queue).toHaveBeenCalledWith(
['Text', this.jax, 'THE_FORMULA_1']
);
// Make sure that it doesn't indeed show up later
MathJax.Hub.Queue.reset();
var errorDelay = formulaEquationPreview.errorDelay * 1.1;
waits(errorDelay);
runs(function () {
expect(MathJax.Hub.Queue).not.toHaveBeenCalled();
})
});
// Make sure that it doesn't indeed show up later
window.MathJax.Hub.Queue.calls.reset();
jasmine.waitUntil(function () {
return formulaEquationPreview.errorDelay * 1.1;
}).then(function () {
expect(window.MathJax.Hub.Queue).not.toHaveBeenCalled();
}).then(done);
});
});
afterEach(function () {
@@ -428,15 +404,15 @@ describe("Formula Equation Preview", function () {
document.getElementById = this.oldDGEBI;
// Return Problem
Problem = this.oldProblem;
if (Problem === undefined) {
delete Problem;
window.Problem = this.oldProblem;
if (window.Problem === undefined) {
delete window.Problem;
}
// Return MathJax
MathJax = this.oldMathJax;
if (MathJax === undefined) {
delete MathJax;
window.MathJax = this.oldMathJax;
if (window.MathJax === undefined) {
delete window.MathJax;
}
});
});

View File

@@ -0,0 +1,248 @@
// Extensions to Jasmine.
//
// This file adds the following:
// 1. Custom matchers that may be helpful project-wise.
// 2. Copies of some matchers from Jasmine-jQuery.
// Because Jasmine-Jquery uses its own version of JQuery, events registered in the code
// using the platform version of JQuery are not "noticed" by Jasmine-jQuery matchers.
// Similarly equality matching does not work either. So after the platform version of
// jQuery has been loaded, we set these matchers up again in this module.
(function(root, factory) {
/* jshint strict: false */
factory(root, root.jQuery);
}((function() {
/* jshint strict: false */
return this;
}()), function(window, $) {
'use strict';
// Add custom Jasmine matchers.
beforeEach(function() {
jasmine.addMatchers(window.imagediff.jasmine);
jasmine.addMatchers({
toHaveAttrs: function() {
return {
compare: function(actual, attrs) {
var result = {},
element = actual;
if ($.isEmptyObject(attrs)) {
return {
pass: false
};
}
result.pass = _.every(attrs, function(value, name) {
return element.attr(name) === value;
});
return result;
}
};
},
toBeInRange: function() {
return {
compare: function(actual, min, max) {
return {
pass: min <= actual && actual <= max
};
}
};
},
toBeInArray: function() {
return {
compare: function(actual, array) {
return {
pass: $.inArray(actual, array) > -1
};
}
};
}
});
});
/* jshint ignore:start */
// All the code below is taken from:
// https://github.com/velesin/jasmine-jquery/blob/2.1.1/lib/jasmine-jquery.js
beforeEach(function() {
jasmine.addMatchers({
toHandle: function() {
return {
compare: function(actual, event) {
if (!actual || actual.length === 0) return {
pass: false
};
var events = $._data($(actual).get(0), "events");
if (!events || !event || typeof event !== "string") {
return {
pass: false
};
}
var namespaces = event.split("."),
eventType = namespaces.shift(),
sortedNamespaces = namespaces.slice(0).sort(),
namespaceRegExp = new RegExp("(^|\\.)" + sortedNamespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
if (events[eventType] && namespaces.length) {
for (var i = 0; i < events[eventType].length; i++) {
var namespace = events[eventType][i].namespace;
if (namespaceRegExp.test(namespace))
return {
pass: true
};
}
} else {
return {
pass: (events[eventType] && events[eventType].length > 0)
};
}
return {
pass: false
};
}
};
},
toHandleWith: function() {
return {
compare: function(actual, eventName, eventHandler) {
if (!actual || actual.length === 0) return {
pass: false
};
var normalizedEventName = eventName.split('.')[0],
stack = $._data($(actual).get(0), "events")[normalizedEventName];
for (var i = 0; i < stack.length; i++) {
if (stack[i].handler == eventHandler) return {
pass: true
};
}
return {
pass: false
};
}
};
}
});
jasmine.addCustomEqualityTester(function(a, b) {
if (a && b) {
if (a instanceof $ || jasmine.isDomNode(a)) {
var $a = $(a);
if (b instanceof $)
return $a.length == b.length && a.is(b);
return $a.is(b);
}
if (b instanceof $ || jasmine.isDomNode(b)) {
var $b = $(b);
if (a instanceof $)
return a.length == $b.length && $b.is(a);
return $(b).is(a);
}
}
});
jasmine.addCustomEqualityTester(function(a, b) {
if (a instanceof $ && b instanceof $ && a.size() == b.size())
return a.is(b);
});
});
var data = {
spiedEvents: {},
handlers: []
};
jasmine.jQuery.events = {
spyOn: function(selector, eventName) {
var handler = function(e) {
var calls = (typeof data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] !== 'undefined') ? data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)].calls : 0;
data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] = {
args: jasmine.util.argsToArray(arguments),
calls: ++calls
};
};
$(selector).on(eventName, handler);
data.handlers.push(handler);
return {
selector: selector,
eventName: eventName,
handler: handler,
reset: function() {
delete data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)];
},
calls: {
count: function() {
return data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] ?
data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)].calls : 0;
},
any: function() {
return data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] ?
!!data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)].calls : false;
}
}
};
},
args: function(selector, eventName) {
var actualArgs = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)].args;
if (!actualArgs) {
throw "There is no spy for " + eventName + " on " + selector.toString() + ". Make sure to create a spy using spyOnEvent.";
}
return actualArgs;
},
wasTriggered: function(selector, eventName) {
return !!(data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)]);
},
wasTriggeredWith: function(selector, eventName, expectedArgs, util, customEqualityTesters) {
var actualArgs = jasmine.jQuery.events.args(selector, eventName).slice(1);
if (Object.prototype.toString.call(expectedArgs) !== '[object Array]')
actualArgs = actualArgs[0];
return util.equals(actualArgs, expectedArgs, customEqualityTesters);
},
wasPrevented: function(selector, eventName) {
var spiedEvent = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)],
args = (jasmine.util.isUndefined(spiedEvent)) ? {} : spiedEvent.args,
e = args ? args[0] : undefined;
return e && e.isDefaultPrevented();
},
wasStopped: function(selector, eventName) {
var spiedEvent = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)],
args = (jasmine.util.isUndefined(spiedEvent)) ? {} : spiedEvent.args,
e = args ? args[0] : undefined;
return e && e.isPropagationStopped();
},
cleanUp: function() {
data.spiedEvents = {};
data.handlers = [];
}
};
/* jshint ignore:end */
}));

View File

@@ -0,0 +1,64 @@
// Custom library to replace the legacy non jasmine 2.0 compatible jasmine-stealth
// jshint ignore: start
(function (root, factory) {
factory(root, root.jasmine, root._);
}((function () {
return this;
}()), function (window, jasmine, _) {
var fake, clearSpies, spyOnConstructor, unfakes = [];
clearSpies = function () {
_.each(unfakes, function (u) {
return u();
});
return unfakes = [];
};
fake = function (owner, thingToFake, newThing) {
var originalThing;
originalThing = owner[thingToFake];
owner[thingToFake] = newThing;
return unfakes.push(function () {
return owner[thingToFake] = originalThing;
});
};
spyOnConstructor = function (owner, classToFake, methodsToSpy) {
var fakeClass, spies;
fakeClass = (function () {
function _Class() {
spies.constructor.apply(this, arguments);
}
return _Class;
})();
if (!methodsToSpy) {
methodsToSpy = [];
}
if (_.isString(methodsToSpy)) {
methodsToSpy = [methodsToSpy];
}
spies = {
constructor: jasmine.createSpy('' + classToFake + '\'s constructor')
};
_.each(methodsToSpy, function (methodName) {
spies[methodName] = jasmine.createSpy('' + classToFake + '#' + methodName);
return fakeClass.prototype[methodName] = function () {
return spies[methodName].apply(this, arguments);
};
});
fake(owner, classToFake, fakeClass);
return spies;
};
jasmine.stealth = {
spyOnConstructor: spyOnConstructor,
clearSpies: clearSpies
};
}));

View File

@@ -0,0 +1,48 @@
// Takes a latch function and optionally timeout and error message.
// Polls the latch function until the it returns true or the maximum timeout expires
// whichever comes first.
(function(root, factory) {
/* jshint strict: false */
factory(root, root.jQuery);
}((function() {
/* jshint strict: false */
return this;
}()), function(window, $) {
'use strict';
var MAX_TIMEOUT = jasmine.DEFAULT_TIMEOUT_INTERVAL;
var realSetTimeout = setTimeout;
var realClearTimeout = clearTimeout;
jasmine.waitUntil = function(conditionalFn, maxTimeout, message) {
var deferred = $.Deferred(),
elapsedTimeInMs = 0,
timeout;
maxTimeout = maxTimeout || MAX_TIMEOUT;
message = message || 'Timeout has expired';
var fn = function() {
elapsedTimeInMs += 50;
if (conditionalFn()) {
if (timeout) { realClearTimeout(timeout); }
deferred.resolve();
} else {
if (elapsedTimeInMs >= maxTimeout) {
// explicitly fail the spec with the given message
fail(message); // jshint ignore:line
// clear timeout and reject the promise
realClearTimeout(timeout);
deferred.reject();
return;
}
timeout = realSetTimeout(fn, 50);
}
};
realSetTimeout(fn, 50);
return deferred.promise();
};
}));

View File

@@ -1,4 +1,6 @@
describe("CSS3 workarounds", function() {
'use strict';
var pointerEventsNone = window.pointerEventsNone;
describe("pointer-events", function() {
beforeEach(function() {
var html = "<a href='#' class='is-disabled'>What wondrous life in this I lead</a>";
@@ -21,17 +23,7 @@ describe("CSS3 workarounds", function() {
});
it("should prevent default when pointerEvents is not Supported", function() {
// mock document.body.style so it does not include 'pointerEvents'
var mockBodyStyle = {},
bodyStyleKeys = Object.keys(document.body.style);
for (var index = 0; index < bodyStyleKeys.length; index++) {
var key = bodyStyleKeys[index];
if (key !== "pointerEvents") {
mockBodyStyle[key] = document.body.style[key];
};
};
pointerEventsNone(".is-disabled", mockBodyStyle);
pointerEventsNone(".is-disabled", {});
spyOnEvent(".is-disabled", "click");
$(".is-disabled").click();
expect("click").toHaveBeenPreventedOn(".is-disabled");

View File

@@ -19,34 +19,34 @@
});
it("should make an AJAX request to the correct URL", function () {
spyOn($, 'ajax').andReturn(deferred);
spyOn($, 'ajax').and.returnValue(deferred);
Language.init();
lang_selector.trigger('change');
expect($.ajax.mostRecentCall.args[0].url).toEqual("/api/user/v1/preferences/test1/");
expect($.ajax.calls.mostRecent().args[0].url).toEqual("/api/user/v1/preferences/test1/");
});
it("should make an AJAX request with correct type", function () {
spyOn($, 'ajax').andReturn(deferred);
spyOn($, 'ajax').and.returnValue(deferred);
Language.init();
lang_selector.trigger('change');
expect($.ajax.mostRecentCall.args[0].type).toEqual("PATCH");
expect($.ajax.calls.mostRecent().args[0].type).toEqual("PATCH");
});
it("should make an AJAX request with correct data", function () {
spyOn($, 'ajax').andReturn(deferred);
spyOn($, 'ajax').and.returnValue(deferred);
Language.init();
lang_selector.val('ar');
lang_selector.trigger('change');
expect($.ajax.mostRecentCall.args[0].data).toEqual('{"pref-lang":"ar"}');
expect($.ajax.calls.mostRecent().args[0].data).toEqual('{"pref-lang":"ar"}');
// change to 'en' from 'ar'
lang_selector.val('en');
lang_selector.trigger('change');
expect($.ajax.mostRecentCall.args[0].data).toEqual('{"pref-lang":"en"}');
expect($.ajax.calls.mostRecent().args[0].data).toEqual('{"pref-lang":"en"}');
});
it("should call refresh on ajax failure", function () {
spyOn($, 'ajax').andCallFake(function () {
spyOn($, 'ajax').and.callFake(function () {
var d = $.Deferred();
d.reject();
return d.promise();

View File

@@ -11,24 +11,37 @@ describe('TooltipManager', function () {
this.element = $('#test-id');
this.tooltip = new TooltipManager(document.body);
jasmine.Clock.useMock();
jasmine.clock().install();
// Set default dimensions to make testing easer.
$('.tooltip').height(HEIGHT).width(WIDTH);
// Re-write default jasmine-jquery to consider opacity.
this.addMatchers({
jasmine.addMatchers({
toBeVisible: function() {
return this.actual.is(':visible') || parseFloat(this.actual.css('opacity'));
return {
compare: function (actual) {
return {
pass: actual.is(':visible') || parseFloat(actual.css('opacity'))
};
}
};
},
toBeHidden: function() {
return this.actual.is(':hidden') || !parseFloat(this.actual.css('opacity'));
},
toBeHidden: function () {
return {
compare: function (actual) {
return {
pass: actual.is(':hidden') || !parseFloat(actual.css('opacity'))
};
}
};
}
});
});
afterEach(function () {
this.tooltip.destroy();
jasmine.clock().uninstall();
});
showTooltip = function (element) {
@@ -36,7 +49,7 @@ describe('TooltipManager', function () {
pageX: PAGE_X,
pageY: PAGE_Y
}));
jasmine.Clock.tick(500);
jasmine.clock().tick(500);
};
it('can destroy itself', function () {
@@ -58,7 +71,7 @@ describe('TooltipManager', function () {
showTooltip(this.element);
expect($('.tooltip')).toBeVisible();
this.element.trigger($.Event("mouseout"));
jasmine.Clock.tick(50);
jasmine.clock().tick(50);
expect($('.tooltip')).toBeHidden();
});
@@ -66,7 +79,7 @@ describe('TooltipManager', function () {
showTooltip(this.element);
expect($('.tooltip')).toBeVisible();
this.element.trigger($.Event("click"));
jasmine.Clock.tick(50);
jasmine.clock().tick(50);
expect($('.tooltip')).toBeHidden();
});

View File

@@ -2,7 +2,7 @@
// supported in older browsers
var pointerEventsNone = function (selector, supportedStyles) {
// Check to see if the brower supports 'pointer-events' css rule.
// Check to see if the browser supports 'pointer-events' css rule.
// If it doesn't, use javascript to stop the link from working
// when clicked.
$(selector).click(function (event) {

View File

@@ -268,52 +268,71 @@
return element;
}
function imageDiffEqualMessage (actual, expected) {
return function () {
var
div = get('div'),
a = get('div', '<div>Actual:</div>'),
b = get('div', '<div>Expected:</div>'),
c = get('div', '<div>Diff:</div>'),
diff = imagediff.diff(actual, expected),
canvas = getCanvas(),
context;
canvas.height = diff.height;
canvas.width = diff.width;
div.style.overflow = 'hidden';
a.style.float = 'left';
b.style.float = 'left';
c.style.float = 'left';
context = canvas.getContext('2d');
context.putImageData(diff, 0, 0);
a.appendChild(toCanvas(actual));
b.appendChild(toCanvas(expected));
c.appendChild(canvas);
div.appendChild(a);
div.appendChild(b);
div.appendChild(c);
return div;
};
}
jasmine = {
toBeImageData : function () {
return imagediff.isImageData(this.actual);
return {
compare: function () {
return {
pass: imagediff.isImageData(this.actual)
}
}
};
},
toImageDiffEqual : function (expected, tolerance) {
if (typeof (document) !== UNDEFINED) {
this.message = function () {
toImageDiffEqual: function () {
return {
compare: function (actual, expected, tolerance) {
var
div = get('div'),
a = get('div', '<div>Actual:</div>'),
b = get('div', '<div>Expected:</div>'),
c = get('div', '<div>Diff:</div>'),
diff = imagediff.diff(this.actual, expected),
canvas = getCanvas(),
context;
result = {};
canvas.height = diff.height;
canvas.width = diff.width;
div.style.overflow = 'hidden';
a.style.float = 'left';
b.style.float = 'left';
c.style.float = 'left';
context = canvas.getContext('2d');
context.putImageData(diff, 0, 0);
a.appendChild(toCanvas(this.actual));
b.appendChild(toCanvas(expected));
c.appendChild(canvas);
div.appendChild(a);
div.appendChild(b);
div.appendChild(c);
return [
div,
"Expected not to be equal."
];
};
}
return imagediff.equal(this.actual, expected, tolerance);
result.pass = imagediff.equal(actual, expected, tolerance);
if (typeof (document) !== UNDEFINED) {
result.message = imageDiffEqualMessage(actual, expected);
}
return result;
},
negativeCompare: function (actual, expected, tolerance) {
return {
pass: !imagediff.equal(actual, expected, tolerance),
message: 'Expected not to be equal.'
};
}
};
}
};

View File

@@ -1,244 +0,0 @@
// Generated by CoffeeScript 1.3.3
/*
jasmine-stealth 0.0.12
Makes Jasmine spies a bit more robust
site: https://github.com/searls/jasmine-stealth
*/
(function() {
var Captor, fake, root, unfakes, whatToDoWhenTheSpyGetsCalled, _,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
root = this;
_ = function(obj) {
return {
each: function(iterator) {
var item, _i, _len, _results;
_results = [];
for (_i = 0, _len = obj.length; _i < _len; _i++) {
item = obj[_i];
_results.push(iterator(item));
}
return _results;
},
isFunction: function() {
return Object.prototype.toString.call(obj) === "[object Function]";
},
isString: function() {
return Object.prototype.toString.call(obj) === "[object String]";
}
};
};
root.spyOnConstructor = function(owner, classToFake, methodsToSpy) {
var fakeClass, spies;
if (methodsToSpy == null) {
methodsToSpy = [];
}
if (_(methodsToSpy).isString()) {
methodsToSpy = [methodsToSpy];
}
spies = {
constructor: jasmine.createSpy("" + classToFake + "'s constructor")
};
fakeClass = (function() {
function _Class() {
spies.constructor.apply(this, arguments);
}
return _Class;
})();
_(methodsToSpy).each(function(methodName) {
spies[methodName] = jasmine.createSpy("" + classToFake + "#" + methodName);
return fakeClass.prototype[methodName] = function() {
return spies[methodName].apply(this, arguments);
};
});
fake(owner, classToFake, fakeClass);
return spies;
};
unfakes = [];
afterEach(function() {
_(unfakes).each(function(u) {
return u();
});
return unfakes = [];
});
fake = function(owner, thingToFake, newThing) {
var originalThing;
originalThing = owner[thingToFake];
owner[thingToFake] = newThing;
return unfakes.push(function() {
return owner[thingToFake] = originalThing;
});
};
root.stubFor = root.spyOn;
jasmine.createStub = jasmine.createSpy;
jasmine.createStubObj = function(baseName, stubbings) {
var name, obj, stubbing;
if (stubbings.constructor === Array) {
return jasmine.createSpyObj(baseName, stubbings);
} else {
obj = {};
for (name in stubbings) {
stubbing = stubbings[name];
obj[name] = jasmine.createSpy(baseName + "." + name);
if (_(stubbing).isFunction()) {
obj[name].andCallFake(stubbing);
} else {
obj[name].andReturn(stubbing);
}
}
return obj;
}
};
whatToDoWhenTheSpyGetsCalled = function(spy) {
var matchesStub, priorStubbing;
matchesStub = function(stubbing, args, context) {
switch (stubbing.type) {
case "args":
return jasmine.getEnv().equals_(stubbing.ifThis, jasmine.util.argsToArray(args));
case "context":
return jasmine.getEnv().equals_(stubbing.ifThis, context);
}
};
priorStubbing = spy.plan();
return spy.andCallFake(function() {
var i, stubbing;
i = 0;
while (i < spy._stealth_stubbings.length) {
stubbing = spy._stealth_stubbings[i];
if (matchesStub(stubbing, arguments, this)) {
if (Object.prototype.toString.call(stubbing.thenThat) === "[object Function]") {
return stubbing.thenThat();
} else {
return stubbing.thenThat;
}
}
i++;
}
return priorStubbing;
});
};
jasmine.Spy.prototype.whenContext = function(context) {
var addStubbing, spy;
spy = this;
spy._stealth_stubbings || (spy._stealth_stubbings = []);
whatToDoWhenTheSpyGetsCalled(spy);
addStubbing = function(thenThat) {
spy._stealth_stubbings.push({
type: 'context',
ifThis: context,
thenThat: thenThat
});
return spy;
};
return {
thenReturn: addStubbing,
thenCallFake: addStubbing
};
};
jasmine.Spy.prototype.when = function() {
var addStubbing, ifThis, spy;
spy = this;
ifThis = jasmine.util.argsToArray(arguments);
spy._stealth_stubbings || (spy._stealth_stubbings = []);
whatToDoWhenTheSpyGetsCalled(spy);
addStubbing = function(thenThat) {
spy._stealth_stubbings.push({
type: 'args',
ifThis: ifThis,
thenThat: thenThat
});
return spy;
};
return {
thenReturn: addStubbing,
thenCallFake: addStubbing
};
};
jasmine.Spy.prototype.mostRecentCallThat = function(callThat, context) {
var i;
i = this.calls.length - 1;
while (i >= 0) {
if (callThat.call(context || this, this.calls[i]) === true) {
return this.calls[i];
}
i--;
}
};
jasmine.Matchers.ArgThat = (function(_super) {
__extends(ArgThat, _super);
function ArgThat(matcher) {
this.matcher = matcher;
}
ArgThat.prototype.jasmineMatches = function(actual) {
return this.matcher(actual);
};
return ArgThat;
})(jasmine.Matchers.Any);
jasmine.Matchers.ArgThat.prototype.matches = jasmine.Matchers.ArgThat.prototype.jasmineMatches;
jasmine.argThat = function(expected) {
return new jasmine.Matchers.ArgThat(expected);
};
jasmine.Matchers.Capture = (function(_super) {
__extends(Capture, _super);
function Capture(captor) {
this.captor = captor;
}
Capture.prototype.jasmineMatches = function(actual) {
this.captor.value = actual;
return true;
};
return Capture;
})(jasmine.Matchers.Any);
jasmine.Matchers.Capture.prototype.matches = jasmine.Matchers.Capture.prototype.jasmineMatches;
Captor = (function() {
function Captor() {}
Captor.prototype.capture = function() {
return new jasmine.Matchers.Capture(this);
};
return Captor;
})();
jasmine.captor = function() {
return new Captor();
};
}).call(this);

View File

@@ -1,51 +0,0 @@
// Jasmine.Async, v0.1.0
// Copyright (c)2012 Muted Solutions, LLC. All Rights Reserved.
// Distributed under MIT license
// http://github.com/derickbailey/jasmine.async
this.AsyncSpec = (function(global){
// Private Methods
// ---------------
function runAsync(block){
return function(){
var done = false;
var complete = function(){ done = true; };
runs(function(){
block(complete);
});
waitsFor(function(){
return done;
});
};
}
// Constructor Function
// --------------------
function AsyncSpec(spec){
this.spec = spec;
}
// Public API
// ----------
AsyncSpec.prototype.beforeEach = function(block){
this.spec.beforeEach(runAsync(block));
};
AsyncSpec.prototype.afterEach = function(block){
this.spec.afterEach(runAsync(block));
};
AsyncSpec.prototype.it = function(description, block){
// For some reason, `it` is not attached to the current
// test suite, so it has to be called from the global
// context.
global.it(description, runAsync(block));
};
return AsyncSpec;
})(this);

View File

@@ -1,199 +1,752 @@
/*
Jasmine-Ajax : a set of helpers for testing AJAX requests under the Jasmine
BDD framework for JavaScript.
Supports jQuery.
Jasmine-Ajax - v3.2.0: a set of helpers for testing AJAX requests under the Jasmine
BDD framework for JavaScript.
http://github.com/pivotal/jasmine-ajax
http://github.com/jasmine/jasmine-ajax
Jasmine Home page: http://pivotal.github.com/jasmine
Jasmine Home page: http://jasmine.github.io/
Copyright (c) 2008-2013 Pivotal Labs
Copyright (c) 2008-2015 Pivotal Labs
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:
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:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
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.
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.
*/
*/
// Jasmine-Ajax interface
var ajaxRequests = [];
//Module wrapper to support both browser and CommonJS environment
(function (root, factory) {
if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
// CommonJS
var jasmineRequire = require('jasmine-core');
module.exports = factory(root, function() {
return jasmineRequire;
});
} else {
// Browser globals
window.MockAjax = factory(root, getJasmineRequireObj);
}
}(typeof window !== 'undefined' ? window : global, function (global, getJasmineRequireObj) {
function mostRecentAjaxRequest() {
if (ajaxRequests.length > 0) {
return ajaxRequests[ajaxRequests.length - 1];
} else {
return null;
//
getJasmineRequireObj().ajax = function(jRequire) {
var $ajax = {};
$ajax.RequestStub = jRequire.AjaxRequestStub();
$ajax.RequestTracker = jRequire.AjaxRequestTracker();
$ajax.StubTracker = jRequire.AjaxStubTracker();
$ajax.ParamParser = jRequire.AjaxParamParser();
$ajax.event = jRequire.AjaxEvent();
$ajax.eventBus = jRequire.AjaxEventBus($ajax.event);
$ajax.fakeRequest = jRequire.AjaxFakeRequest($ajax.eventBus);
$ajax.MockAjax = jRequire.MockAjax($ajax);
return $ajax.MockAjax;
};
getJasmineRequireObj().AjaxEvent = function() {
function now() {
return new Date().getTime();
}
}
function clearAjaxRequests() {
ajaxRequests = [];
}
function noop() {
}
// Fake XHR for mocking Ajax Requests & Responses
function FakeXMLHttpRequest() {
var extend = Object.extend || jQuery.extend;
extend(this, {
requestHeaders: {},
// Event object
// https://dom.spec.whatwg.org/#concept-event
function XMLHttpRequestEvent(xhr, type) {
this.type = type;
this.bubbles = false;
this.cancelable = false;
this.timeStamp = now();
open: function() {
this.method = arguments[0];
this.url = arguments[1];
this.username = arguments[3];
this.password = arguments[4];
this.readyState = 1;
this.isTrusted = false;
this.defaultPrevented = false;
// Event phase should be "AT_TARGET"
// https://dom.spec.whatwg.org/#dom-event-at_target
this.eventPhase = 2;
this.target = xhr;
this.currentTarget = xhr;
}
XMLHttpRequestEvent.prototype.preventDefault = noop;
XMLHttpRequestEvent.prototype.stopPropagation = noop;
XMLHttpRequestEvent.prototype.stopImmediatePropagation = noop;
function XMLHttpRequestProgressEvent() {
XMLHttpRequestEvent.apply(this, arguments);
this.lengthComputable = false;
this.loaded = 0;
this.total = 0;
}
// Extend prototype
XMLHttpRequestProgressEvent.prototype = XMLHttpRequestEvent.prototype;
return {
event: function(xhr, type) {
return new XMLHttpRequestEvent(xhr, type);
},
setRequestHeader: function(header, value) {
this.requestHeaders[header] = value;
},
progressEvent: function(xhr, type) {
return new XMLHttpRequestProgressEvent(xhr, type);
}
};
};
getJasmineRequireObj().AjaxEventBus = function(eventFactory) {
function EventBus(source) {
this.eventList = {};
this.source = source;
}
abort: function() {
this.readyState = 0;
},
function ensureEvent(eventList, name) {
eventList[name] = eventList[name] || [];
return eventList[name];
}
readyState: 0,
function findIndex(list, thing) {
if (list.indexOf) {
return list.indexOf(thing);
}
onload: function() {
},
onreadystatechange: function(isTimeout) {
},
status: null,
send: function(data) {
this.params = data;
this.readyState = 2;
},
data: function() {
var data = {};
if (typeof this.params !== 'string') return data;
var params = this.params.split('&');
for (var i = 0; i < params.length; ++i) {
var kv = params[i].replace(/\+/g, ' ').split('=');
var key = decodeURIComponent(kv[0]);
data[key] = data[key] || [];
data[key].push(decodeURIComponent(kv[1]));
data[key].sort();
for(var i = 0; i < list.length; i++) {
if (thing === list[i]) {
return i;
}
return data;
},
}
getResponseHeader: function(name) {
return this.responseHeaders[name];
},
return -1;
}
getAllResponseHeaders: function() {
var responseHeaders = [];
for (var i in this.responseHeaders) {
if (this.responseHeaders.hasOwnProperty(i)) {
responseHeaders.push(i + ': ' + this.responseHeaders[i]);
EventBus.prototype.addEventListener = function(event, callback) {
ensureEvent(this.eventList, event).push(callback);
};
EventBus.prototype.removeEventListener = function(event, callback) {
var index = findIndex(this.eventList[event], callback);
if (index >= 0) {
this.eventList[event].splice(index, 1);
}
};
EventBus.prototype.trigger = function(event) {
var evt;
// Event 'readystatechange' is should be a simple event.
// Others are progress event.
// https://xhr.spec.whatwg.org/#events
if (event === 'readystatechange') {
evt = eventFactory.event(this.source, event);
} else {
evt = eventFactory.progressEvent(this.source, event);
}
var eventListeners = this.eventList[event];
if (eventListeners) {
for (var i = 0; i < eventListeners.length; i++) {
eventListeners[i].call(this.source, evt);
}
}
};
return function(source) {
return new EventBus(source);
};
};
getJasmineRequireObj().AjaxFakeRequest = function(eventBusFactory) {
function extend(destination, source, propertiesToSkip) {
propertiesToSkip = propertiesToSkip || [];
for (var property in source) {
if (!arrayContains(propertiesToSkip, property)) {
destination[property] = source[property];
}
}
return destination;
}
function arrayContains(arr, item) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] === item) {
return true;
}
}
return false;
}
function wrapProgressEvent(xhr, eventName) {
return function() {
if (xhr[eventName]) {
xhr[eventName].apply(xhr, arguments);
}
};
}
function initializeEvents(xhr) {
xhr.eventBus.addEventListener('readystatechange', wrapProgressEvent(xhr, 'onreadystatechange'));
xhr.eventBus.addEventListener('loadstart', wrapProgressEvent(xhr, 'onloadstart'));
xhr.eventBus.addEventListener('load', wrapProgressEvent(xhr, 'onload'));
xhr.eventBus.addEventListener('loadend', wrapProgressEvent(xhr, 'onloadend'));
xhr.eventBus.addEventListener('progress', wrapProgressEvent(xhr, 'onprogress'));
xhr.eventBus.addEventListener('error', wrapProgressEvent(xhr, 'onerror'));
xhr.eventBus.addEventListener('abort', wrapProgressEvent(xhr, 'onabort'));
xhr.eventBus.addEventListener('timeout', wrapProgressEvent(xhr, 'ontimeout'));
}
function unconvertibleResponseTypeMessage(type) {
var msg = [
"Can't build XHR.response for XHR.responseType of '",
type,
"'.",
"XHR.response must be explicitly stubbed"
];
return msg.join(' ');
}
function fakeRequest(global, requestTracker, stubTracker, paramParser) {
function FakeXMLHttpRequest() {
requestTracker.track(this);
this.eventBus = eventBusFactory(this);
initializeEvents(this);
this.requestHeaders = {};
this.overriddenMimeType = null;
}
function findHeader(name, headers) {
name = name.toLowerCase();
for (var header in headers) {
if (header.toLowerCase() === name) {
return headers[header];
}
}
return responseHeaders.join('\r\n');
},
responseText: null,
response: function(response) {
this.status = response.status;
this.responseText = response.responseText || "";
this.readyState = 4;
this.responseHeaders = response.responseHeaders ||
{"Content-type": response.contentType || "application/json" };
// uncomment for jquery 1.3.x support
// jasmine.Clock.tick(20);
this.onload();
this.onreadystatechange();
},
responseTimeout: function() {
this.readyState = 4;
jasmine.Clock.tick(jQuery.ajaxSettings.timeout || 30000);
this.onreadystatechange('timeout');
}
});
return this;
}
function normalizeHeaders(rawHeaders, contentType) {
var headers = [];
if (rawHeaders) {
if (rawHeaders instanceof Array) {
headers = rawHeaders;
} else {
for (var headerName in rawHeaders) {
if (rawHeaders.hasOwnProperty(headerName)) {
headers.push({ name: headerName, value: rawHeaders[headerName] });
}
}
}
} else {
headers.push({ name: "Content-Type", value: contentType || "application/json" });
}
jasmine.Ajax = {
isInstalled: function() {
return jasmine.Ajax.installed === true;
},
assertInstalled: function() {
if (!jasmine.Ajax.isInstalled()) {
throw new Error("Mock ajax is not installed, use jasmine.Ajax.useMock()");
return headers;
}
},
useMock: function() {
if (!jasmine.Ajax.isInstalled()) {
var spec = jasmine.getEnv().currentSpec;
spec.after(jasmine.Ajax.uninstallMock);
jasmine.Ajax.installMock();
function parseXml(xmlText, contentType) {
if (global.DOMParser) {
return (new global.DOMParser()).parseFromString(xmlText, 'text/xml');
} else {
var xml = new global.ActiveXObject("Microsoft.XMLDOM");
xml.async = "false";
xml.loadXML(xmlText);
return xml;
}
}
},
installMock: function() {
if (typeof jQuery != 'undefined') {
jasmine.Ajax.installJquery();
} else {
throw new Error("jasmine.Ajax currently only supports jQuery");
var xmlParsables = ['text/xml', 'application/xml'];
function getResponseXml(responseText, contentType) {
if (arrayContains(xmlParsables, contentType.toLowerCase())) {
return parseXml(responseText, contentType);
} else if (contentType.match(/\+xml$/)) {
return parseXml(responseText, 'text/xml');
}
return null;
}
jasmine.Ajax.installed = true;
},
installJquery: function() {
jasmine.Ajax.mode = 'jQuery';
jasmine.Ajax.real = jQuery.ajaxSettings.xhr;
jQuery.ajaxSettings.xhr = jasmine.Ajax.jQueryMock;
var iePropertiesThatCannotBeCopied = ['responseBody', 'responseText', 'responseXML', 'status', 'statusText', 'responseTimeout', 'responseURL'];
extend(FakeXMLHttpRequest.prototype, new global.XMLHttpRequest(), iePropertiesThatCannotBeCopied);
extend(FakeXMLHttpRequest.prototype, {
open: function() {
this.method = arguments[0];
this.url = arguments[1];
this.username = arguments[3];
this.password = arguments[4];
this.readyState = 1;
this.requestHeaders = {};
this.eventBus.trigger('readystatechange');
},
},
setRequestHeader: function(header, value) {
if(this.requestHeaders.hasOwnProperty(header)) {
this.requestHeaders[header] = [this.requestHeaders[header], value].join(', ');
} else {
this.requestHeaders[header] = value;
}
},
uninstallMock: function() {
jasmine.Ajax.assertInstalled();
if (jasmine.Ajax.mode == 'jQuery') {
jQuery.ajaxSettings.xhr = jasmine.Ajax.real;
}
jasmine.Ajax.reset();
},
overrideMimeType: function(mime) {
this.overriddenMimeType = mime;
},
reset: function() {
jasmine.Ajax.installed = false;
jasmine.Ajax.mode = null;
jasmine.Ajax.real = null;
},
abort: function() {
this.readyState = 0;
this.status = 0;
this.statusText = "abort";
this.eventBus.trigger('readystatechange');
this.eventBus.trigger('progress');
this.eventBus.trigger('abort');
this.eventBus.trigger('loadend');
},
jQueryMock: function() {
var newXhr = new FakeXMLHttpRequest();
ajaxRequests.push(newXhr);
return newXhr;
},
readyState: 0,
installed: false,
mode: null
onloadstart: null,
onprogress: null,
onabort: null,
onerror: null,
onload: null,
ontimeout: null,
onloadend: null,
onreadystatechange: null,
addEventListener: function() {
this.eventBus.addEventListener.apply(this.eventBus, arguments);
},
removeEventListener: function(event, callback) {
this.eventBus.removeEventListener.apply(this.eventBus, arguments);
},
status: null,
send: function(data) {
this.params = data;
this.eventBus.trigger('loadstart');
var stub = stubTracker.findStub(this.url, data, this.method);
if (stub) {
if (stub.isReturn()) {
this.respondWith(stub);
} else if (stub.isError()) {
this.responseError();
} else if (stub.isTimeout()) {
this.responseTimeout();
}
}
},
contentType: function() {
return findHeader('content-type', this.requestHeaders);
},
data: function() {
if (!this.params) {
return {};
}
return paramParser.findParser(this).parse(this.params);
},
getResponseHeader: function(name) {
name = name.toLowerCase();
var resultHeader;
for(var i = 0; i < this.responseHeaders.length; i++) {
var header = this.responseHeaders[i];
if (name === header.name.toLowerCase()) {
if (resultHeader) {
resultHeader = [resultHeader, header.value].join(', ');
} else {
resultHeader = header.value;
}
}
}
return resultHeader;
},
getAllResponseHeaders: function() {
var responseHeaders = [];
for (var i = 0; i < this.responseHeaders.length; i++) {
responseHeaders.push(this.responseHeaders[i].name + ': ' +
this.responseHeaders[i].value);
}
return responseHeaders.join('\r\n') + '\r\n';
},
responseText: null,
response: null,
responseType: null,
responseURL: null,
responseValue: function() {
switch(this.responseType) {
case null:
case "":
case "text":
return this.readyState >= 3 ? this.responseText : "";
case "json":
return JSON.parse(this.responseText);
case "arraybuffer":
throw unconvertibleResponseTypeMessage('arraybuffer');
case "blob":
throw unconvertibleResponseTypeMessage('blob');
case "document":
return this.responseXML;
}
},
respondWith: function(response) {
if (this.readyState === 4) {
throw new Error("FakeXMLHttpRequest already completed");
}
this.status = response.status;
this.statusText = response.statusText || "";
this.responseHeaders = normalizeHeaders(response.responseHeaders, response.contentType);
this.readyState = 2;
this.eventBus.trigger('readystatechange');
this.responseText = response.responseText || "";
this.responseType = response.responseType || "";
this.responseURL = response.responseURL || null;
this.readyState = 4;
this.responseXML = getResponseXml(response.responseText, this.getResponseHeader('content-type') || '');
if (this.responseXML) {
this.responseType = 'document';
}
if ('response' in response) {
this.response = response.response;
} else {
this.response = this.responseValue();
}
this.eventBus.trigger('readystatechange');
this.eventBus.trigger('progress');
this.eventBus.trigger('load');
this.eventBus.trigger('loadend');
},
responseTimeout: function() {
if (this.readyState === 4) {
throw new Error("FakeXMLHttpRequest already completed");
}
this.readyState = 4;
jasmine.clock().tick(30000);
this.eventBus.trigger('readystatechange');
this.eventBus.trigger('progress');
this.eventBus.trigger('timeout');
this.eventBus.trigger('loadend');
},
responseError: function() {
if (this.readyState === 4) {
throw new Error("FakeXMLHttpRequest already completed");
}
this.readyState = 4;
this.eventBus.trigger('readystatechange');
this.eventBus.trigger('progress');
this.eventBus.trigger('error');
this.eventBus.trigger('loadend');
}
});
return FakeXMLHttpRequest;
}
return fakeRequest;
};
getJasmineRequireObj().MockAjax = function($ajax) {
function MockAjax(global) {
var requestTracker = new $ajax.RequestTracker(),
stubTracker = new $ajax.StubTracker(),
paramParser = new $ajax.ParamParser(),
realAjaxFunction = global.XMLHttpRequest,
mockAjaxFunction = $ajax.fakeRequest(global, requestTracker, stubTracker, paramParser);
this.install = function() {
if (global.XMLHttpRequest === mockAjaxFunction) {
throw "MockAjax is already installed.";
}
global.XMLHttpRequest = mockAjaxFunction;
};
this.uninstall = function() {
if (global.XMLHttpRequest !== mockAjaxFunction) {
throw "MockAjax not installed.";
}
global.XMLHttpRequest = realAjaxFunction;
this.stubs.reset();
this.requests.reset();
paramParser.reset();
};
this.stubRequest = function(url, data, method) {
var stub = new $ajax.RequestStub(url, data, method);
stubTracker.addStub(stub);
return stub;
};
this.withMock = function(closure) {
this.install();
try {
closure();
} finally {
this.uninstall();
}
};
this.addCustomParamParser = function(parser) {
paramParser.add(parser);
};
this.requests = requestTracker;
this.stubs = stubTracker;
}
return MockAjax;
};
getJasmineRequireObj().AjaxParamParser = function() {
function ParamParser() {
var defaults = [
{
test: function(xhr) {
return (/^application\/json/).test(xhr.contentType());
},
parse: function jsonParser(paramString) {
return JSON.parse(paramString);
}
},
{
test: function(xhr) {
return true;
},
parse: function naiveParser(paramString) {
var data = {};
var params = paramString.split('&');
for (var i = 0; i < params.length; ++i) {
var kv = params[i].replace(/\+/g, ' ').split('=');
var key = decodeURIComponent(kv[0]);
data[key] = data[key] || [];
data[key].push(decodeURIComponent(kv[1]));
}
return data;
}
}
];
var paramParsers = [];
this.add = function(parser) {
paramParsers.unshift(parser);
};
this.findParser = function(xhr) {
for(var i in paramParsers) {
var parser = paramParsers[i];
if (parser.test(xhr)) {
return parser;
}
}
};
this.reset = function() {
paramParsers = [];
for(var i in defaults) {
paramParsers.push(defaults[i]);
}
};
this.reset();
}
return ParamParser;
};
getJasmineRequireObj().AjaxRequestStub = function() {
var RETURN = 0,
ERROR = 1,
TIMEOUT = 2;
function RequestStub(url, stubData, method) {
var normalizeQuery = function(query) {
return query ? query.split('&').sort().join('&') : undefined;
};
if (url instanceof RegExp) {
this.url = url;
this.query = undefined;
} else {
var split = url.split('?');
this.url = split[0];
this.query = split.length > 1 ? normalizeQuery(split[1]) : undefined;
}
this.data = (stubData instanceof RegExp) ? stubData : normalizeQuery(stubData);
this.method = method;
this.andReturn = function(options) {
this.action = RETURN;
this.status = options.status || 200;
this.contentType = options.contentType;
this.response = options.response;
this.responseText = options.responseText;
this.responseHeaders = options.responseHeaders;
this.responseURL = options.responseURL;
};
this.isReturn = function() {
return this.action === RETURN;
};
this.andError = function() {
this.action = ERROR;
};
this.isError = function() {
return this.action === ERROR;
};
this.andTimeout = function() {
this.action = TIMEOUT;
};
this.isTimeout = function() {
return this.action === TIMEOUT;
};
this.matches = function(fullUrl, data, method) {
var urlMatches = false;
fullUrl = fullUrl.toString();
if (this.url instanceof RegExp) {
urlMatches = this.url.test(fullUrl);
} else {
var urlSplit = fullUrl.split('?'),
url = urlSplit[0],
query = urlSplit[1];
urlMatches = this.url === url && this.query === normalizeQuery(query);
}
var dataMatches = false;
if (this.data instanceof RegExp) {
dataMatches = this.data.test(data);
} else {
dataMatches = !this.data || this.data === normalizeQuery(data);
}
return urlMatches && dataMatches && (!this.method || this.method === method);
};
}
return RequestStub;
};
getJasmineRequireObj().AjaxRequestTracker = function() {
function RequestTracker() {
var requests = [];
this.track = function(request) {
requests.push(request);
};
this.first = function() {
return requests[0];
};
this.count = function() {
return requests.length;
};
this.reset = function() {
requests = [];
};
this.mostRecent = function() {
return requests[requests.length - 1];
};
this.at = function(index) {
return requests[index];
};
this.filter = function(url_to_match) {
var matching_requests = [];
for (var i = 0; i < requests.length; i++) {
if (url_to_match instanceof RegExp &&
url_to_match.test(requests[i].url)) {
matching_requests.push(requests[i]);
} else if (url_to_match instanceof Function &&
url_to_match(requests[i])) {
matching_requests.push(requests[i]);
} else {
if (requests[i].url === url_to_match) {
matching_requests.push(requests[i]);
}
}
}
return matching_requests;
};
}
return RequestTracker;
};
getJasmineRequireObj().AjaxStubTracker = function() {
function StubTracker() {
var stubs = [];
this.addStub = function(stub) {
stubs.push(stub);
};
this.reset = function() {
stubs = [];
};
this.findStub = function(url, data, method) {
for (var i = stubs.length - 1; i >= 0; i--) {
var stub = stubs[i];
if (stub.matches(url, data, method)) {
return stub;
}
}
};
}
return StubTracker;
};
var jRequire = getJasmineRequireObj();
var MockAjax = jRequire.ajax(jRequire);
jasmine.Ajax = new MockAjax(global);
return MockAjax;
}));

View File

@@ -29,8 +29,8 @@ prepend_path: common/static
# Paths to library JavaScript files (optional)
lib_paths:
- js/vendor/jquery.min.js
- js/vendor/jasmine-jquery.js
- js/vendor/jasmine-imagediff.js
- js/libs/jasmine-waituntil.js
- js/vendor/jquery.truncate.js
- js/vendor/mustache.js
- common/js/vendor/underscore.js

View File

@@ -29,8 +29,9 @@ prepend_path: common/static
# Paths to library JavaScript files (optional)
lib_paths:
- js/vendor/jquery.min.js
- js/vendor/jasmine-jquery.js
- js/vendor/jasmine-imagediff.js
- js/libs/jasmine-stealth.js
- js/libs/jasmine-waituntil.js
- js/vendor/jquery.simulate.js
- js/vendor/jquery.truncate.js
- common/js/vendor/underscore.js
@@ -45,7 +46,6 @@ lib_paths:
- coffee/src/jquery.immediateDescendents.js
- js/vendor/requirejs/text.js
- js/vendor/sinon-1.17.0.js
- js/vendor/jasmine-stealth.js
# Paths to source JavaScript files
src_paths:

View File

@@ -34,6 +34,7 @@ var files = [
{pattern: 'js/vendor/jquery.min.js', included: true},
{pattern: 'js/vendor/jasmine-imagediff.js', included: true},
{pattern: 'js/libs/jasmine-waituntil.js', included: true},
{pattern: 'js/libs/jasmine-extensions.js', included: true},
{pattern: 'js/vendor/jquery.truncate.js', included: true},
{pattern: 'js/vendor/mustache.js', included: true},
{pattern: 'common/js/vendor/underscore.js', included: true},
@@ -45,6 +46,7 @@ var files = [
{pattern: 'js/test/add_ajax_prefix.js', included: true},
{pattern: 'js/test/i18n.js', included: true},
{pattern: 'coffee/src/jquery.immediateDescendents.js', included: true},
{pattern: 'js/vendor/jquery.leanModal.js', included: true},
// Paths to source JavaScript files
{pattern: 'js/xblock/**/*.js', included: true, nocache: true},

View File

@@ -32,6 +32,7 @@ var files = [
{pattern: 'js/vendor/jasmine-imagediff.js', included: false},
{pattern: 'js/libs/jasmine-stealth.js', included: false},
{pattern: 'js/libs/jasmine-waituntil.js', included: false},
{pattern: 'js/libs/jasmine-extensions.js', included: false},
{pattern: 'js/vendor/jquery.simulate.js', included: false},
{pattern: 'js/vendor/jquery.truncate.js', included: false},
{pattern: 'common/js/vendor/underscore.js', included: false},