Skip to content
This repository has been archived by the owner on May 10, 2022. It is now read-only.

Allow the consumer DSL to be used from code running in a node context (rather than browser) #17

Closed
wants to merge 2 commits into from

Conversation

redbeard
Copy link

This required a couple of changes:

  • Fixed incorrect package.json 'main' property.
  • Added module export.
  • Added lazy dependency on xmlhttprequest module (allows access to XHR object from node code)

@bethesque
Copy link
Contributor

I'm not a JS expert in any way, so my apologies if this sounds stupid. We've just pulled out all the "require" stuff so that it can be used in a framework independent way. Would it not be better to do the require line if (!XMLHttpRequest) { var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; } in the calling code, and keep the dsl code completely framework agnostic?

…n int; Fixing code to account for both browser and node.
@bethesque
Copy link
Contributor

Which XMLHttpRequest is being required here? I didn't think Node had one?

I'm not actually sure if we want to make this change or not. @BenSayers is working modifying the code to work with Node in an async way. See #15

@BenSayers
Copy link
Contributor

@bethesque Christmas and New Years slowed me down a bit but I'm back working on it in my spare time now. Should be finished soon. If you are interested in the progress you can see it on my branch.

@bethesque
Copy link
Contributor

No worries. One thing to note is that the xhr.status is a string within a browser, but is an integer in Node. The code in master now does parseInt(xhr.status, 10) !== 200 to cover both bases.

@bethesque
Copy link
Contributor

Hey Ben, if the mock service doesn't start up because you're a numpty and you've forgotten to bundle install before you run the tests, the run-tests just finishes with a success status code. Do you know if there's a way to fail the tests if waitForServerToStart fails?

@bethesque
Copy link
Contributor

Something funny is up with the ordering of the requests. This is running the tests in the example directory.

I had to change the files in example/karma.conf.js to

    files: [
      'client.js',
      'client-spec.js',
      '../src/bootstrap.js',
      '../src/**/*.js'
    ],

Then I ran script/setup.sh and script/test.sh. As you can see from the logs, the interactions get cleared all at once at the start, then the registration and the executions are all mixed up. It looks like the tests are running in parallel, which won't work with the current implementation of the mock server.

I, [2015-01-09T10:38:18.155785 #93131]  INFO -- : Cleared interactions before example ""
I, [2015-01-09T10:38:18.197403 #93131]  INFO -- : Cleared interactions before example ""
I, [2015-01-09T10:38:18.201621 #93131]  INFO -- : Cleared interactions before example ""
I, [2015-01-09T10:38:18.207031 #93131]  INFO -- : Registered expected interaction GET /sayHello
D, [2015-01-09T10:38:18.207309 #93131] DEBUG -- : {
  "providerState": null,
  "description": "a request for hello",
  "request": {
    "method": "get",
    "path": "/sayHello"
  },
  "response": {
    "status": 200,
    "headers": {
      "Content-Type": "application/json"
    },
    "body": {
      "reply": "Hello"
    }
  }
}
I, [2015-01-09T10:38:18.213704 #93131]  INFO -- : Registered expected interaction GET /friends?age=30&children=Mary Jane&children=James
D, [2015-01-09T10:38:18.213955 #93131] DEBUG -- : {
  "providerState": null,
  "description": "a request friends",
  "request": {
    "method": "get",
    "path": "/friends",
    "query": {
      "age": "30",
      "children": [
        "Mary Jane",
        "James"
      ]
    },
    "headers": {
      "Accept": "application/json"
    }
  },
  "response": {
    "status": 200,
    "headers": {
      "Content-Type": "application/json"
    },
    "body": {
      "friends": [
        {
          "name": "Sue"
        }
      ]
    }
  }
}
I, [2015-01-09T10:38:18.219044 #93131]  INFO -- : Registered expected interaction PUT /unfriendMe
D, [2015-01-09T10:38:18.219178 #93131] DEBUG -- : {
  "providerState": null,
  "description": "a request to unfriend",
  "request": {
    "method": "put",
    "path": "/unfriendMe"
  },
  "response": {
    "status": 200,
    "headers": {
      "Content-Type": "application/json"
    },
    "body": {
      "reply": "Bye"
    }
  },
  "provider_state": "I am friends with Fred"
}
I, [2015-01-09T10:38:18.223505 #93131]  INFO -- : Received request GET /sayHello
D, [2015-01-09T10:38:18.223690 #93131] DEBUG -- : {
  "path": "/sayHello",
  "query": "",
  "method": "get",
  "headers": {
    "Host": "localhost:1234",
    "Connection": "keep-alive",
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36",
    "Accept": "*/*",
    "Referer": "http://localhost:9876/context.html",
    "Accept-Encoding": "gzip, deflate, sdch",
    "Accept-Language": "en-US,en;q=0.8",
    "Version": "HTTP/1.1"
  }
}
I, [2015-01-09T10:38:18.223971 #93131]  INFO -- : Found matching response for GET /sayHello
D, [2015-01-09T10:38:18.224082 #93131] DEBUG -- : {
  "status": 200,
  "headers": {
    "Content-Type": "application/json"
  },
  "body": {
    "reply": "Hello"
  }
}
W, [2015-01-09T10:38:18.231852 #93131]  WARN -- : Verifying - actual interactions do not match expected interactions for example "". 
Missing requests:
    GET /friends?age=30&children=Mary Jane&children=James
    PUT /unfriendMe


W, [2015-01-09T10:38:18.231949 #93131]  WARN -- : Missing requests:
    GET /friends?age=30&children=Mary Jane&children=James
    PUT /unfriendMe


I, [2015-01-09T10:38:18.235510 #93131]  INFO -- : Received request GET /friends?age=30&children=Mary%20Jane&children=James
D, [2015-01-09T10:38:18.235664 #93131] DEBUG -- : {
  "path": "/friends",
  "query": "age=30&children=Mary%20Jane&children=James",
  "method": "get",
  "headers": {
    "Host": "localhost:1234",
    "Connection": "keep-alive",
    "Accept": "application/json",
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36",
    "Referer": "http://localhost:9876/context.html",
    "Accept-Encoding": "gzip, deflate, sdch",
    "Accept-Language": "en-US,en;q=0.8",
    "Version": "HTTP/1.1"
  }
}
I, [2015-01-09T10:38:18.236125 #93131]  INFO -- : Found matching response for GET /friends?age=30&children=Mary Jane&children=James
D, [2015-01-09T10:38:18.236222 #93131] DEBUG -- : {
  "status": 200,
  "headers": {
    "Content-Type": "application/json"
  },
  "body": {
    "friends": [
      {
        "name": "Sue"
      }
    ]
  }
}
W, [2015-01-09T10:38:18.243576 #93131]  WARN -- : Verifying - actual interactions do not match expected interactions for example "". 
Missing requests:
    PUT /unfriendMe


W, [2015-01-09T10:38:18.243665 #93131]  WARN -- : Missing requests:
    PUT /unfriendMe


I, [2015-01-09T10:38:18.248980 #93131]  INFO -- : Received request PUT /unfriendMe
D, [2015-01-09T10:38:18.249325 #93131] DEBUG -- : {
  "path": "/unfriendMe",
  "query": "",
  "method": "put",
  "headers": {
    "Host": "localhost:1234",
    "Connection": "keep-alive",
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36",
    "Origin": "http://localhost:9876",
    "Accept": "*/*",
    "Referer": "http://localhost:9876/context.html",
    "Accept-Encoding": "gzip, deflate, sdch",
    "Accept-Language": "en-US,en;q=0.8",
    "Version": "HTTP/1.1"
  }
}
I, [2015-01-09T10:38:18.249669 #93131]  INFO -- : Found matching response for PUT /unfriendMe
D, [2015-01-09T10:38:18.249830 #93131] DEBUG -- : {
  "status": 200,
  "headers": {
    "Content-Type": "application/json"
  },
  "body": {
    "reply": "Bye"
  }
}
I, [2015-01-09T10:38:18.257649 #93131]  INFO -- : Verifying - interactions matched for example ""


@bethesque
Copy link
Contributor

Ok, worked it out, I needed to make the tests do the 'done' callback. They can't be synchronous any more.

@bethesque
Copy link
Contributor

I'm thinking, it's quite tedius to do a DELETE and a POST for each interaction. It would be much simpler to do a a PUT /interactions and do the whole thing in one go. I'll look into that if I have the time.

@bethesque
Copy link
Contributor

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.

describe("when there are no friends", function () {
        it("returns an error message", function (jasmineDone) {
          //Add interaction
          helloProvider
            .given("I have no friends")
            .uponReceiving("a request to unfriend")
            .withRequest("put", "/unfriendMe2")
            .willRespondWith(404);

          //Run the tests
          helloProvider.run(function(pactDone) {

            function success(message) {
              //The success callback should *not* be invoked!
              // expect(true).toEqual(false);
              pactDone(jasmineDone);
            }

            function error(message) {
              //The error callback *should* be invoked
              // expect(message).toEqual("No friends :(")
              pactDone(jasmineDone);
            }

            client.unfriendMe(success, error);

          });
        });
      });

@BenSayers
Copy link
Contributor

@bethesque are these comments intended for my nodejs pull request?

@bethesque
Copy link
Contributor

Ha, yes. I just realised I put them on the wrong one. Will repost. I'm going to close this PR, seeing as yours supersedes it.

@bethesque bethesque closed this Jan 9, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants