konacha - helper methods coffeescript - coffeescript

I'm trying to define a helper method in konacha in coffeescript, something like this
#expect_int_is_universal = (i) ->
expect(i).to.equal 42
describe '#test', ->
it 'checks if integer is 42', ->
#expect_int_is_universal(42)
Is it possible in konacha?
edit: error log here:
update: the fix is putting it inside a beforeEach block
beforeEach ->
#expect_int_is_universal = (i) ->
expect(i).to.equal 42
describe '#test', ->
it 'checks if integer is 42', ->
#expect_int_is_universal(42)

mu is too short hasn't successfully converted his comment as the answer, but i'll provide it here below:
# (AKA this) inside your it callback is not the same # as at the top level so you're defining expect_int_is_universal as a method on one object but trying to call it as a method on another object. Try without the #s. I don't know enough Konocha, Mocha, or Chai to say any more than that

Related

How to use set methods to initialize instance variables via constructor in coffeescript

I have a "class" in coffee script whose instance variables I want to initialize with instance methods that return a value via a callback, but it doesn't work as I had hoped:
EventEmitter = require('events').EventEmitter
class MyClass extends EventEmitter
constructor: ->
#datamember: setDatamember()
setDatamember: ->
someFunction (response) ->
#datamember = response
#emit 'init'
getDatamember: ->
return #datamember
----
myObj = new MyClass
myObj.on 'init', ->
console.log myObj.getDatamember
The result I get suggests that "this" in setDatamember is referring to something different from what "this" refers to in the object instance. If I explicitly call myObj.setDatamember, I get the expected result, but is there any way to call on a set method -- specifically one that sets the data member via a callback -- in the constructor? I've looked through the docs, as well as various other sources of coffeescript info (e.g. this one), and I haven't found anything that touches upon this.
Try using a fat arrow for the anonymous function:
setDatamember: ->
someFunction (response) =>
#datamember = response
#emit 'init'
Also, you'll need to call the correct function in the constructor:
constructor: ->
#setDatamember()
In general, avoid fat arrows on methods - the way Coffee-Script implements this does some bad things to memory usage. Also, it will rarely be necessary.
However, anonymous functions that refer to this will almost always need fat arrows. this is not held in closure like normal variables, and will only be set by binding (Function.prototype.bind) or by calling it as an object method (obj.myMethod() will set this to obj in myMethod).
Try using fat arrows on everything except the constructor:
class MyClass
constructor: ->
#setDatamember()
setDatamember: =>
someFunction (response) =>
#datamember = response
getDatamember: =>
return #datamember
However, you also look to have someFunction in there as an asynchronous function, so you'll never be able to just do
mc = new MyClass
console.log mc.datamember
Because that doesn't wait for someFunction to return before accessing mc.datamember.

Purpose of # symbol infront of functions [duplicate]

This question already has an answer here:
Static classes and methods in coffeescript
(1 answer)
Closed 8 years ago.
I cant understand exactly what # (this) does infront of class functions. I am using Spine framework, and I got a class Contact which extends Spine.model. I override the Spine methods for creating, deleting, fetching etc, and have them print on the console first like this:
create: ->
console.log('create')
super
destroy: ->
console.log("destroy")
super
Some of these methods will work the same if I add # infront, for example create, while others will not work without #, and others will not work with #. All the methods I override can be seen on the link above.
Is it possible to explain me the effect of # symbol infront of
functions, and why its causing this behaviour?
Answer from mu is too short :
You can define class methods by prefixing them with #:
class Box2DUtility
constructor: () ->
#drawWorld: (world, context) -> alert 'World drawn!
'
And then draw your world...
Box2DUtility.drawWorld()
Demo: http://jsfiddle.net/ambiguous/5yPh7/
And if you want your drawWorld to act like a constructor then you can say new # like this:
class Box2DUtility
constructor: (s) -> #s = s
m: () -> alert "instance method called: #{#s}"
#drawWorld: (s) -> new # s
Box2DUtility.drawWorld('pancakes').m()
Demo: http://jsfiddle.net/ambiguous/bjPds/1/

Run method with reference to it's static vars from a child class

I have a class Child which extends Test. I want to call a function from Test from Child.
I tried this:
class Test
constructor: ->
#i = 'hello world'
f1: -> console.log #i
f2: -> console.log 'hello'
class Child extends Test
run: ->
Test::f1()
hello = new Child()
hello.run()
When I call hello.run(), it calls Test.f1(), but the result is undefined. It's not setting the static variable #i before it's running Test.f1().
If I switch Test::f1() to Test::f2(), it gives me the correct result.
I need to know how should I make Test's constructor run when I create a new Child() so that #i is defined in Test when I run Test::f1() from Child.run().
Thanks! :D
Here's one way of doing it:
class Test
#i: 'hello world'
#f1: -> console.log #i
f2: -> console.log 'hello'
class Child extends Test
run: ->
Test.f1()
hello = new Child()
hello.run()
Notice, the i variable is static, so it doesn't make sense to set it in the constructor. Also, the f1 method is now static as well.
(I'm not an expert with CoffeeScript, so I'm not sure what the :: syntax is needed for.)
The constructor is being run when you create a new instance of Child. The problem is the way that you're invoking f1.
You don't want to say Test::f1(). You can just say #f1(), since Child is a subclass of Test. These are different in a very important way: Test::f1() does not set this, so when that function requests this.i, it finds only undefined, because this is set to Window (or something ridiculous like that in the browser, not sure if you're running this in Node). Saying #f1() is the same as saying Test::f1.call(this). This is one of the nice things that CoffeeScript's class system lets you do.
Finally, a pedantic note: there are no static variables in the code you've written. i, as you've written it, is an instance variable. Static variables look like this:
class Test
#staticVar = 1234
Or like this:
class Test
# ...
Test.staticVar = 1234
Instance variables look like this:
class Test
fn: ->
#instanceVar = 1234
Or like this:
test = new Test()
test.instanceVar = 1234
Or even like this (for the default value of an instance variable shared among all instances):
Test::instanceVar = 1234
In a similar vein:
When I call hello.run(), it calls Test.f1(), but the result is undefined. It's not setting the static variable #i before it's running Test.f1().
You're never calling Test.f1(); you're calling Test::f1(), which is very different. In the code you've written, there is no Test.f1, only Test.prototype.f1.

Coffeescript translation

If I have this javascript:
function I_did_something(){
this.test.assertExists('#selector', 'exists');
}
casper.then(I_did_something);
The problem is that casper is using call to call the then method meaning that I cannot do something like this:
#I_did_something = ->
#assertExists('#selector', 'exists')
casper.then #I_did_something
Because this does not refer to the global object.
Can anyone suggest how I would translate this into coffeescript without using the window object preferably?
You can use a fat arrow (=>) to bind the function to the current this:
#I_did_something = =>
#assertExists('#selector', 'exists')
That has a similar effect to:
that = #
#I_did_something = ->
that.assertExists('#selector', 'exists')
and I think that's what you're after.

Why must my coffeescript method belong to the class?

I come from a C#/Java background which use a class based OO system and I don't get the JavaScript/CoffeeScript prototype OO system yet. I've written a CoffeeScript class below which allows me to display names for contacts according to a system-side preference. I can only get the class to work by making the joinNonEmpty(stringList, joinText) method belong to the prototype and calling it the way I would call a static method in Java/C# land.
Is there a way I can make this method call using this.joinNonEmpty(...)?
Can you shed some light on why I can reference the firstLastRender, lastFirstRender and firstOrNickThenLast methods in the constructor with this. but it doesn't work from those methods when calling the joinNonEmpty helper?
Does this have something to do with how I'm locating the appropriate method via the preference map?
prefs = displayNameFormat: "FirstOrNickThenLast"
class DisplayNameRenderer
constructor: ->
#prefToRenderMap =
FirstLast: this.firstLastRender
LastFirst: this.lastFirstRender
FirstOrNickThenLast: this.firstOrNickThenLast
# Why does this method have to be static (a class method)?
#joinNonEmpty: (stringList, joinText) ->
nonEmptyStrings = []
for s in stringList
nonEmptyStrings.push(s) if s isnt null and s isnt ""
nonEmptyStrings.join(joinText)
firstLastRender: (contact) ->
# TypeError: Object expected.
joinNonEmpty([contact.firstName, contact.lastName], ' ')
lastFirstRender: (contact) ->
# TypeError: Object doesn't support this method or property
this.joinNonEmpty([contact.lastName, contact.firstName], ', ')
firstOrNickThenLast: (contact) ->
# Works correctly.
DisplayNameRenderer.joinNonEmpty([(if contact.nickname isnt null and contact.nickname isnt "" then contact.nickname else contact.firstName), contact.lastName], ' ')
render: (contact) ->
#prefToRenderMap[prefs.displayNameFormat](contact)
contact = firstName: "Jonathan", nickname: "Jonny", lastName: "Appleseed"
dnr = new DisplayNameRenderer()
# => "Jonny Appleseed"
console.log dnr.render(contact)
Thanks for taking the time to answer.
this (AKA #) is determined when the function is called (with exceptions as below). So when you do this:
#prefToRenderMap =
FirstLast: this.firstLastRender
LastFirst: this.lastFirstRender
FirstOrNickThenLast: this.firstOrNickThenLast
You're storing unbound references to the three functions in the #prefToRenderMap instance variable and #prefToRenderMap is itself an object. Then you try to call the methods in your DisplayNameRenderer instance like this:
#prefToRenderMap[prefs.displayNameFormat](contact)
and everything falls apart because the methods are called in the wrong context and # isn't what they're expecting it to be. If prefs is 'FirstOrNickThenLast' then you're effectively doing this:
#prefToRenderMap.FirstOrNickThenLast(contact)
and # (AKA this) will be #prefToRenderMap inside the firstOrNickThenLast method. But, of course, #prefToRenderMap doesn't have any of the methods that you're trying to call so you get various errors.
One solution is to use the fat arrow (=>) to define the methods:
The fat arrow => can be used to both define a function, and to bind it to the current value of this, right on the spot.
So you could have things like this:
joinNonEmpty: (stringList, joinText) ->
#...
firstLastRender: (contact) =>
#joinNonEmpty([contact.firstName, contact.lastName], ' ')
and everything will work out. Here's a stripped down demo that will also show you your this problem:
http://jsfiddle.net/ambiguous/RAPJw/1/
You could also avoid this problem by referring to the methods by their names. Given a method name in a string, m = 'some_method', you can call that method like this o[m]() in both JavaScript and CoffeeScript and the result will be the same as if you said o.some_method(). A better structure would look more like this:
class DisplayNameRenderer
constructor: ->
#prefToRenderMap =
FirstOrNickThenLast: 'firstOrNickThenLast'
joinNonEmpty: (stringList, joinText) ->
#...
firstOrNickThenLast: (contact) ->
#joinNonEmpty([(if contact.nickname isnt null and contact.nickname isnt "" then contact.nickname else contact.firstName), contact.lastName], ' ')
render: (contact) ->
#[#prefToRenderMap['FirstOrNickThenLast']](contact)
Note the change to the structure of #prefToRenderMap and how it is used in render. And a demo of this approach: http://jsfiddle.net/ambiguous/DFYwu/
As an aside, instead of saying ClassName.class_method() inside an instance method, you can use the constructor property instead: #constructor.class_method(). Also, you usually say #method() or #property rather than this.method() and this.property in CoffeeScript.