Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce support for matchers: #89

Merged
merged 5 commits into from
Feb 6, 2013
Merged

Introduce support for matchers: #89

merged 5 commits into from
Feb 6, 2013

Conversation

horkhe
Copy link
Contributor

@horkhe horkhe commented Nov 9, 2012

This pull introduces support for matchers in both expectation creation and history digging functions.

Here is an example how an expectation can be created using matchers:

%% When
meck:expect(Mod, f, [{[1, meck:is(fun(X) -> X == 1 end)],           a},
                     {[1, meck:is(hamcrest_matchers:less_than(3))], b},
                     {['_', '_'],                                   c}]),
%% Then
?assertEqual(a, Mod:f(1, 1)),
?assertEqual(b, Mod:f(1, 2)),
?assertEqual(c, Mod:f(2, 2)).

Here is an example how can be checked if a function has been called during test using matchers:

?assertMatch(true, meck:called(Mod, test, ['_', meck:is(hamcrest_matchers:equal_to(2)), {'_', 3}, "four"]))

As you can see meck:is/1 can create a matcher from any single argument function or a hamcrest matcher. Matchers can be used instead of any expected argument.

@horkhe
Copy link
Contributor Author

horkhe commented Nov 12, 2012

@eproxus What do you think about that?

@horkhe
Copy link
Contributor Author

horkhe commented Nov 12, 2012

Oops, I made a faulty force push. So please hold on with accepting this pull request. Tomorrow I will fix that. Fortunately I have another clone of this repo at work.

@horkhe
Copy link
Contributor Author

horkhe commented Nov 13, 2012

Ok, I am done. Now this pull request brings fully fledged (To reflect that I renamed the pull request) support for matchers. The syntax is uniform on both expectation and verification side.

@eproxus
Copy link
Owner

eproxus commented Nov 13, 2012

Look at the size of that pull request... Will review as soon as I have time. 😃

@horkhe
Copy link
Contributor Author

horkhe commented Nov 13, 2012

It brings quite a feature. Besides it is not as big as the previous one :-)

@horkhe
Copy link
Contributor Author

horkhe commented Nov 13, 2012

@eproxus If you could comment on the suggested API now that would be helpful.

@horkhe
Copy link
Contributor Author

horkhe commented Nov 13, 2012

@eproxus off topic: for erlang projects you might wanna give a try to IntelliJ IDEA + Erlang plugin. It appeared just at the end of this August but the author is of the plugin is very active.

@eproxus
Copy link
Owner

eproxus commented Nov 19, 2012

  • In my opinion, too many modules. meck_matcher and meck_args_matcher could be merged to one for example.

  • Too many changes in one pull request for my taste. The passthrough/0 and func/1 ret specs should be a separate pull request.

  • It's too tied into Hamcrest itself. I'd like Hamcrest to be an optional dependency, not required. This means that some of the Meck API would understand Hamcrest matchers, but not depend on them.

    This pull request seems to wrap and hide Hamcrest inside Meck. I'd rather integrate with Hamcrest optionally.

@horkhe
Copy link
Contributor Author

horkhe commented Nov 19, 2012

  • different module for different entity. But if you insist I will merge these two.
  • Yep, I mixed different changes in one pull request, but that is mostly because it takes rather long time to review the changes so I keep adding them,
  • No it is not too tight, please take a closer look. the only module that knows about hamcrest is meck_matcher and all the rest operates with internal matcher representation. So hamcrest is only an option.

@horkhe
Copy link
Contributor Author

horkhe commented Nov 19, 2012

@eproxus by the way recently some changes to hamcrest where introduced so I will remove a couple of more lines of code from meck_matcher

@horkhe
Copy link
Contributor Author

horkhe commented Nov 19, 2012

And let's not split this pull request in pieces please for the latter changes depend on passthrough and func being a ret_spec

@eproxus
Copy link
Owner

eproxus commented Nov 19, 2012

Why do the later changes depend on passthrough/0 and func/1 at all? As I see it, those should te two completely unrelated changes.

@horkhe
Copy link
Contributor Author

horkhe commented Nov 19, 2012

Ok I will move them to another pull request. But thispull request puts ret_specs to a dedicated module so they would need to be accepted in order. First changes with passthrough a func and then this one

@eproxus
Copy link
Owner

eproxus commented Nov 19, 2012

Dependencies between pull requests are fine. I just don't want to pull in a lot of changes in one huge pull request. It's easier to review and discuss them if they are separated.

@horkhe
Copy link
Contributor Author

horkhe commented Nov 19, 2012

@eproxus I created another pull request for ret_spec part. Let's start from it first.

@eproxus
Copy link
Owner

eproxus commented Nov 19, 2012

@horkhe Sure, sound good!

@horkhe
Copy link
Contributor Author

horkhe commented Jan 3, 2013

It's too tied into Hamcrest itself. I'd like Hamcrest to be an optional dependency, not required. This means that some of the Meck API would understand Hamcrest matchers, but not depend on them. This pull request seems to wrap and hide Hamcrest inside Meck. I'd rather integrate with Hamcrest optionally.

Yes and no. Meck introduces its own abstraction for matchers that is meck_matcher. A meck_matcher instance can be created from a predicate function (that will probably be the most widely used case) or from a matcher of a supported 3rd party framework (at the moment only Hamcrest is supported). meck_matcher is the only piece of Meck code that knows about Hamcrest existence. But even though hamcrest per se is optional I put it as a dependency to the Meck rebar.config effectively forcing everybody who takes dependency on Meck pull Hamcrest as well. I admit that that was a bad idea. To resolve that I made two rebar configs: one external that takes no dependencies and will be used by Meck users; and internal test.config that is used by internal Makefile to build and test the Meck itself.

In my opinion, too many modules. meck_matcher and meck_args_matcher could be merged to one for example

Well as I already explained in one of my comments I create them not because I like a lot of modules :) but rather because I like to keep different abstractions separately. For example meck_matcher introduces a matcher abstraction - an entity that encapsulates some criteria and provides a way to verify if some value meets this criteria. Matchers can be created from predicate functions and matchers of supported frameworks. As for meck_args_matcher it is an abstraction that is used to represent an expectation clause arguments where individual parameter may be fully defined - a value, partially defined - a '_' pattern, or conditionally defined - a matcher. In the future the code that generates argument matching code for impostor module will move here. That is why I created all these modules. Yet again not because I have a fetish for large numbers :-).

So this is it. Please let me know what do you think.

And by the way, happy new year!!! :-)

@horkhe horkhe closed this Jan 3, 2013
@horkhe horkhe reopened this Jan 3, 2013
@horkhe
Copy link
Contributor Author

horkhe commented Jan 5, 2013

@eproxus Hi Adam, I left a reply to your comment, please review when you have time.

@@ -1112,7 +1133,8 @@ remote_setup() ->
{Node, meck_test_module}.

remote_teardown({Node, _Mod}) ->
ok = slave:stop(Node).
ok = slave:stop(Node),
ok = net_kernel:stop().
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just out of curiosity, why is this needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that running rebar eunit results in the following output:

  All 143 tests passed.
Cover analysis: /home/travis/builds/eproxus/meck/.eunit/index.html

Code Coverage:
meck                          : 96%
...
Total                         : 88%
ERROR: eunit failed while processing /home/travis/builds/eproxus/meck: {'EXIT',net_kernel_stop_failed}

This explicit net_kernel:stop() fixed that.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might it be this issue fixed in rebar already? https://github.com/basho/rebar/issues/286

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried the latest Rebar with this fix and saw that error anyway.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then please report that as a bug to the rebar project instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eproxus Do you want me to rollback this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... besides, it does seem like a problem on our side, for we do start net_kernel in this test but had not stopped it before I made this change.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, then it should definately be there. 😄

I also noticed that we should probably do {ok, _} = net_kernel:start([Myself, shortnames]), instead of just running it...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do that later or we will never get this pull request merged ;-). Are there any blocking issues left?

@eproxus
Copy link
Owner

eproxus commented Jan 7, 2013

Just a note, I'd prefer more, smaller commits with isolated, atomic changes. As it is now, it's a bit hard to follow the development and get an overview of how interdependent changes are. It's also okay with smaller pull request containing clean ups and other minor changes separately. They'll more likely be accepted faster in that case.

@horkhe
Copy link
Contributor Author

horkhe commented Jan 7, 2013

Yep. I did such a humangous pull request in an effort to push more changes to the upstream faster. It is obvious now that that was a biiiiiig mistake, for the effect was reverse. In the future I will do smaller commits/pull requests as you suggested.

@eproxus
Copy link
Owner

eproxus commented Jan 11, 2013

The code looks good. I also want to try out the API a bit manually before the final merge. Will let you know when it's done.

@horkhe
Copy link
Contributor Author

horkhe commented Jan 12, 2013

Glad to hear that :-)

@eproxus
Copy link
Owner

eproxus commented Jan 21, 2013

Seems that the dialyzer plt creation somehow sneaked into the build scripts, making them take longer than 30 secs on Travis CI. Can't see any dependencies on the dialyzer targets in the makefile though, any ideas?

@horkhe
Copy link
Contributor Author

horkhe commented Jan 21, 2013

Well, I made that on purpose to make sure that the code is checked by static analyzer on pull requests. But it seems that on R14 it takes too long to build PLT. As you can see R15 is much faster with this respect. So I should probably remove the dialyzer check from the build.

@horkhe
Copy link
Contributor Author

horkhe commented Jan 21, 2013

@eproxus Have you had a chance to give the API a try?

@eproxus
Copy link
Owner

eproxus commented Jan 21, 2013

Let's remove it for now then.

Yes, I'll merge as soon as the compilation problems are fixed and all travis builds passes. 👍

@horkhe
Copy link
Contributor Author

horkhe commented Jan 21, 2013

@eproxus Hey Adam, it seems I am finally done with that :)

@horkhe horkhe closed this Jan 28, 2013
@horkhe horkhe reopened this Jan 28, 2013
@horkhe
Copy link
Contributor Author

horkhe commented Jan 31, 2013

@eproxus could you please merge this. I have other changes coming.

eproxus added a commit that referenced this pull request Feb 6, 2013
Introduce support for matchers:
@eproxus eproxus merged commit 8bba380 into eproxus:develop Feb 6, 2013
@horkhe
Copy link
Contributor Author

horkhe commented Feb 6, 2013

Thanks a lot!

@eproxus
Copy link
Owner

eproxus commented Feb 6, 2013

Np. Forgot to check the build on Travis, but seems the GitHub hooks works now as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants