-
Notifications
You must be signed in to change notification settings - Fork 26
Conversation
Ta, will have a look at this tomorrow. |
FYI I've sent @BenSayers a PR (BenSayers#1) which converts this branch to use Browserify, based on the work from my previous PR. My motivation here is to make supporting both Node and the browser simpler in the long run. |
Ok, whose should I merge first then?! |
Looks like there's some contention around the size of the compiled browser output in my version. My pull request shouldn't hold this one up, if this one is deemed suitable. |
Ok, in the right place now. When verification fails, is there a way to fail the test in an asynchronous world? In the example, if I take out the code that verifies that the response returned by the mock service is right, but make a wrong call to the mock service, the test should still fail, but it doesn't.
|
Hi Ben, just to summarise, I'm happy to merge this when we can work out a way to raise an error when verification fails. Thanks for your work on this. |
@bethesque I mistakenly thought if you give an error to jasmine's done callback it will fail the test, I have updated the tests and they fail when expected now. However upon reflection of this change I'm not happy with the way the error handling in the async world turned out. In the clean and setup stages of running the tests we don't have a way of communicating failure to the tests, so in this case I just throw the error. This is not a good thing to do as this is asynchronous code and we are in a new call stack so there is no clean way for the test to catch this and makes it hard to test the error handling. In the verify and write stages of running the tests we have the I'm thinking we need to change the way errors are communicated back to the tests, but am not clear on the best way forward. Some possible solutions I have in mind right now are:
Thoughts? I'm open to better ways of dealing with this if you think of any. |
@@ -14,7 +14,7 @@ | |||
"quotmark": "single", | |||
"undef": true, | |||
"unused": true, | |||
"strict": true, | |||
"strict": false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way we can be strict again?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are still using strict mode - it appears at the top of the dist file. I removed it from the jshint rules because it was insisting we put it at the top of every file in src.
I wish I had some better ideas, but this is not a style of coding that I'm very familiar with. |
Promises might be a good way to solve this. They would play nicely with something like jasmine-as-promised. |
I'd rather not couple this library to jasmine, that seems like the job of something built on top of this if it turns out to be useful. @markdalgleish how would you involve promise in the mix? I'm imagining you'd change the
This would look very similar if you changed the signature of run to accept two functions, one being the test and another being a finished callback.
The approach used by the jasmine-as-promised plugin is broken by the async api changes introduced in jasmine 2. Right now I'm leaning toward adding a |
@bethesque @markdalgleish have a look at the latest commit and let me know what you think. |
c51fb58
to
a28dd87
Compare
@bethesque just rebased onto the latest master. Anything else you'd like done before accepting this PR? On a random note, it would be good if the pact mock server exposed a healthcheck url that we can call to determine when it is ready to receive requests. I had to put a timeout in to hold back the tests from running when the server is not ready, I'd like it to be less brittle. |
I was about to say, it does have a healthcheck URL, I added it the other day, but then I checked the code, and I realised it must be sitting on my home laptop, uncommitted. I will chase that up. I'm still not entirely happy with the way this is working. I think the two step process will be confusing to people, and they'll not realise why they have to do the That |
Regarding the healthcheck endpoint - I have released pact-mock_service gem 0.2.4. If you hit the root URL |
@bethesque I'm not a fan of coupling this implementation to a specific testing language. The reasons behind this are:
What if we moved the fail test code into the The test would look like this:
|
I like that much better. Do you think it's more or less confusing to do this: helloProvider.run(function(runComplete) {
expect(client.sayHello()).toEqual("Hello");
runComplete(done);
}); |
The problem with having the done callback passed back inside the run callback is we are not able to get a reference to it when things go wrong in the steps prior to executing the run callback. This means we need to execute the run callback even though we know the pact mock server is not setup properly because without it we can't stop the test. This may result in a confusing failure because along with the error we generate there will be others genetated by the run callback. Worst case the run callback throws an exception and we never get the done callback at all, and the test fails with a timeout error. To allow us to fail cleanly we need a reference to the done callback directly. |
Right, that makes sense. How do we fail it at that stage then? With the |
In the before we pass in a function that accepts an error argument and will fail the test if it has a value. So if we have an error early in the mock setup stages we will call this function handing it the error to fail the test then call the done callback to end the test. |
|
||
if (Pact.IsNodeJs) { | ||
module.exports = Pact; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I merge in this PR https://github.com/DiUS/pact-consumer-js-dsl/pull/27/files, I believe we won't need this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That PR is based upon the node module xmlhttprequest
which we discussed a while back.
I think @markdalgleish has a nicer solution for making the differences between node and the browser more transparent using browserify, which gives us a dependency management solution as well.
But to be honest I'd like to focus on getting this change through before going through a refactoring exercise to clean up the nodejs checks. The length of time it's taking to get this PR approved is hurting my ability to get Pact widely adopted at my company.
If I make the changes discussed above are there any other concerns which will prevent this getting approved?
I think that's it. I really appreciate your work on this. |
Let me know when it's ready to merge, as I don't get any alerts when there's a new commit. |
…h latest details on how to run the project
…ack to the tests in a async friendly way
… execute too soon.
…t to be set in a beforeEach
a28dd87
to
e71bc02
Compare
@bethesque should be good to merge now |
Thanks. I'll look at it as soon as I have a moment. Once it's merged, there's a few simplifications we can make. The mock service now has a PUT /interactions, which will get rid of all the callbacks to set up the interactions sequentially, and there's now a 'pact-mock-service start' and 'pact-mock-service stop' task. The start task will block until the port is ready, so we can remove the 'wait for' stuff. |
This is looking good. Failing in all the right places when I deliberately mess up the tests. |
Ok, I've merged this in, thanks for your awesome work Ben. There's one thing that I'm considering - is it confusing or consistent to have a "done" function in the mock service, as well as in Jasmine? What do you think of "verify"? beforeEach(function() {
client = new ProviderClient('http://localhost:1234');
helloProvider = MockService.create({
consumer: 'Hello Consumer',
provider: 'Hello Provider',
port: 1234,
verify: function (error) {
expect(error).toBe(null);
}
});
}); |
I have no objections to renaming the function to A story to add to the backlog should be to add api documentation so we can explain the purpose of this function clearly. I've had success using jsdoc-to-markdown for automatically generating the docs from the source. |
Good point. Firstly, we should add an explanation to the README. |
Summary of the changes I made:
I've never used gulp before so I may not have done things in the "gulp" way. I also had a lot of merge conflicts when rebasing against master so please check I didn't blow away anything accidentally.