dynamically evaluated expectations in matchers

461 views
Skip to first unread message

jmilkiewicz

unread,
Jun 18, 2011, 7:03:02 AM6/18/11
to angular
Hi

I am using angular e2e test runner and I must admit it really makes
its job. The one thing (till now) what is missing for me is the
ability to dynamically evaluate expectations in matchers. If you take
a look at https://github.com/angular/angular.js/blob/master/src/scenario/matchers.js
you could see that argument named "expected" is 'eagerly' evaluated.
Unfortunately in the majority of my tests expectations are not known
in advance.
As an example pls take a look at following test:
it('should add item', function() {
numberOfItemsBefore = repeater('div[id="items"] > ul > li', 'item in
items').count();
...
addAnItem();
...
numberOfItemsAfter = repeater('div[id="items"] > ul > li', 'item in
items').count();
expect(numberOfItemsAfter).toEqual(numberOfItemsBefore.value + 1);
});

Unfortunately this test will now work since at the time of recording
expectations the variable numberOfItemsBefore.value is undefined
(since numberOfItemsBefore is not 'fulfilled future').
As a workaround I defined my own matcher that corresponds to angular
matcher but expected parameter is treated as a function to be
executed. My own "toEqual" matcher is like:
angular.scenario.matcher('toEqualWithFunctionReturn',
function(expected) {
return angular.equals(this.actual, expected());
});

Alternatively I could modify existing angular matchers by adding
checking if expected argument is a function or not and then act
appropriately.

Don't you think that these kind of matchers (i mean these that take
function as an argument) should be incorporated into angular itself?

Vojta Jina

unread,
Jun 18, 2011, 11:27:34 AM6/18/11
to ang...@googlegroups.com, esp...@google.com
Hey,

you can achieve this like that:
  it('async expectation', function() {
    browser().navigateTo('index.html');
    var count = element('ul#test li').count();

    this.addFuture('any title', function(done) {
      expect(element('ul#suck li').count()).toEqual(count.value);
      done();
    });
  });

I know it's not nice, but you can write your helper for that...

Elliott's opinion on that would be nice...
V.

jmilkiewicz

unread,
Jun 18, 2011, 6:13:31 PM6/18/11
to angular
Hi

Right. It's not nice at all.

regards
Jakub
On Jun 18, 5:27 pm, Vojta Jina <vojta.j...@gmail.com> wrote:
> Hey,
>
> you can achieve this like that:
> *  it('async expectation', function() {*
> *    browser().navigateTo('index.html');*
> *    var count = element('ul#test li').count();*
> *
> *
> *    this.addFuture('any title', function(done) {*
> *      expect(element('ul#suck li').count()).toEqual(count.value);*
> *      done();*
> *    });*
> *  });*
> *
> *
> I know it's not nice, but you can write your helper for that...
>
> Elliott's opinion on that would be nice...
> V.
>
>
>
>
>
>
>
> On Saturday, June 18, 2011 1:03:02 PM UTC+2, jmilkiewicz wrote:
>
> > Hi
>
> > I am using angular e2e test runner and I must admit it really makes
> > its job. The one thing (till now) what is missing for me is the
> > ability to dynamically evaluate expectations in matchers. If you take
> > a look at
> >https://github.com/angular/angular.js/blob/master/src/scenario/matche...

Elliott Sprehn

unread,
Jun 22, 2011, 7:14:16 PM6/22/11
to ang...@googlegroups.com
On Sat, Jun 18, 2011 at 8:27 AM, Vojta Jina <vojta...@gmail.com> wrote:
Hey,

you can achieve this like that:
  it('async expectation', function() {
    browser().navigateTo('index.html');
    var count = element('ul#test li').count();

    this.addFuture('any title', function(done) {
      expect(element('ul#suck li').count()).toEqual(count.value);
      done();
    });
  });


I don't think this works. You can't add futures during a running test. expect() just adds a future to the queue for the current spec, but that'd during the build phase, not the run phase.

The issue you're trying to solve has come up a few times. We need to come up with a way to have DSL statements in general allow future values as arguments and wait for their values to resolve.

This is what I'm thinking:

angular.scenario.dsl('example', function() {
  return function(a, b) {
    this.addFuture('name of the future', [a, b], function(a, b, done) {
       // a and b are resolved now.
    });
  };
});

-Elliott 

Vojta Jina

unread,
Jun 23, 2011, 9:01:30 AM6/23/11
to ang...@googlegroups.com
I agree, it's quit a common issue, so we need to come up with some DSL for that, so here is issue: https://github.com/angular/angular.js/issues/429
My previous code example is not nice, but it works...
V.

fineline

unread,
Mar 22, 2012, 4:50:37 AM3/22/12
to ang...@googlegroups.com
I'm now facing the same problem. Have there been any more thoughts on this over the past few months?

Thanks
Tim

fineline

unread,
Mar 23, 2012, 5:37:07 AM3/23/12
to ang...@googlegroups.com
Regarding Elliot's earlier reply - it does seem that I can add futures as part of a test, similar to the example on:


But I definitely agree it would be good to be able to pass a future as argument to a matcher.

Thanks
Tim

Vojta Jína

unread,
Mar 23, 2012, 1:12:20 PM3/23/12
to ang...@googlegroups.com
In general, we haven't touched scenario runner for a loooong time and
yep, it needs some love.
I hope we can address most of these issues post v10.

In meantime, feel free to send a pull request - this feature should be
easy to implement.

V.

> --
> You received this message because you are subscribed to the Google Groups
> "AngularJS" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/angular/-/gSGoHcLBX4MJ.
> To post to this group, send email to ang...@googlegroups.com.
> To unsubscribe from this group, send email to
> angular+u...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/angular?hl=en.

Kai Groner

unread,
Mar 24, 2012, 4:44:53 PM3/24/12
to ang...@googlegroups.com
I wrote something that would adds a .eventually permutation of other matchers (similar to .not).

https://gist.github.com/2187487

It worked for my project at the time, but it's use of .waitFor() may not be ideal.



Kai

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.

Vojta Jína

unread,
Mar 25, 2012, 11:34:58 PM3/25/12
to ang...@googlegroups.com
Nice work Kai, that's very helpful for testing stuff with q promises...

But note, that Angular's scenario runner does not uses jasmine. It has
similar API, but it's not jasmine.

V.

Kai Groner

unread,
Mar 26, 2012, 1:01:42 AM3/26/12
to ang...@googlegroups.com
That's a good point!  I think I need to have a closer look at the scenario runner.
Reply all
Reply to author
Forward
0 new messages