Jasmine shares questions about coffeescript issues

I am trying to dry some jasmine tests by extracting common examples.

@sharedExamplesForThing = (thing) -> beforeEach -> @thingy = new thing it "is neat", -> expect(@thingy.neat).toBeTruthy() describe "widget with shared behavior", -> sharedExamplesForThing(-> new Widget) 

This works well when everything is defined in one file. The problems I encounter arise when I try to move sharedExamples to a separate file. I get Can't find variable: sharedExamplesForThing ...

Therefore, in the interest of debugging, I tried the following:

 describe "widget with shared behavior", -> it "is acting like a meany", -> console.log sharedExamplesForThing expect(false).toBeTruthy() sharedExamplesForThing(-> new Widget) 

In the is acting like a meany log shows sharedExamplesForThing as [Function] , but I still get Can't find variable outside it . I feel that this may have something to do with a problem that is not related to my current experience, but I may be completely wrong. What am I missing here?

(using rails, jasminerice, guard-jasmine)

+6
source share
3 answers

I found the snippet on common examples from thinkbot really useful.

I implemented it in coffeescript as follows:

1) In some auxiliary file that is loaded before all specification files:

 window.FooSpec = sharedExamples: {} window.itShouldBehaveLike = (-> exampleName = _.first(arguments) exampleArguments = _.select(_.rest(arguments), ((arg) => return !_.isFunction(arg))) innerBlock = _.detect(arguments, ((arg) => return _.isFunction(arg))) exampleGroup = FooSpec.sharedExamples[exampleName] if(exampleGroup) return describe(exampleName, (-> exampleGroup.apply(this, exampleArguments) if(innerBlock) then innerBlock() ) ) else return it("cannot find shared behavior: '" + exampleName + "'", (-> expect(false).toEqual(true) ) ) ) 

2) For my specifications:

(a) I can determine the general behavior:

 FooSpec.sharedExamples["had a good day"] = (-> it "finds good code examples", -> expect(this.thoughtbot_spy).toHaveBeenCalled() ) 

(b) And use it somewhere in some specification like:

 itShouldBehaveLike("had a good day") 

(Note: I assume that the specification defined this.thoughtbot_spy respectively before the specified line)

+2
source

When you assign a top-level member variable in CoffeeScript, it is assigned as a property of the global object ( window in the browser). Thus, it generates the following JavaScript:

 window.sharedExamplesForThing = ...; 

This means that you can reference it outside the file as window.sharedExamplesForThing or just sharedExamplesForThing . So, what you are doing should work, assuming the general example file has been loaded before the specification file. I think the problem that you are facing is that the specification file is loaded first (since the function descriptions are started when the file is downloaded, while the functions are started after all the files are downloaded). Therefore, you may need to adjust the boot order, you can try to place common example files in the support directory, and then request it first.

Instead of assigning variables directly to the window object, it might be better to set up a namespace to export your shared variables (so that you don't clutter up the global object):

 window.MyNamespace = {} MyNamespace.sharedExamplesForThing = ... 

Then in your spec file you can refer to it as MyNamespace.sharedExamplesForThing .

It is useful for me to look at the generated JavaScript to try to understand how CoffeeScript exports variables between files.

+1
source

Here on my blog I wrote about how best to use common examples. Hope this helps.

http://pivotallabs.com/drying-up-jasmine-specs-with-shared-behavior/

0
source

All Articles