Comparing version 0.1.2 to 1.0.0-rc
124
package.json
{ | ||
"name": "pact", | ||
"description": "Vows macros for easy HTTP server testing.", | ||
"keywords" : [ | ||
"Vows", | ||
"HTTP", | ||
"test" | ||
"version": "1.0.0-rc", | ||
"description": "Pact for all things Javascript", | ||
"main": "./dist/pact.js", | ||
"scripts": { | ||
"coverage": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js", | ||
"docs": "./node_modules/.bin/jsdoc -r ./src --readme ./README.md -P ./package.json -d ./docs", | ||
"dist": "npm run dist:node && npm run dist:web", | ||
"dist:web": "webpack --config ./config/webpack.web.config.js", | ||
"dist:node": "webpack --config ./config/webpack.node.config.js", | ||
"lint": "standard", | ||
"jscpd": "jscpd -p src -r json -o jscpd.json", | ||
"predist": "npm run lint && npm run jscpd", | ||
"postdist": "npm t", | ||
"test": "./node_modules/.bin/babel-node ./node_modules/.bin/isparta cover ./node_modules/.bin/_mocha -- ./test" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/pact-foundation/pact-js.git" | ||
}, | ||
"engines": { | ||
"node": ">=0.12" | ||
}, | ||
"keywords": [ | ||
"pact", | ||
"pact-js", | ||
"javascript", | ||
"contract testing", | ||
"testing", | ||
"consumer driven testing" | ||
], | ||
"version": "0.1.2", | ||
"author": "Reid Burke <me@reidburke.com> (http://reidburke.com/)", | ||
"contributors" : [ | ||
"Ryan Grove <ryan@wonko.com>" | ||
"author": "Beth Skurrie <beth@bethesque.com> (https://github.com/bethesque)", | ||
"contributors": [ | ||
{ | ||
"name": "Tarcio Saraiva", | ||
"email": "tarcio@gmail.com", | ||
"url": "http://twitter.com/tarciosaraiva" | ||
}, | ||
{ | ||
"name": "David Stanciu", | ||
"email": "davidstanciu29@gmail.com", | ||
"url": "https://github.com/dstanciu29" | ||
}, | ||
{ | ||
"name": "Michel Boudreau", | ||
"email": "michelboudreau@gmail.com", | ||
"url": "http://codinghitchhiker.com" | ||
}, | ||
{ | ||
"name": "Fu Ying", | ||
"email": "fu.ying.er@rea-group.com" | ||
}, | ||
{ | ||
"name": "Malinda Kapuruge", | ||
"email": "kaushalye@gmail.com" | ||
}, | ||
{ | ||
"name": "Ben Sayers", | ||
"email": "bpsayers@gmail.com" | ||
} | ||
], | ||
"main": "index", | ||
"directories": { | ||
"lib": "./lib" | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/pact-foundation/pact-js/issues" | ||
}, | ||
"dependencies" : {}, | ||
"engines": { | ||
"node": ">=0.2.5" | ||
"homepage": "http://docs.pact.io/documentation/javascript.html", | ||
"standard": { | ||
"parser": "babel-eslint", | ||
"ignore": [ | ||
"config/**", | ||
"test/**", | ||
"dist/**", | ||
"docs/**" | ||
] | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/reid/pact.git" | ||
"dependencies": { | ||
"lodash.find": "4.4.0", | ||
"lodash.isfunction": "3.0.8", | ||
"lodash.isnil": "4.0.0", | ||
"lodash.isundefined": "3.0.1", | ||
"lodash.omitby": "4.4.0", | ||
"mitm": "1.2.1" | ||
}, | ||
"licenses" : [ | ||
{ "type" : "BSD", "url" : "http://developer.yahoo.com/yui/license.html" } | ||
] | ||
"devDependencies": { | ||
"@pact-foundation/pact-node": "4.4.3", | ||
"babel-cli": "6.10.1", | ||
"babel-eslint": "6.1.0", | ||
"babel-loader": "6.2.4", | ||
"babel-preset-es2015": "6.9.0", | ||
"babel-register": "6.9.0", | ||
"bluebird": "3.4.1", | ||
"chai": "3.5.0", | ||
"chai-as-promised": "5.3.0", | ||
"coveralls": "2.11.9", | ||
"imports-loader": "0.6.5", | ||
"isparta": "4.0.0", | ||
"istanbul": "0.4.4", | ||
"jscpd": "0.6.2", | ||
"jsdoc": "3.4.0", | ||
"json-loader": "0.5.4", | ||
"mocha": "2.5.3", | ||
"nock": "8.0.0", | ||
"proxyquire": "1.7.9", | ||
"sinon": "1.17.4", | ||
"sinon-chai": "2.8.0", | ||
"standard": "7.1.2", | ||
"superagent": "2.0.0", | ||
"webpack": "1.13.1" | ||
} | ||
} |
288
README.md
@@ -1,91 +0,239 @@ | ||
# Pact | ||
# Pact JS | ||
[![Build Status](https://travis-ci.org/pact-foundation/pact-js.svg?branch=master)](https://travis-ci.org/pact-foundation/pact-js) | ||
[![Code Climate](https://codeclimate.com/github/pact-foundation/pact-js/badges/gpa.svg)](https://codeclimate.com/github/pact-foundation/pact-js) | ||
[![Coverage Status](https://coveralls.io/repos/github/pact-foundation/pact-js/badge.svg?branch=master)](https://coveralls.io/github/pact-foundation/pact-js?branch=master) | ||
[![Issue Count](https://codeclimate.com/github/pact-foundation/pact-js/badges/issue_count.svg)](https://codeclimate.com/github/pact-foundation/pact-js) | ||
[![npm](https://img.shields.io/github/license/pact-foundation/pact-js.svg?maxAge=2592000)](https://github.com/pact-foundation/pact-js/blob/master/LICENSE) | ||
A collection of [Vows][] macros for easy HTTP server testing. | ||
Implementation of the consumer driven contract library [pact](https://github.com/pact-foundation/pact-specification) for Javascript. | ||
Tastes great with [Express](http://expressjs.com) and [Connect](http://senchalabs.github.com/connect/). | ||
From the [Pact website](http://docs.pact.io/): | ||
Works with [Node.js](http://nodejs.org/) v0.2.5 and later. | ||
>The Pact family of frameworks provide support for [Consumer Driven Contracts](http://martinfowler.com/articles/consumerDrivenContracts.html) testing. | ||
## Documentation | ||
>A Contract is a collection of agreements between a client (Consumer) and an API (Provider) that describes the interactions that can take place between them. | ||
<http://reid.github.com/pact/> | ||
>Consumer Driven Contracts is a pattern that drives the development of the Provider from its Consumers point of view. | ||
>Pact is a testing tool that guarantees those Contracts are satisfied. | ||
Read [Getting started with Pact](http://dius.com.au/2016/02/03/microservices-pact/) for more information on | ||
how to get going. | ||
**NOTE: we are currently in the process of replacing [Pact Consumer JS DSL](https://github.com/DiUS/pact-consumer-js-dsl) with this library. Please bare with us whilst we transition. If you want to use Pact with JS and are new to Pact, start here.** | ||
## Installation | ||
npm i pact | ||
It's easy, simply run the below: | ||
``` | ||
npm install --save-dev pact | ||
``` | ||
## Example | ||
### Using Pact JS | ||
// Pact works with http.Server instances. | ||
// This includes express.Server, connect.Server, etc. | ||
// This method returns a new express.Server: | ||
var createServer = require("../lib/app").createServer; | ||
#### Consumer Side Testing | ||
require("vows").describe("HTTP Server").addBatch({ | ||
"A server in development" : { | ||
// Start a server for testing with httpify | ||
// Give it a new http.Server | ||
topic : httpify(createServer()), | ||
"when /foo is requested" : { | ||
topic : request(), // knows the URL from context name | ||
"should fail" : code(400) // check status code | ||
} | ||
"when /foo?bar=baz is requested" : { | ||
topic : request(), | ||
"should succeed" : code(200), | ||
"should return response time header" : function (topic) { | ||
// header names are lowercased for easy testing | ||
assert.include(topic.headers, "x-response-time"); | ||
}, | ||
"should be correct size" : function (topic) { | ||
// response is available as topic.body | ||
assert.equal(topic.body.length, 11); | ||
} | ||
}, | ||
"when making a bogus request" : { | ||
// you can always specify your own URL | ||
// POST requests work as well | ||
topic : request({ | ||
url : "/bogus", | ||
method : "POST", | ||
body : "quux=0" | ||
}), | ||
"should fail" : code(404) | ||
} | ||
}, | ||
"A server in production" : { | ||
topic : function () { | ||
// Example: wrap httpify for testing | ||
// with a new environment | ||
var oldEnv = process.env.NODE_ENV; | ||
process.env.NODE_ENV = "production"; | ||
var server = app.createServer(); | ||
httpify(server).apply(this); | ||
process.env.NODE_ENV = oldEnv; | ||
}, | ||
"when / is requested" : { | ||
topic : request(), | ||
"should fail" : code(404) | ||
} | ||
} | ||
}).export(module); | ||
The library provides a Verifier Service, Matchers and an API Interceptor: | ||
## Run self-tests | ||
>**Verifier** Sets up a test double (Verifier Provider API) with expected interactions. It's also responsible for generating Pact files. | ||
> | ||
>**Matchers** are functions you can use to increase the expressiveness of your tests, and reduce brittle test cases. See the [matching](http://docs.pact.io/documentation/matching.html) docs for more information. | ||
> | ||
>**Interceptor** is a utility that can be used to intercept requests to the Provider, where it's not simple for you to change your API endpoint. | ||
Requires [Vows][]. | ||
To use the library on your tests, do as you would normally with any other dependency: | ||
make test | ||
```javascript | ||
// ES6 | ||
import { default as Pact, Matchers, Interceptor } from 'pact-js' | ||
## About | ||
// you have to new the Interceptor | ||
// the others are just plain objects | ||
const interceptor = new Interceptor() | ||
Authored by [Reid Burke](http://github.com/reid), copyright Yahoo! Inc., and provided under the BSD license. See LICENSE file. | ||
// ~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~ | ||
// ES5 | ||
var Pact = require('pact-js') | ||
var matchers = Pact.Matchers | ||
matchers.term() | ||
matchers.somethingLike() | ||
matchers.eachLike() | ||
## History | ||
// you have to new the Interceptor | ||
var Interceptor = new Pact.Interceptor() | ||
``` | ||
Pact is used at Yahoo! for testing Node.js servers. It's based on the embedded Vows macros from the YUI Labs [Yeti](http://github.com/yui/yeti) project. | ||
Then to write a test that will generate a Pact file, here's an example below - it uses [Mocha](https://mochajs.org). There's a bit going on in there as we are spinning up the Pact Verifier Service Provider to mock a real server on the provider server. This is needed because that's where we will record our interactions. | ||
## Bugs | ||
More questions about what's involved in Pact? [Read more about it](http://docs.pact.io/documentation/how_does_pact_work.html). | ||
Submit bugs and pull requests to [Pact on GitHub](http://github.com/reid/pact). | ||
Check the `examples` folder for examples with Karma Jasmine / Mocha. The example below is taken from the [integration spec](https://github.com/pact-foundation/pact-js/blob/master/test/dsl/integration.spec.js). | ||
[Vows]: http://vowsjs.org/ | ||
```javascript | ||
import path from 'path' | ||
import { expect } from 'chai' | ||
import Promise from 'bluebird' | ||
import request from 'superagent' | ||
import wrapper from '@pact-foundation/pact-node' | ||
import { default as Pact } from 'pact' | ||
// great library to spin up the Pact Verifier Server | ||
// that will record interactions and eventually validate your pacts | ||
import wrapper from '@pact-foundation/pact-node' | ||
describe('Pact', () => { | ||
// when using the wrapper, you will need to tell it where to store the logs | ||
// make sure you the folders created before hand | ||
const mockServer = wrapper.createServer({ | ||
port: 1234, | ||
log: path.resolve(process.cwd(), 'logs', 'mockserver-integration.log'), | ||
dir: path.resolve(process.cwd(), 'pacts'), | ||
spec: 2 | ||
}) | ||
// this is the response you expect from your Provider | ||
const EXPECTED_BODY = [{ | ||
id: 1, | ||
name: 'Project 1', | ||
due: '2016-02-11T09:46:56.023Z', | ||
tasks: [ | ||
{id: 1, name: 'Do the laundry', 'done': true}, | ||
{id: 2, name: 'Do the dishes', 'done': false}, | ||
{id: 3, name: 'Do the backyard', 'done': false}, | ||
{id: 4, name: 'Do nothing', 'done': false} | ||
] | ||
}] | ||
var provider | ||
after(() => { | ||
wrapper.removeAllServers() | ||
}); | ||
beforeEach((done) => { | ||
mockServer.start().then(() => { | ||
// in order to use the Verifier, simply pass an object like below | ||
// it should contain the names of the consumer and provider in normal language | ||
// you can also use a different port if you have multiple providers | ||
provider = Pact({ consumer: 'My Consumer', provider: 'My Provider', port: 1234 }) | ||
done() | ||
}) | ||
}) | ||
afterEach((done) => { | ||
mockServer.delete().then(() => { | ||
done() | ||
}) | ||
}) | ||
context('with a single request', () => { | ||
it('successfully writes Pact file', (done) => { | ||
// add interactions, as many as needed | ||
beforeEach((done) => { | ||
provider.addInteraction({ | ||
state: 'i have a list of projects', | ||
uponReceiving: 'a request for projects', | ||
withRequest: { | ||
method: 'get', | ||
path: '/projects', | ||
headers: { 'Accept': 'application/json' } | ||
}, | ||
willRespondWith: { | ||
status: 200, | ||
headers: { 'Content-Type': 'application/json' }, | ||
body: EXPECTED_BODY | ||
} | ||
}).then(() => done()) | ||
}) | ||
// once test is run, write pact and remove interactions | ||
afterEach((done) => { | ||
provider.finalize().then(() => done()) | ||
}) | ||
// and this is how the verification process invokes your request | ||
// and writes the Pact file if all is well, returning you the data of the request | ||
// so you can do your assertions | ||
it('successfully verifies', (done) => { | ||
const verificationPromise = request | ||
.get('http://localhost:1234/projects') | ||
.set({ 'Accept': 'application/json' }) | ||
.then(provider.verify) | ||
expect(verificationPromise).to.eventually.eql(JSON.stringify(EXPECTED_BODY)).notify(done) | ||
}) | ||
}) | ||
}) | ||
}) | ||
``` | ||
#### Provider API Testing | ||
Once you have created Pacts for your Consumer, you need to validate those Pacts against your Provider. | ||
First, install [Pact Node](https://github.com/pact-foundation/pact-node): | ||
``` | ||
npm install @pact-foundation/pact-node --save | ||
``` | ||
Then run the Provider side verification step: | ||
```js | ||
var pact = require('@pact-foundation/pact-node'); | ||
var opts = { | ||
providerBaseUrl: <String>, // Running API provider host endpoint. Required. | ||
pactUrls: <Array>, // Array of local Pact file paths or Pact Broker URLs (http based). Required. | ||
providerStatesUrl: <String>, // URL to fetch the provider states for the given provider API. Optional. | ||
providerStatesSetupUrl <String>, // URL to send PUT requests to setup a given provider state. Optional. | ||
pactBrokerUsername: <String>, // Username for Pact Broker basic authentication. Optional | ||
pactBrokerPassword: <String>, // Password for Pact Broker basic authentication. Optional | ||
}; | ||
pact.verifyPacts(opts)).then(function () { | ||
// do something | ||
}); | ||
``` | ||
That's it! Read more about [Verifying Pacts](http://docs.pact.io/documentation/verifying_pacts.html). | ||
### Publishing Pacts to a Broker | ||
Sharing is caring - to simplify sharing Pacts between Consumers and Providers, checkout [sharing pacts](http://docs.pact.io/documentation/sharings_pacts.html). | ||
```js | ||
var pact = require('@pact-foundation/pact-node'); | ||
var opts = { | ||
pactUrls: <Array>, // Array of local Pact files or directories containing them. Required. | ||
pactBroker: <String>, // URL to fetch the provider states for the given provider API. Optional. | ||
pactBrokerUsername: <String>, // Username for Pact Broker basic authentication. Optional | ||
pactBrokerPassword: <String> // Password for Pact Broker basic authentication. Optional | ||
}; | ||
pact.publishPacts(opts)).then(function () { | ||
// do something | ||
}); | ||
``` | ||
### Using Mocha? | ||
Check out [Pact JS Mocha](https://github.com/pact-foundation/pact-js-mocha). | ||
## Contributing | ||
1. Fork it | ||
2. Create your feature branch (`git checkout -b my-new-feature`) | ||
3. Commit your changes (`git commit -am 'Add some feature'`) | ||
4. Push to the branch (`git push origin my-new-feature`) | ||
5. Create new Pull Request | ||
If you would like to implement `Pact` in another language, please check out the [Pact specification](https://github.com/bethesque/pact-specification) and have a chat to one of us on the [pact-dev Google group](https://groups.google.com/forum/#!forum/pact-support). | ||
The vision is to have a compatible `Pact` implementation in all the commonly used languages, your help would be greatly appreciated! | ||
## Contact | ||
* Twitter: [@pact_up](https://twitter.com/pact_up) | ||
* Google users group: https://groups.google.com/forum/#!forum/pact-support |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
Non-existent author
Supply chain riskThe package was published by an npm account that no longer exists.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
2563869
91
18890
1
240
0
6
24
1
4
13
+ Addedlodash.find@4.4.0
+ Addedlodash.isfunction@3.0.8
+ Addedlodash.isnil@4.0.0
+ Addedlodash.isundefined@3.0.1
+ Addedlodash.omitby@4.4.0
+ Addedmitm@1.2.1
+ Addedlodash._baseeach@4.1.3(transitive)
+ Addedlodash._basefind@3.0.0(transitive)
+ Addedlodash._basefindindex@3.6.0(transitive)
+ Addedlodash._baseiteratee@4.7.0(transitive)
+ Addedlodash._basetostring@4.12.0(transitive)
+ Addedlodash._stringtopath@4.8.0(transitive)
+ Addedlodash.find@4.4.0(transitive)
+ Addedlodash.isfunction@3.0.8(transitive)
+ Addedlodash.isnil@4.0.0(transitive)
+ Addedlodash.isundefined@3.0.1(transitive)
+ Addedlodash.keysin@4.2.0(transitive)
+ Addedlodash.omitby@4.4.0(transitive)
+ Addedmitm@1.2.1(transitive)
+ Addedunderscore@1.5.2(transitive)