Skip to content

Instantly share code, notes, and snippets.

@mefellows
Last active May 25, 2017 00:25
Show Gist options
  • Save mefellows/15c9fcb052c2aa9d8951f91d48d6da54 to your computer and use it in GitHub Desktop.
Save mefellows/15c9fcb052c2aa9d8951f91d48d6da54 to your computer and use it in GitHub Desktop.
define(['client', 'Pact'], function (example, Pact) {
describe("Client", function () {
var client, provider
beforeAll(function (done) {
client = example.createClient('http://localhost:1234');
console.log(Pact);
// Create a Mock Server test double of your Provider API. If you need multiple Providers for a scenario, you can create as many as these as you need.
provider = Pact({
consumer: 'Friends Client',
provider: 'Friends API',
spec: '3.0.0' // https://github.com/pact-foundation/pact-specification
});
// required for slower Travis CI environment
setTimeout(function () {
console.log('beforeAll done');
done();
}, 2000)
// Required if run with `singleRun: false. In some cases you might want to clear out the expectations of the Mock Service, call this to clear out
// any expectations for the next test run. NOTE: verify() will implicitly call this.
provider.removeInteractions();
});
afterAll(function (done) {
// Record the interactions registered to the Mock Server into the pact file and shuts it down.
console.log('afterAll provider.finalize');
provider.finalize().then(function () {
console.log('afterAll provider.finalize done');
done();
}, function (err) {
console.log('afterAll provider.finalize error: ' + err);
done.fail(err);
})
});
describe("sayHello", function () {
beforeAll(function (done) {
console.log('addInteraction-->sayHello');
// Register an expectation on the Mock Server, which must be called by your test case(s). You can add multiple interactions per
// server. These will be validated and written to a pact if successful.
provider.addInteraction({
uponReceiving: 'a request for hello',
withRequest: {
method: 'GET',
path: '/sayHello'
},
willRespondWith: {
status: 200,
headers: {"Content-Type": "application/json"},
body: {reply: "Hello"}
}
}).then(function () {
console.log('addInteraction-->sayHello done');
done();
}, function (err) {
console.log('addInteraction-->sayHello error: ' + err);
done.fail(err);
})
});
afterAll(function (done) {
console.log('sayHello.afterAll');
provider.removeInteractions().then(function () {
console.log('sayHello.afterAll done');
done();
});
});
it("should say hello", function (done) {
//Run the tests
console.log('client.sayHello');
client.sayHello().then(function (data) {
console.log('client.sayHello then');
expect(JSON.parse(data.responseText)).toEqual({reply: "Hello"});
done();
}).catch(function (err) {
console.log('client.sayHello error');
done.fail(err);
});
});
// verify with Pact, and reset expectations
it('successfully verifies', function (done) {
// Checks with the Mock Service if the expected interactions have been exercised.
console.log('provider.verify');
provider.verify().then(function (a) {
console.log('provider.verify done');
done();
}, function (e) {
console.log('provider.verify error: ' + e);
done.fail(e);
});
});
});
});
});
define([], function () {
function Client() {
var self = this;
var localBaseUrl;
self.createClient = function (baseUrl) {
localBaseUrl = baseUrl;
return this;
};
self.sayHello = function () {
//Makes a synchronous request
var xhr = new XMLHttpRequest();
xhr.open('GET', localBaseUrl + '/sayHello', false);
xhr.send();
return Promise.resolve(xhr);
};
self.findFriendsByAgeAndChildren = function (age, children) {
//dirty hack - assume two children, because iterating
//over an array in native Javascript is like stabbing yourself in the eyballs
var url = localBaseUrl + '/friends?age=' + age + '&children=' + children[0] + '&children=' + children[1];
var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.setRequestHeader('Accept', 'application/json');
xhr.send();
return Promise.resolve(xhr);
};
self.unfriendMe = function () {
//Makes an asynchronous request
return new Promise(function (resolve, reject) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4) {
if (xmlhttp.status === 200) {
resolve(xmlhttp)
} else if (xmlhttp.status === 404) {
xmlhttp.text = "No friends :("
reject(xmlhttp);
} else {
reject(xmlhttp);
}
}
}
xmlhttp.open('PUT', localBaseUrl + '/unfriendMe', true);
xmlhttp.send();
})
};
}
return new Client();
});
// Karma configuration
// Generated on Wed May 10 2017 16:04:17 GMT-0500 (Central Daylight Time)
module.exports = function (config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
frameworks: ['jasmine', 'pact', 'requirejs'],
pact: {},
// list of files / patterns to load in the browser
files: [
{pattern: 'node_modules/pact-web/pact-web.js', included: false},
{pattern: 'js/*.js', included: false},
'test-main.js'
],
// list of files to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['PhantomJS_without_security'],
customLaunchers: {
Chrome_without_security: {
base: 'Chrome',
flags: ['--disable-web-security'],
displayName: 'Chrome w/o security'
},
PhantomJS_without_security: {
base: 'PhantomJS',
flags: ['--web-security=no']
}
},
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}
{
"name": "PactTest",
"version": "1.0.0",
"keywords": [
"util",
"functional",
"server",
"client",
"browser"
],
"author": "MICHANDE",
"contributors": [],
"dependencies": {},
"scripts": {
"test:client": "karma start --single-run --browsers PhantomJS_without_security",
"test:client:watch": "karma start --single-run=false --browsers PhantomJS_without_security",
"test:client:debug": "karma start --browsers Chrome,Chrome_without_security",
"test:publish": "node js/publish.js"
},
"devDependencies": {
"@pact-foundation/pact-node": "^4.9.2",
"jasmine-core": "^2.6.1",
"karma": "^1.7.0",
"karma-chrome-launcher": "^2.1.1",
"karma-jasmine": "^1.1.0",
"karma-pact": "0.0.7",
"karma-phantomjs-launcher": "^1.0.4",
"karma-requirejs": "^1.1.0",
"pact": "^2.5.0",
"pact-web": "^2.5.0",
"requirejs": "^2.3.3"
}
}
// From: https://github.com/pact-foundation/pact-js/tree/master/examples/e2e
var pact = require('@pact-foundation/pact-node');
var path = require('path');
var opts = {
pactUrls: [path.resolve(__dirname, '../pacts/friends_client-friends_api.json')],
pactBroker: 'http://localhost:8080',
tags: ['prod', 'test'],
consumerVersion: '3.0.0'
};
pact.publishPacts(opts).then(function () {
console.log('Pacts are published: '+JSON.stringify(opts, null, 2));
}).catch(function (e) {
console.log('Pact contract publishing failed: ', e)
});
var allTestFiles = []
var TEST_REGEXP = /(spec|test)\.js$/i
// Get a list of all the test files to include
Object.keys(window.__karma__.files).forEach(function (file) {
if (TEST_REGEXP.test(file)) {
// Normalize paths to RequireJS module names.
// If you require sub-dependencies of test files to be loaded as-is (requiring file extension)
// then do not normalize the paths
var normalizedTestModule = file.replace(/^\/base\/|\.js$/g, '')
allTestFiles.push(normalizedTestModule)
}
})
console.log("loading test files:")
console.log(allTestFiles);
require.config({
// Karma serves files under /base, which is the basePath from your config file
baseUrl: '/base',
paths: {
'Pact': 'node_modules/pact-web/pact-web',
'client': 'js/client'
},
// dynamically load all test files
deps: allTestFiles,
// we have to kickoff jasmine, as it is asynchronous
callback: window.__karma__.start
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment