Extending Spectacular
Snake Case Syntax
All the exposed methods are provided both with camelCase
and snake_case
syntax. By convention, JavaScript use the camel case form, but some people writing CoffeeScript for nodejs often use the snake case form. Spectacular support both.
You can define any matcher, or helper, or aliases, with either the snake case or camel case form, the alternative will be also added to the global object.
For instance, the sharedExample
is also available through shared_example
.
You can find below a table with all the snake case equivalent:
after | No differences | |
before | No differences | |
beWithin | be_within | |
chain | No differences | |
contains | No differences | |
context | No differences | |
createWith | create_with | |
dependsOn | depends_on | |
describe | No differences | |
description | No differences | |
equal | No differences | |
exist | No differences | |
expect | No differences | |
factory | No differences | |
factoryMixin | factory_mixin | |
fail | No differences | |
failureMessageForShould | failure_message_for_should | |
failureMessageForShouldnt | failure_message_for_shouldnt | |
fixturePath | fixture_path | |
fixtures | No differences | |
given | No differences | |
have.selector | No differences | |
have | No differences | |
haveBeenCalled.with | have_been_called.with | |
haveBeenCalled | have_been_called | |
it | No differences | |
itBehavesLike | it_behaves_like | |
its | No differences | |
itShould | it_should | |
itsInstance | its_instance | |
itsReturn | its_return | |
match | No differences | |
match | No differences | |
pending | No differences | |
registerFixtureHandler | register_fixture_handler | |
set | No differences | |
should | No differences | |
shouldnt | No differences | |
skip | No differences | |
specify | No differences | |
spy.argsForCall | spy.args_for_call | |
spyOn(...).andCallFake | spy_on(...).and_call_fake | |
spyOn(...).andCallThrough | spy_on(...).and_call_trough | |
spyOn(...).andReturns | spy_on(...).and_returns | |
spyOn | spy_on | |
subject | No differences | |
success | No differences | |
takes | No differences | |
the | No differences | |
throwAnError(msg).inContext | throw_an_error(msg).in_context | |
throwAnError(msg).with | throw_an_error(msg).with | |
throwAnError | throw_an_error | |
trait | No differences | |
whenPass | when_pass | |
withArguments | with_arguments | |
withParameters | with_parameters | |
xcontext | No differences | |
xdescribe | No differences | |
xit | No differences |
You can also snakify/camelize your own objects using the utils.snakify
or utils.camelize
methods:
myObject =
someMethod: ->
someOtherMethod: ->
utils.snakify myObject
Will gives you an object such as:
myObject =
someMethod: ->
someOtherMethod: ->
some_method: ->
some_other_method: ->
Matchers
Matchers are defined with the spectacular.matcher
function. It generates an object with a match
method that should return a boolean value corresponding to the assertion result.
spectacular.matcher 'returnSomething', ->
match (actual) -> actual() isnt null
description -> "return something"
failureMessageForShould message = "Expected #{@actual} to #{@description}"
# Usage:
it -> should returnSomething
The matcher receive a string containing ' not'
if the matcher was passed to shouldnt
or expect(...).not.to
.
If an exception is raised during the matcher execution, the example will be marked as errored
instead of failure
.
You can create parameterizable matcher by calling the takes
function in the matcher definition block.
spectacular.matcher 'parameterizableMatcher', ->
takes 'value1', 'value2'
match -> @value1 and @value2
description -> 'parameterizableMatcher description'
failureMessageForShould -> 'parameterizableMatcher message'
# Usage:
it -> should parameterizableMatcher(value1, value2)
The parameters defined with takes are then stored in the matcher instance with the provided names. The takes
function accept a slat argument such as values...
. In that case, the splat must be the sole argument.
It's possible to run code on the initialization of a matcher:
spectacular.matcher 'matcherWithInit', ->
init -> # do some setup such creating composed objects
match (actual) -> @composedObject.match actual
description -> 'matcher with init description'
failureMessageForShould -> 'matcher with init message'
# Usage:
it -> should matcherWithInit(value1, value2)
You can also add chaining methods with the chain
function:
spectacular.matcher 'chainableMatcher', ->
takes 'value1'
chain 'with', (@value2) ->
match -> @value1 and @value2
description -> 'chainableMatcher description'
failureMessageForShould -> 'chainableMatcher message'
# Usage:
it -> should chainableMatcher(value1).with(value2)
Asynchronous Matchers
Matchers can be asynchronous, in that case they should return a promise instead of a boolean value. The default timeout for asynchronous matchers is 5000ms, it can be changed by setting the timeout
in the matcher block.
spectacular.matcher 'asyncMatcher', ->
timeout 1000
match (actual, notText) ->
promise = new spectacular.Promise
setTimeout (-> promise.resolve actual isnt null), 100
promise
description -> 'should match asynchronously'
failureMessageForShould -> 'Expected to match asynchronously'
If the promise is rejected, the example is marked as errored
.
Fixtures Handlers
Spectacular support by default 3 fixtures format: json
, html
and dom
.
However you can quickly extend Spectacular with new fixtures handlers using the registerFixtureHandler
:
registerFixtureHandler 'ext', (content) ->
# do something with the content
The value returned by the handler block will be used as the fixture in specs.