-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathindex.js
More file actions
120 lines (107 loc) · 4.31 KB
/
index.js
File metadata and controls
120 lines (107 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
const _ = require("lodash");
const mock_context = require('aws-lambda-mock-context');
const Promise = require("bluebird");
const path = require("path");
const fs = require("fs");
const chai = require("chai").should();
const REQUEST_EXTENSION = ".request.json";
const RESPONSE_EXTENSION_JSON = ".response.json";
const RESPONSE_EXTENSION_PATTERN = ".response.pattern";
const RESPONSE_EXTENSION_JS = ".response.js";
module.exports = function(method_under_test, options) {
if(_.isString(options)) {
options = { path: options };
}
return _.chain(fs.readdirSync(options.path))
.filter(isTestCase)
.map(extractTestCaseName)
.map(_.partial(processTestCase, method_under_test, options))
.value();
}
function isTestCase(filename) {
return filename.endsWith(REQUEST_EXTENSION);
}
function extractTestCaseName(filename) {
return filename.substr(0, filename.length - REQUEST_EXTENSION.length);
}
function loadRequest(test_case, options) {
return JSON.parse(fs.readFileSync(path.join(options.path, test_case + REQUEST_EXTENSION)));
}
function processTestCase(method_under_test, options, test_case) {
return it(test_case, function() {
const request = loadRequest(test_case, options);
// Pre-processing
var promise = Promise.resolve(request);
if(options.before) {
promise = Promise.resolve(options.before(request, test_case, options))
.then(result => request);
}
// Execute the test
const context = mock_context();
return promise.then(request => {
method_under_test(request, context, context.done);
return context.Promise;
}).then(
response => processResults(null, response, request, options, test_case)
, error => processResults(error, null, request, options, test_case)
);
});
}
function processResults(error, response, request, options, test_case) {
if(options.after) {
return Promise.resolve(options.after(error, response, request, test_case, options, validateResponse));
}
return validateResponse(error, response, request, test_case, options);
}
function validateResponse(error, response, request, test_case, options) {
if(error && !options.errorExpected) {
throw error;
}
else if(!error && options.errorExpected) {
throw new Error("Test case should have thrown an error, but instead succeeded - " + JSON.stringify(response, null, 2));
}
return matchesExpectedResponse(error, response, request, test_case, options);
}
function matchesExpectedResponse(error, response, request, test_case, options) {
var js_response_filename = path.join(options.path, test_case + RESPONSE_EXTENSION_JS);
var json_response_filename = path.join(options.path, test_case + RESPONSE_EXTENSION_JSON);
var pattern_response_filename = path.join(options.path, test_case + RESPONSE_EXTENSION_PATTERN);
if(fs.existsSync(js_response_filename)) {
return require(js_response_filename)(error, response, request, test_case, options);
}
if(fs.existsSync(pattern_response_filename)) {
return matches_pattern(error, response, pattern_response_filename, options);
}
else if(fs.existsSync(json_response_filename) || options.saveMissingResponses) {
return matches_json(error, response, json_response_filename, options);
}
else {
var printable_response = _.isError(error) ? error.toString() : JSON.stringify(error || response, null, 2);
throw new Error(`No valid response file found for test case:\n * ${json_response_filename}\n * ${pattern_response_filename}\nResponse was:\n ${printable_response}`);
}
}
function matches_json(error, response, json_response_filename, options) {
if(!fs.existsSync(json_response_filename)) {
fs.writeFileSync(json_response_filename, JSON.stringify(response, null, 2));
}
else {
var expected = JSON.parse(fs.readFileSync(json_response_filename));
if(!_.isNull(error)) {
if(expected.message) {
return error.message.should.deep.equals(expected.message);
}
else {
// TODO - Add other json validation properties for errors
throw new Error("No validatable properties found in the json response file to validate error");
}
}
else {
return response.should.deep.equals(expected);
}
}
}
function matches_pattern(error, response, pattern_response_filename, options) {
var expected = fs.readFileSync(pattern_response_filename, 'utf-8').trim();
var actual = _.isError(error) ? error.toString() : JSON.stringify(error || response, null, 2);
return actual.should.match(new RegExp(expected));
}