baconjs / bacon.matchers

Matchers API for Bacon.js
MIT License
21 stars 6 forks source link

Working on matchers #1

Closed Lonelind closed 10 years ago

Lonelind commented 11 years ago

Not an issue as it is. Just suggestion and following question.

While working with bacon.matchers I thought, that it is useful to return original Bacon.Observable instance if test passed (for example, for something like this:

Bacon.constant(2).equals(2).toProperty()

). Just for compatibility. So I need to know, how can I handle errors and test fails here.

So, if I have

Bacon.Observable::equals = (y) ->
  @map (x) =>
    if x is y
      y
    else
      #what to place here?

In comment, there is some kind of result that I need to return if test fails. And to be handled in chain. What should I do here or what you could recommend?

raimohanska commented 11 years ago

In my opinion, there are two ways to use matchers:

1) filter by matcher:

var result = stream.where.equal(1)

stream 1--2--3--1--2--3
       |         |
result 1         1

2) map to boolean by matcher

var result = stream.is.equal(1)

stream 1--2--3--1--2--3
       |  |  |  |  |  |
result t--f--f--t--f--f

(t=true, f=false)

Both are probably useful, but I'm not yet quite sure if where.equal and is.equal are the best way to distinguish the two cases.

raimohanska commented 11 years ago

By the way, it would make sense to find out whether some of the existing matcher libs (Chai at least) could be "lifted" to streams and properties.

Lonelind commented 11 years ago

Okay, got it =) And almost done on equal.

Another question. If you have any suggestions to how to use where and is in chain without ()?

raimohanska commented 11 years ago

That would require the "where" and "is" objects to be created in such a way that they know their parent Observable. So, they can't be just added to the prototype. I guess that would require some kind of a hook in the Observable class itself.

Lonelind commented 11 years ago

Exactly. Just what I thought about. So, this is something like that:

class Observable
  #...
  where : 
    self: @

  is :
    self: @

Or add them in constructor.

raimohanska commented 11 years ago

We should not add bacon-matchers specific stuff to bacon.js. Instead a more generic way to bind extra functionality to Observables. Take inspiration from JQuery plugins, maybe?

raimohanska commented 11 years ago

Maybe

Bacon.Observable.addPlugin ->
  this.is = blah

Would be simple and generic enuf.

raimohanska commented 11 years ago

Accidental close;)

raimohanska commented 11 years ago

Otoh, not sure if its really worth the effort and runtime penalty just to save a pair of parentheses...

Lonelind commented 11 years ago

I think, we can use names such as isEqual and whereEqual for now. So in future, when plugin feature is ready, we'll rename them properly. But today functionality is priority, I think.

Also, I need to go deeper in Bacon.js knowledge. =)

raimohanska commented 11 years ago

Yeah, why not. Or do is().equal() and where().equal(). That wont require a change in baconjs and would promote re-use.

-juha-

On 25.3.2013, at 17.02, Alexander Lonelind notifications@github.com wrote:

I think, we can use names such as isEqual and whereEqual for now. So in future, when plugin feature is ready, we'll rename them properly. But today functionality is priority, I think.

Also, I need to go deeper in Bacon.js knowledge. =)

— Reply to this email directly or view it on GitHub.

wolfflow commented 11 years ago

This is possible, but not old IE(6-8)-compliant (IE9+ is ok though): https://gist.github.com/wolfflow/5245478

wolfflow commented 11 years ago

Generally, there are two ways to provide such chainable syntax. Former is chai.js way, Object.setProperty, not compatible with legacy IE 6-8. The latter, Jasmine matchers, where 'is', 'not' and others are actually instantiated, similar to decorator pattern is not so obvious, but seems to be compatible with almost all browsers.