Skip to content
This repository has been archived by the owner on Dec 16, 2023. It is now read-only.

Commit

Permalink
feat: allow to manually remove unused fixtures
Browse files Browse the repository at this point in the history
fixes #123
  • Loading branch information
Michael Weibel committed Jul 5, 2018
1 parent b01018e commit b006082
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 18 deletions.
17 changes: 12 additions & 5 deletions src/catalog.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,20 +193,23 @@ module.exports = class Catalog {
files = files.filter(f => !/^\./.test(f));
for (let file of files) {
let mapping = this._read(`${pathname}/${file}`);
newMatchers.push(Matcher.fromMapping(host, mapping));
newMatchers.push(Matcher.fromMapping(`${pathname}/${file}`, host, mapping));
}
} else {
const mapping = this._read(pathname);
newMatchers.push(Matcher.fromMapping(host, mapping));
newMatchers.push(Matcher.fromMapping(`${pathname}`, host, mapping));
}

return newMatchers;
}

getNotMatchedFixtures() {
return Object.keys(this.matchers).map(host => {
return this.matchers[host].filter(matcher => !matcher.isMatched)
}).reduce((a, b) => a.concat(b), []);
}

save(host, request, response, callback) {
const matcher = Matcher.fromMapping(host, { request, response });
const matchers = this.matchers[host] || [];
matchers.push(matcher);
const requestHeaders = this.settings.headers;

const uid = `${Date.now()}${Math.floor(Math.random() * 100000)}`;
Expand All @@ -224,6 +227,10 @@ module.exports = class Catalog {
}

const filename = `${pathname}/${uid}`;
const matcher = Matcher.fromMapping(filename, host, { request, response });
const matchers = this.matchers[host] || [];
matchers.push(matcher);

try {
const file = File.createWriteStream(tmpfile, { encoding: 'utf-8' });
file.write(`${request.method.toUpperCase()} ${request.url.path || '/'}\n`);
Expand Down
3 changes: 3 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ class Replay extends EventEmitter {
this.catalog.setFixturesDir(dir);
}

get notMatchedFixtures() {
return this.catalog.getNotMatchedFixtures();
}
}


Expand Down
30 changes: 18 additions & 12 deletions src/matcher.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// A matcher is a function that, given a request, returns an appropriate response or nothing.
//
// The most common use case is to calling `Matcher.fromMapping(mapping)`.
// The most common use case is to calling `Matcher.fromMapping(filename, host, mapping)`.
//
// The request consists of:
// url - URL object
Expand All @@ -25,7 +25,7 @@ const jsStringEscape = require('js-string-escape');
// To create a matcher from request/response mapping use `fromMapping`.
module.exports = class Matcher {

constructor(request, response) {
constructor(fixturePath, request, response) {
// Map requests to object properties. We do this for quick matching.
assert(request.url || request.regexp, 'I need at least a URL to match request to response');
if (request.regexp) {
Expand All @@ -38,6 +38,9 @@ module.exports = class Matcher {
this.path = url.path;
}

this.fixturePath = fixturePath;
this.isMatched = false;

this.method = (request.method && request.method.toUpperCase()) || 'GET';
this.headers = {};
if (request.headers)
Expand Down Expand Up @@ -103,20 +106,27 @@ module.exports = class Matcher {
data += chunks[0];
data = jsStringEscape(data);

return this.body instanceof RegExp ?
this.body.test(data) :
this.body === data;
if (this.body instanceof RegExp && this.body.test(data)) {
this.isMatched = true;
return this.response;
} else if(this.body === data) {
this.isMatched = true;
return this.response;
}
return false
}

return true;
this.isMatched = true;

return this.response;
}


// Returns new matcher function based on the supplied mapping.
//
// Mapping can contain `request` and `response` object. As shortcut, mapping can specify `path` and `method` (optional)
// directly, and also any of the response properties.
static fromMapping(host, mapping) {
static fromMapping(fileName, host, mapping) {
assert(!!mapping.path ^ !!mapping.request, 'Mapping must specify path or request object');

let matchingRequest;
Expand All @@ -141,11 +151,7 @@ module.exports = class Matcher {
body: mapping.request.body
};

const matcher = new Matcher(matchingRequest, mapping.response || {});
return function(request) {
if (matcher.match(request))
return matcher.response;
};
return new Matcher(fileName, matchingRequest, mapping.response || {});
}

};
Expand Down
2 changes: 1 addition & 1 deletion src/recorder.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module.exports = function recorded(settings) {
const matchers = catalog.find(host);
if (matchers)
for (let matcher of matchers) {
let response = matcher(request);
let response = matcher.match(request);
if (response) {
callback(null, response);
return;
Expand Down
5 changes: 5 additions & 0 deletions test/replay_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ describe('Replay', function() {

describe('listeners', function() {
let response;
let notMatchedFixtures;

before(function(done) {
HTTP
.get(`http://example.com:${INACTIVE_PORT}/weather?c=94606`, function(_) {
response = _;
notMatchedFixtures = Replay.notMatchedFixtures
done();
})
.on('error', done);
Expand All @@ -46,6 +48,9 @@ describe('Replay', function() {
it('should return response trailers', function() {
assert.deepEqual(response.trailers, { });
});
it('should have matched', function() {
assert.equal(Replay.notMatchedFixtures.filter(matcher => matcher.path === '/weather?c=94606').length, 0);
})
});

describe('Old http status line format', function() {
Expand Down

0 comments on commit b006082

Please sign in to comment.