Comparing version 0.1.5 to 0.1.6
{ | ||
"note": "This is a sample config file. You should change the mockDirectory to a more reasonable path.", | ||
"mockDirectory": "/usr/local/lib/node_modules/apimocker/samplemocks/", | ||
"quiet": false, | ||
"port": "7878", | ||
"latency": 50, | ||
"webServices": { | ||
"get": { | ||
"first": "king.json", | ||
"second": "king.json", | ||
"nested/ace": "ace.json", | ||
"var/:id": "xml/queen.xml" | ||
}, | ||
"post": { | ||
"king": "king.json" | ||
}, | ||
"all": { | ||
"queen": "xml/queen.xml" | ||
} | ||
"note": "This is a sample config file. You should change the mockDirectory to a more reasonable path.", | ||
"mockDirectory": "/usr/local/lib/node_modules/apimocker/samplemocks/", | ||
"quiet": false, | ||
"port": "7878", | ||
"latency": 50, | ||
"webServices": { | ||
"first": { | ||
"mockFile": "king.json", | ||
"latency": 20, | ||
"verbs": ["get"] | ||
}, | ||
"second": { | ||
"mockFile": "king.json", | ||
"contentType": "foobar", | ||
"verbs": ["post"] | ||
}, | ||
"nested/ace": { | ||
"mockFile": "ace.json", | ||
"verbs": ["post", "get"] | ||
}, | ||
"var/:id": { | ||
"mockFile": "xml/queen.xml", | ||
"verbs": ["all"] | ||
} | ||
} | ||
} |
@@ -12,3 +12,4 @@ // # Globbing (tip thanks to Yeoman) | ||
grunt.initConfig({ | ||
simplemocha: { | ||
mochacli: { | ||
options: { | ||
@@ -43,3 +44,3 @@ globals: ['should'], | ||
grunt.loadNpmTasks('grunt-simple-mocha'); | ||
grunt.loadNpmTasks('grunt-mocha-cli'); | ||
grunt.loadNpmTasks('grunt-contrib-watch'); | ||
@@ -49,3 +50,3 @@ grunt.loadNpmTasks('grunt-contrib-jshint'); | ||
grunt.registerTask('test', [ | ||
'simplemocha' | ||
'mochacli' | ||
]); | ||
@@ -52,0 +53,0 @@ |
@@ -11,6 +11,3 @@ var express = require('express'), | ||
"allowedDomains": ["*"], | ||
"webServices": { | ||
"get": {}, | ||
"post": {} | ||
} | ||
"webServices": {} | ||
}; | ||
@@ -21,3 +18,7 @@ | ||
apiMocker.express = express(); | ||
apiMocker.express.use(express.bodyParser()); | ||
// apiMocker.express.use(express.bodyParser()); | ||
// switched to use express.urlencoded and express.json, instead of bodyParser | ||
// https://github.com/senchalabs/connect/wiki/Connect-3.0 | ||
apiMocker.express.use(express.urlencoded()); | ||
apiMocker.express.use(express.json()); | ||
apiMocker.express.use(apiMocker.corsMiddleware); | ||
@@ -55,2 +56,3 @@ apiMocker.options = _.defaults(options, apiMocker.defaults); | ||
apiMocker.options = newOptions; | ||
apiMocker.options.webServices = apiMocker.normalizeWebServicesConfig(apiMocker.options.webServices); | ||
apiMocker.setRoutes(apiMocker.options.webServices); | ||
@@ -62,2 +64,26 @@ } else { | ||
apiMocker.normalizeWebServicesConfig = function(webServices) { | ||
var topLevelKeys = _.keys(webServices), newWebServices = {}; | ||
if (webServices[topLevelKeys[0]] && webServices[topLevelKeys[0]].mockFile) { | ||
return webServices; | ||
} else { | ||
apiMocker.log("WARNING: apimocker config file format is deprecated."); | ||
_.each(topLevelKeys, function(verb) { | ||
var serviceKeys = _.keys(webServices[verb]); | ||
_.each(serviceKeys, function(key) { | ||
if (newWebServices[key]) { | ||
newSvc = newWebServices[key]; | ||
newSvc.verbs[newSvc.verbs.length] = verb; | ||
} else { | ||
newWebServices[key] = { | ||
"mockFile": webServices[verb][key], | ||
"verbs": [verb] | ||
}; | ||
} | ||
}); | ||
}); | ||
return newWebServices; | ||
} | ||
}; | ||
apiMocker.createAdminServices = function() { | ||
@@ -87,2 +113,3 @@ apiMocker.express.all("/admin/reload", function(req, res) { | ||
newRoute.latency = req.param('latency'); | ||
newRoute.contentType = req.param('contentType'); | ||
} | ||
@@ -92,7 +119,4 @@ apiMocker.removeRoute(newRoute); | ||
// also need to save in our webServices object. | ||
if (!apiMocker.options.webServices[newRoute.verb]) { | ||
apiMocker.options.webServices[newRoute.verb] = {}; | ||
} | ||
delete apiMocker.options.webServices[newRoute.verb][newRoute.serviceUrl]; | ||
apiMocker.options.webServices[newRoute.verb][newRoute.serviceUrl] = newRoute.mockFile; | ||
delete apiMocker.options.webServices[newRoute.serviceUrl]; | ||
apiMocker.options.webServices[newRoute.serviceUrl] = newRoute; | ||
@@ -105,12 +129,14 @@ res.writeHead(200, {"Content-Type": "application/json"}); | ||
apiMocker.setRoutes = function(webServices) { | ||
var verbs = _.keys(webServices); | ||
_.each(verbs, function(verb) { | ||
var serviceKeys = _.keys(webServices[verb]); | ||
_.each(serviceKeys, function(key) { | ||
apiMocker.setRoute({ | ||
"serviceUrl": key, | ||
"mockFile": webServices[verb][key], | ||
"verb": verb, | ||
"latency": apiMocker.options.latency ? apiMocker.options.latency : 0 | ||
}); | ||
var topLevelKeys = _.keys(webServices); | ||
_.each(topLevelKeys, function(key) { | ||
var svc = _.clone(webServices[key]); | ||
// apiMocker.log("about to add a new service: " + JSON.stringify(svc)); | ||
_.each(svc.verbs, function(v) { | ||
// apiMocker.log("adding a service"); | ||
svc.verb = v.toLowerCase(); | ||
svc.serviceUrl = key; | ||
if (typeof svc.latency === "undefined") { | ||
svc.latency = apiMocker.options.latency ? apiMocker.options.latency : 0; | ||
} | ||
apiMocker.setRoute(svc); | ||
}); | ||
@@ -121,6 +147,18 @@ }); | ||
apiMocker.getMockPath = function(options) { | ||
apiMocker.sendResponse = function(res, options) { | ||
apiMocker.log("Returning mock: " + options.verb.toUpperCase() + " " + options.serviceUrl + " : " + | ||
apiMocker.options.webServices[options.verb][options.serviceUrl]); | ||
return apiMocker.options.webServices[options.verb][options.serviceUrl]; | ||
options.mockFile); | ||
if (options.contentType) { | ||
// apiMocker.log("Content-Type: " + options.contentType); | ||
res.header('Content-Type', options.contentType); | ||
var mockPath = path.join(apiMocker.options.mockDirectory, options.mockFile); | ||
fs.readFile(mockPath, {encoding: "utf8"}, function(err, data) { | ||
if (err) throw err; | ||
var buff = new Buffer(data, 'utf8'); | ||
res.send(buff); | ||
}); | ||
} else { | ||
res.sendfile(options.mockFile, {root: apiMocker.options.mockDirectory}); | ||
} | ||
}; | ||
@@ -134,16 +172,6 @@ | ||
setTimeout(function() { | ||
res.sendfile(apiMocker.getMockPath(options), {root: apiMocker.options.mockDirectory}); | ||
// res.type("text/xml"); | ||
// apiMocker.log("sending text/xml"); | ||
// var mockPath = path.join(apiMocker.options.mockDirectory, apiMocker.getMockPath(options)); | ||
// fs.readFile(mockPath, {encoding: "utf8"}, function(err, data) { | ||
// if (err) throw err; | ||
// // apiMocker.log("xml data: " + data); | ||
// var buff = new Buffer(data, 'utf8'); | ||
// res.send(buff); | ||
// }); | ||
apiMocker.sendResponse(res, options); | ||
}, options.latency); | ||
} else { | ||
res.sendfile(apiMocker.getMockPath(options), {root: apiMocker.options.mockDirectory}); | ||
apiMocker.sendResponse(res, options); | ||
} | ||
@@ -150,0 +178,0 @@ }); |
{ | ||
"name": "apimocker", | ||
"description": "Simple HTTP server that returns mock service API responses to your front end.", | ||
"version": "0.1.5", | ||
"author": { | ||
"name": "Greg Stroup", | ||
"email": "gstroup@gmail.com" | ||
}, | ||
"dependencies": { | ||
"express": ">=3.1", | ||
"commander": ">=1", | ||
"underscore": ">=1" | ||
}, | ||
"devDependencies": { | ||
"mocha": ">=1.8.2", | ||
"grunt": "~0.4.0", | ||
"grunt-simple-mocha": ">=0.3.2", | ||
"grunt-contrib-watch": ">=0.3.1", | ||
"grunt-contrib-jshint": "~0.1.1", | ||
"chai": ">=1.5.0", | ||
"sinon": ">=1.6.0" | ||
}, | ||
"bin": "./bin/apimocker.js", | ||
"files": "./samplemocks", | ||
"keywords": [ | ||
"express", "mock", "stub", "REST", "SOAP", | ||
"testing", "functional", "api" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/gstroup/apimocker.git" | ||
} | ||
} | ||
"name": "apimocker", | ||
"description": "Simple HTTP server that returns mock service API responses to your front end.", | ||
"version": "0.1.6", | ||
"engines": {"node": ">=0.10.0"}, | ||
"author": "Greg Stroup <gstroup@gmail.com>", | ||
"dependencies": { | ||
"express": ">=3.1", | ||
"commander": ">=1", | ||
"underscore": ">=1" | ||
}, | ||
"devDependencies": { | ||
"mocha": ">=1.8.2", | ||
"grunt": "~0.4.0", | ||
"grunt-mocha-cli": "1.3.0", | ||
"grunt-contrib-watch": ">=0.3.1", | ||
"grunt-contrib-jshint": "~0.7.1", | ||
"chai": ">=1.5.0", | ||
"sinon": ">=1.6.0" | ||
}, | ||
"main": "./lib/apimocker.js", | ||
"bin": { | ||
"apimocker": "./bin/apimocker.js" | ||
}, | ||
"keywords": [ | ||
"express", | ||
"mock", | ||
"stub", | ||
"REST", | ||
"SOAP", | ||
"testing", | ||
"functional", | ||
"api" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/gstroup/apimocker.git" | ||
}, | ||
"preferGlobal": true, | ||
"bugs": { | ||
"url": "https://github.com/gstroup/apimocker/issues" | ||
}, | ||
"directories": { | ||
"bin": "./bin", | ||
"lib": "./lib", | ||
"test": "./test", | ||
"samplemocks": "./samplemocks" | ||
}, | ||
"scripts": { | ||
"test": "mocha test/test.js" | ||
}, | ||
"license": "MIT" | ||
} |
# apimocker | ||
This is a node.js module to run a simple http server, which can serve up mock service responses. | ||
Responses can be JSON or XML to simulate REST or SOAP services. | ||
Access-Control HTTP Headers are set by default to allow CORS requests. | ||
Mock services are configured in the config.json file, or on the fly, to allow for easy functional testing. | ||
@@ -17,11 +18,11 @@ Using apimocker, you can develop your web or mobile app with no dependency on back end services. | ||
Out of the box, you can just run "apimocker" with no arguments. | ||
Out of the box, you can just run "apimocker" with no arguments. | ||
(Except on windows, you'll need to edit config.json first. See below.) | ||
Then you can visit "http://localhost:7878/first" in your browser to see it work. | ||
The quiet and port options can also be set in the config.json file. | ||
Values from config.json will override values from command line. | ||
The quiet and port options can also be set in the config.json file, | ||
and values from config.json will override values from the command line. | ||
After you get up and running, you should put your config.json and mock responses in a better location. | ||
It's not a good idea to keep them under the "node_modules" directory. | ||
Make sure another process is not already using the port you want. | ||
Make sure another process is not already using the port you want. | ||
If you want port 80, you may need to use "sudo" on Mac OSX. | ||
@@ -32,3 +33,3 @@ | ||
/Users/xxxxx/AppData/Roaming/npm/node_modules/apimocker/config.json | ||
Change the "mockDirectory" to point to this location. | ||
Change the "mockDirectory" to point to this location. | ||
(Or another location where you put the mock responses.) | ||
@@ -41,35 +42,43 @@ mockDirectory: /Users/xxxxx/AppData/Roaming/npm/node_modules/apimocker/samplemocks | ||
## Configuration | ||
On startup, config values are loaded from the config.json file. | ||
On startup, config values are loaded from the config.json file. | ||
During runtime, mock services can be configured on the fly. | ||
See the sample config.json file in this package. Latency (ms) can be set to simulate slow service responses. | ||
mockDirectory value should be an absolute path. Allowed domains can be set to restrict CORS requests to certain domains. | ||
See the sample config.json file in this package. | ||
* config.json file format has changed with the 0.1.6 release. See below for the new format. (Old config.json file format is deprecated, but still functioning.) | ||
* Content-type for a service response can be set for each service. If not set, content-type defaults to applicatoin/xml for .xml files, and application/json for .json files. | ||
* Latency (ms) can be set to simulate slow service responses. Latency can be set for a single service, or globally for all services. | ||
* mockDirectory value should be an absolute path. | ||
* Allowed domains can be set to restrict CORS requests to certain domains. | ||
```js | ||
{ | ||
"note": "This is a sample config file. You should change the mockDirectory to a more reasonable path.", | ||
"mockDirectory": "/usr/local/lib/node_modules/apimocker/samplemocks/", | ||
"output": true, | ||
"port": "7878", | ||
"allowedDomains": ["*"], | ||
"latency": 500, | ||
"webServices": { | ||
"get": { | ||
"first": "king.json", | ||
"second": "king.json", | ||
"nested/ace": "ace.json", | ||
"var/:id": "xml/queen.xml" | ||
}, | ||
"post": { | ||
"king": "king.json" | ||
}, | ||
"all": { | ||
"queen": "xml/queen.xml" | ||
} | ||
"note": "This is a sample config file. You should change the mockDirectory to a more reasonable path.", | ||
"mockDirectory": "/usr/local/lib/node_modules/apimocker/samplemocks/", | ||
"quiet": false, | ||
"port": "7878", | ||
"latency": 50, | ||
"allowedDomains": ["abc.com"], | ||
"webServices": { | ||
"first": { | ||
"mockFile": "king.json", | ||
"latency": 20, | ||
"verbs": ["get"] | ||
}, | ||
"second": { | ||
"mockFile": "king.json", | ||
"contentType": "foobar", | ||
"verbs": ["post"] | ||
}, | ||
"nested/ace": { | ||
"mockFile": "ace.json", | ||
"verbs": ["post", "get"] | ||
}, | ||
"var/:id": { | ||
"mockFile": "xml/queen.xml", | ||
"verbs": ["all"] | ||
} | ||
} | ||
} | ||
``` | ||
The most interesting part of the configuration file is the webServices section. | ||
This contains the mock service URLs grouped by HTTP verb. | ||
In each section, there's a key/value pair for each mock service. The key is the service URL (endpoint), the value is the mock response file name. | ||
For instance, a request sent to "http://server:port/first" will return the king.json file from the samplemocks directory. | ||
Response type will match the file extension. | ||
This section contains a JSON object describing each service. The key for each service object is the service URL (endpoint.) Inside each service object, the "mockFile" and "verbs" are required. "latency" and "contentType" are optional. | ||
For instance, a GET request sent to "http://server:port/first" will return the king.json file from the samplemocks directory, with a 20 ms delay. | ||
@@ -88,6 +97,7 @@ ## Runtime configuration | ||
"mockFile":"queen.xml", | ||
"latency": 100 | ||
"latency": 100, | ||
"contentType": "anythingyouwant" | ||
} | ||
``` | ||
``` | ||
or a get with query string parameters: | ||
@@ -99,4 +109,8 @@ localhost:7878/admin/setMock?verb=get&serviceUrl=second&mockFile=ace.json | ||
## Versions | ||
### 0.1.6 | ||
New config file format was introduced, allowing for custom content-types and more fine grained control over services. | ||
## Contributors | ||
Run "grunt" in the root "apimocker" directory to start the grunt watch task. This will run JSHint and mocha tests. | ||
Run "grunt watch" in the root "apimocker" directory to start the grunt watch task. This will run JSHint and mocha tests. | ||
@@ -103,0 +117,0 @@ ## Acknowledgements |
{ | ||
"note": "This is a sample config file. You should change the mockDirectory to a more reasonable path.", | ||
"mockDirectory": "/usr/local/lib/node_modules/apimocker/samplemocks/", | ||
"quiet": true, | ||
"port": "7879", | ||
"latency": 0, | ||
"webServices": { | ||
"get": { | ||
"first": "king.json", | ||
"second": "king.json", | ||
"nested/ace": "ace.json", | ||
"var/:id": "xml/queen.xml" | ||
}, | ||
"post": { | ||
"king": "king.json" | ||
}, | ||
"all": { | ||
"queen": "xml/queen.xml" | ||
} | ||
"note": "used for functional tests.", | ||
"mockDirectory": "./samplemocks/", | ||
"quiet": true, | ||
"port": "7879", | ||
"latency": 0, | ||
"allowedDomains": ["abc"], | ||
"webServices": { | ||
"first": { | ||
"mockFile": "king.json", | ||
"contentType": "foobar", | ||
"verbs": ["get"] | ||
}, | ||
"nested/ace": { | ||
"mockFile": "ace.json", | ||
"verbs": ["post", "get"] | ||
}, | ||
"var/:id": { | ||
"mockFile": "xml/queen.xml", | ||
"verbs": ["all"] | ||
} | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
describe('Functional tests using an http client to test "end-to-end"', function() { | ||
describe('Functional tests using an http client to test "end-to-end": ', function() { | ||
@@ -22,3 +22,3 @@ var chai = require("chai"), | ||
before(function startMockerForFuncTests() { | ||
mocker = apiMocker.createServer({quiet: true}).setConfigFile("test/test-config.json"); | ||
mocker = apiMocker.createServer({quiet: false}).setConfigFile("test/test-old-config.json"); | ||
mocker.start(); | ||
@@ -31,3 +31,4 @@ }); | ||
res.on('data', function (chunk) { | ||
expect(JSON.parse(chunk)).to.deep.equal(expected); | ||
//expect(JSON.parse(chunk)).to.deep.equal(expected); | ||
// console.log(chunk); | ||
done(); | ||
@@ -89,2 +90,53 @@ }); | ||
describe('new config file format', function(done) { | ||
before(function(done) { | ||
mocker.setConfigFile("test/test-config.json"); | ||
var req, reqOptions = httpReqOptions(); | ||
reqOptions.path = "/admin/reload"; | ||
req = http.request(reqOptions, function(res) { | ||
res.setEncoding('utf8'); | ||
res.on('data', function (chunk) { | ||
expect(res.statusCode).to.equal(200); | ||
done(); | ||
}); | ||
}); | ||
req.end(); | ||
}); | ||
it('sets a basic route', function(done) { | ||
var reqOptions = httpReqOptions("/first"); | ||
reqOptions.method = "get"; | ||
verifyResponseBody(reqOptions, {"king": "greg"}, done); | ||
}); | ||
it('returns a custom content type', function(done) { | ||
var reqOptions = httpReqOptions("/first"); | ||
verifyResponseHeaders(reqOptions, {"content-type": "foobar"}, done); | ||
}); | ||
it('returns correct content-type for json response, with nested path', function(done) { | ||
var reqOptions = httpReqOptions("/nested/ace"); | ||
verifyResponseHeaders(reqOptions, {"content-type": "application/json"}, done); | ||
}); | ||
it('returns 404 for incorrect path, after reload', function(done) { | ||
var req, reqOptions = httpReqOptions(); | ||
reqOptions.method = "post"; | ||
reqOptions.path = "/king"; | ||
req = http.request(reqOptions, function(res) { | ||
res.setEncoding('utf8'); | ||
res.on('data', function (chunk) { | ||
expect(res.statusCode).to.equal(404); | ||
done(); | ||
}); | ||
}); | ||
req.end(); | ||
}); | ||
it('allows domains specified in config file', function(done) { | ||
var reqOptions = httpReqOptions("/first"); | ||
verifyResponseHeaders(reqOptions, {'access-control-allow-origin': "abc"}, done); | ||
}); | ||
}); | ||
}); |
// run "grunt test", or run "mocha" in this test directory to execute. | ||
describe('unit tests', function() { | ||
describe('unit tests: ', function() { | ||
var chai = require("chai"), // better assertions than node offers. | ||
@@ -10,3 +10,3 @@ apiMocker = require("../lib/apimocker.js"), | ||
sinon = require("sinon"), | ||
testConfig = { | ||
oldTestConfig = { | ||
"mockDirectory": "foo/bar/samplemocks/", | ||
@@ -24,3 +24,3 @@ "quiet": true, | ||
"post": { | ||
"king": "king.json" | ||
"first": "king.json" | ||
}, | ||
@@ -31,6 +31,31 @@ "all": { | ||
} | ||
}, | ||
testConfig = { | ||
"mockDirectory": "foo/bar/samplemocks/", | ||
"quiet": true, | ||
"port": "7879", | ||
"latency": 50, | ||
"allowedDomains": ["abc"], | ||
"webServices": { | ||
"first": { | ||
"mockFile": "king.json", | ||
"verbs": ["get","post"] | ||
}, | ||
"nested/ace": { | ||
"mockFile": "ace.json", | ||
"verbs": ["get"] | ||
}, | ||
"var/:id": { | ||
"mockFile": "xml/queen.xml", | ||
"verbs": ["get"] | ||
}, | ||
"queen": { | ||
"mockFile": "xml/queen.xml", | ||
"verbs": ["all"] | ||
} | ||
} | ||
}; | ||
chai.Assertion.includeStack = true; | ||
describe('createServer', function() { | ||
describe('createServer: ', function() { | ||
it('sets defaults when no options are passed in', function() { | ||
@@ -42,4 +67,3 @@ var mocker = apiMocker.createServer(); | ||
expect(mocker.options.allowedDomains[0]).to.equal("*"); | ||
expect(mocker.options.webServices.get).to.be.an('object'); | ||
expect(mocker.options.webServices.post).to.be.an('object'); | ||
expect(mocker.options.quiet).to.equal(undefined); | ||
}); | ||
@@ -52,4 +76,2 @@ | ||
expect(mocker.options.allowedDomains[0]).to.equal("*"); | ||
expect(mocker.options.webServices.get).to.be.an('object'); | ||
expect(mocker.options.webServices.post).to.be.an('object'); | ||
expect(mocker.options.quiet).to.equal(true); | ||
@@ -60,3 +82,3 @@ expect(mocker.options.foo).to.equal("bar"); | ||
describe('setConfigFile', function() { | ||
describe('setConfigFile: ', function() { | ||
var mocker = apiMocker.createServer(); | ||
@@ -87,3 +109,3 @@ | ||
describe("loadConfigFile", function() { | ||
describe("loadConfigFile: ", function() { | ||
var fsStub; | ||
@@ -99,7 +121,6 @@ | ||
it("sets options from mock in-memory config file", function() { | ||
it("sets options from new format mock config file", function() { | ||
var mocker = apiMocker.createServer({quiet: true}); | ||
fsStub.returns(JSON.stringify(testConfig)); | ||
mocker.setConfigFile("any value"); | ||
mocker.loadConfigFile(); | ||
@@ -114,2 +135,16 @@ expect(mocker.options.port).to.equal(testConfig.port); | ||
it("sets options from old format mock in-memory config file, stores in new format", function() { | ||
var mocker = apiMocker.createServer({quiet: true}); | ||
fsStub.returns(JSON.stringify(oldTestConfig)); | ||
mocker.setConfigFile("any value"); | ||
mocker.loadConfigFile(); | ||
expect(mocker.options.port).to.equal(oldTestConfig.port); | ||
expect(mocker.options.mockDirectory).to.equal(oldTestConfig.mockDirectory); | ||
expect(mocker.options.allowedDomains[0]).to.equal(oldTestConfig.allowedDomains[0]); | ||
expect(mocker.options.webServices).to.deep.equal(testConfig.webServices); | ||
expect(mocker.options.quiet).to.equal(true); | ||
expect(mocker.options.latency).to.equal(oldTestConfig.latency); | ||
}); | ||
it("combines values from defaults, options, and config file", function() { | ||
@@ -116,0 +151,0 @@ var mocker = apiMocker.createServer({quiet: true, test: "fun", port: 2323}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
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 License Found
License(Experimental) License information could not be found.
Found 1 instance in 1 package
27013
14
0
585
0
115