more fixes, plus start messing around with capybara-like way to interact with jquery elements for testing

This commit is contained in:
John Bintz 2012-01-18 17:41:08 -05:00
parent 81673543fe
commit 01f2b2a0e3
9 changed files with 214 additions and 98 deletions

View File

@ -7,3 +7,6 @@ gem 'guard', '~> 0.8.0'
gem 'jasmine-headless-webkit', :path => '../jasmine-headless-webkit' gem 'jasmine-headless-webkit', :path => '../jasmine-headless-webkit'
gem 'guard-jasmine-headless-webkit', :path => '../guard-jasmine-headless-webkit' gem 'guard-jasmine-headless-webkit', :path => '../guard-jasmine-headless-webkit'
gem 'rb-fsevent' gem 'rb-fsevent'
gem 'jquery-rails'
gem 'rack', '~> 1.2.0'
gem 'sprockets', '~> 2.0.0'

View File

@ -0,0 +1,29 @@
#= require jquery
#
this.Cabiai =
wrapException: (view, message) ->
throw new Error("#{message}\nin: #{$(view).html()}")
Actions:
_view: -> Cabiai.viewSource.apply(this)
clickOn: (text) ->
found = false
$('button', @_view()).each (index, element) =>
if !found and $(element).text() == text
$(element).click()
found = true
Cabiai.wrapException(@_view(), "Button not found: #{text}") if !found
within: (selector, callback) ->
preservedView = @_view
view = $(selector, @_view())
@_view = -> view
callback.apply(this)
@_view = preservedView

View File

@ -1,17 +1,18 @@
class jasmine.GWT.Background class jasmine.GWT.Background
constructor: (code) -> constructor: (@code) ->
@statements = [] @statements = []
run: =>
jasmine.GWT.currentScenario_ = this jasmine.GWT.currentScenario_ = this
code.apply(this) @code.apply(this)
jasmine.GWT.currentScenario_ = null jasmine.GWT.currentScenario_ = null
Given: (name, code) -> Given: (name, code) => this.Step('Given', name, code)
@statements.push([ 'Given', name, code ]) When: (name, code) => this.Step('When', name, code)
When: (name, code) -> Then: (name, code) => this.Step('Then', name, code)
@statements.push([ 'When', name, code ])
Then: (name, code) -> Step: (type, name, code) =>
@statements.push([ 'Then', name, code ]) @statements.push([ type, name, code ])

View File

@ -1,15 +1,19 @@
class jasmine.GWT.Feature class jasmine.GWT.Feature
constructor: (@name, code) -> constructor: (@name, @code) ->
run: =>
jasmine.GWT.currentFeature_ = this jasmine.GWT.currentFeature_ = this
@background = null @background = null
code.apply(this) @code.apply(this)
jasmine.GWT.currentFeature_ = null jasmine.GWT.currentFeature_ = null
Scenario: (name, code) -> Scenario: (name, code) ->
new jasmine.GWT.Scenario(name, code, this) scenario = new jasmine.GWT.Scenario(name, code, this)
scenario.run()
Background: (code) -> Background: (code) ->
@background = new jasmine.GWT.Background(code) @background = new jasmine.GWT.Background(code)
@background.run()

View File

@ -1,47 +1,37 @@
#= require jasmine/GWT/Background #= require jasmine/GWT/Background
# #
class jasmine.GWT.Scenario extends jasmine.GWT.Background class jasmine.GWT.Scenario extends jasmine.GWT.Background
constructor: (scenarioName, code, @feature) -> @runCode: (type, name, param, position, context, args = []) ->
super(code)
_statements = this.allStatements()
_this = this
describe @feature.name, ->
describe scenarioName, ->
_this.spies_ = []
for index in [ 0..._statements.length ]
[ type, name, param ] = _statements[index]
_this._type = type
_this._name = name
runCode = (param, index, args = []) ->
isLast = (index + 1) == _statements.length
isFirst = (index == 0)
it "#{type} #{name}", -> it "#{type} #{name}", ->
if isFirst if position == 'first'
jasmine.GWT.runHook('World', _this) jasmine.GWT.runHook('World', context)
jasmine.GWT.runHook('Before', _this) jasmine.GWT.runHook('Before', context)
this.spyOn = (args...) -> this.spyOn = (args...) ->
this.spies_ = _this.spies_ this.spies_ = context.spies_
jasmine.Spec.prototype.spyOn.apply(this, args) jasmine.Spec.prototype.spyOn.apply(this, args)
this.removeAllSpies = -> this.removeAllSpies = ->
if isLast if position == 'last'
jasmine.Spec.prototype.removeAllSpies.apply(_this) jasmine.Spec.prototype.removeAllSpies.apply(context)
param.apply(_this, args) param.apply(context, args)
if isLast if position == 'last'
jasmine.GWT.runHook('After', _this) jasmine.GWT.runHook('After', context)
runFailure = (type, name, args) -> @runFailure: (type, name, args) ->
it "#{type} #{name}", -> it "#{type} #{name}", ->
output = [ "", "No step defined for #{type} #{name}. Define one using the following:", '' ] output = [ "", "No step defined for #{type} #{name}. Define one using the following:", '' ]
output = output.concat(jasmine.GWT.Scenario.generateStepDefinition(type, name, args))
output.push("")
this.addMatcherResult(
jasmine.GWT.Scenario.generateNotDefinedResult(type, name, output.join("\n"))
)
@generateStepDefinition: (type, name, args) ->
output = []
argCount = args.length argCount = args.length
@ -61,46 +51,65 @@ class jasmine.GWT.Scenario extends jasmine.GWT.Background
output.push("#{type} /^#{name}$/, (#{args.join(', ')}) ->") output.push("#{type} /^#{name}$/, (#{args.join(', ')}) ->")
output.push(" @not_defined()") output.push(" @not_defined()")
output.push("") output
this.addMatcherResult( @generateNotDefinedResult: (type, name, message) ->
new jasmine.ExpectationResult( new jasmine.ExpectationResult(
matcherName: 'steps', matcherName: 'step',
passed: false, passed: false,
expected: 'to be defined', expected: 'to be defined',
actual: "#{type} #{name}", actual: "#{type} #{name}",
message: output.join("\n") message: message
)
) )
constructor: (@scenarioName, @code, @feature) ->
super(@code)
run: =>
super()
jasmine.GWT.currentScenario_ = this
_statements = this.allStatements()
_this = this
describe @feature.name, ->
describe _this.scenarioName, ->
_this.spies_ = []
position = 'first'
for index in [ 0..._statements.length ]
[ type, name, param ] = _statements[index]
[ _this._type, _this._name ] = [ type, name ]
args = [] args = []
codeRunner = (thing, args = []) ->
jasmine.GWT.Scenario.runCode(type, name, thing, position, _this, args)
if param? if param?
if typeof param == "function" if typeof param == "function"
runCode(param, index) codeRunner(param)
continue continue
else else
args = [ param ] args = [ param ]
found = false found = false
if jasmine.GWT.Steps[type] for [ match, code ] in (jasmine.GWT.Steps[type] || [])
for [ match, code ] in jasmine.GWT.Steps[type]
if match.constructor == RegExp
if result = name.match(match) if result = name.match(match)
result.shift() codeRunner(code, result[1..-1].concat(args))
runCode(code, index, result.concat(args))
found = true
break
else
if name == match
runCode(code, index)
found = true found = true
break break
runFailure(type, name, args) if !found jasmine.GWT.Scenario.runFailure(type, name, args) if !found
position = (if (index + 2) == _statements.length then 'last' else 'middle')
jasmine.GWT.currentScenario_ = null
allStatements: => allStatements: =>
allStatements = [] allStatements = []
@ -111,12 +120,6 @@ class jasmine.GWT.Scenario extends jasmine.GWT.Background
allStatements.concat(@statements) allStatements.concat(@statements)
not_defined: => not_defined: =>
fakeResult = new jasmine.ExpectationResult( fakeResult = jasmine.GWT.Scenario.generateNotDefinedResult(@_type, @_name, 'has no code defined.')
matcherName: 'step',
passed: false,
expected: 'to be defined',
actual: "#{@_type} #{@_name}",
message: "has no code defined."
)
jasmine.getEnv().currentSpec.addMatcherResult(fakeResult) jasmine.getEnv().currentSpec.addMatcherResult(fakeResult)

View File

@ -1,6 +1,7 @@
jasmine.GWT.globals = jasmine.GWT.globals =
Feature: (args...) -> Feature: (args...) ->
new jasmine.GWT.Feature(args...) feature = new jasmine.GWT.Feature(args...)
feature.run()
Background: (args...) -> Background: (args...) ->
jasmine.GWT.currentFeature_.Background(args...) jasmine.GWT.currentFeature_.Background(args...)

View File

@ -0,0 +1,45 @@
#= require cabiai
#
describe 'Cabiai', ->
cabiai = null
beforeEach ->
Cabiai.viewSource = -> @view
cabiai = {}
cabiai[method] = code for method, code of Cabiai.Actions
describe 'Actions#clickOn', ->
context 'button', ->
text = "text"
isClicked = false
beforeEach ->
cabiai.view = $("<div><button>#{text}</button></div>")
$('button', cabiai.view).click -> isClicked = true
it 'should find a button by text', ->
cabiai.clickOn(text)
expect(isClicked).toEqual(true)
it 'should not find it' , ->
try
cabiai.clickOn('other')
expect("throw exception").toEqual(false)
catch e
expect(e.message).toMatch(/Button not found: other/)
describe 'Actions#within', ->
beforeEach ->
cabiai.view = $('<div><li>One</li><li>Two</li></div>')
it 'should focus an action within a selector', ->
currentView = null
cabiai.within 'li:eq(1)', ->
currentView = this._view()
expect(currentView).toEqual($('li:eq(1)', cabiai.view))

View File

@ -61,3 +61,33 @@ describe 'jasmine.GWT', ->
jasmine.GWT.World(func) jasmine.GWT.World(func)
expect(jasmine.GWT.Hook).toHaveBeenCalledWith('World', func) expect(jasmine.GWT.Hook).toHaveBeenCalledWith('World', func)
describe '.runHook', ->
object = null
value = 'value'
beforeEach ->
object = {}
jasmine.GWT.Hooks['Hooks'] = [
-> this.value = value
]
it 'should run all the code in the hooks', ->
jasmine.GWT.runHook('Hooks', object)
expect(object.value).toEqual(value)
describe '.generateWoldMethods', ->
object = null
method = ->
beforeEach ->
object =
method: method
it 'should add methods to the object', ->
newObject = {}
runner = jasmine.GWT.generateWorldMethods(object)
runner.apply(newObject)
expect(newObject.method).toEqual(method)

View File

@ -1,7 +1,7 @@
src_dir: lib/assets/javascripts src_dir: lib/assets/javascripts
src_files: [ 'jasmine-gwt.js.coffee' ] src_files: [ 'jasmine-gwt.js.coffee', 'cabiai.js.coffee' ]
spec_dir: spec/javascripts spec_dir: spec/javascripts
spec_files: [ '**/*_spec.coffee' ] spec_files: [ '**/*_spec.*', '*_spec.*' ]
helpers: [ 'spec_helper.coffee' ] helpers: [ 'spec_helper.coffee' ]