Skip to content

Commit 281fba0

Browse files
committed
optimization
- teat: enhanced testing - feat: consitent usage of "target" and "client" namings - feat: streamline .info property across targets and clients - feat: added detailed tests for every use case and forced each target and client to run through them all (closes #4) - fix: node postData.text = undefined (closes #8) - fix: node postData.params was ignored - fix: cleanup syntax in ocaml - feat: switch to `require-directory` module - feat: use reduce instead of map for pair object creation - feat: more efficient matching for conversion
1 parent cb93bc7 commit 281fba0

110 files changed

Lines changed: 1269 additions & 659 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,6 @@ module.exports = function (opts) {
169169
module.exports.info = function () {
170170
// return target info
171171
return {
172-
family: 'node', // target family
173172
key: 'native', // target key
174173
ext: '.js', // preferred extension
175174
title: '', // target label

bin/httpsnippet

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ var pkg = require('../package.json');
1414
cmd
1515
.version(pkg.version)
1616
.usage('[options] <file>')
17-
.option('-t, --target <target>', 'target ouput')
18-
.option('-f, --family [family]', 'target family')
17+
.option('-t, --target <target>', 'target output')
18+
.option('-c, --client [client]', 'target client library')
1919
.option('-o, --output <directory>', 'write output to directory')
2020
.option('-n, --output-name <name>', 'output file name')
2121
.parse(process.argv);
@@ -24,12 +24,6 @@ if (!cmd.args.length || !cmd.target) {
2424
cmd.help();
2525
}
2626

27-
// short hand
28-
if (cmd.target && !cmd.family) {
29-
cmd.family = cmd.target;
30-
delete cmd.target;
31-
}
32-
3327
if (cmd.output) {
3428
var dir = path.resolve(cmd.output);
3529

@@ -86,7 +80,7 @@ async.waterfall([
8680
return cb(!e[0] ? 'invalid input' : (e[0].field + ' ' + e[0].message), null);
8781
}
8882

89-
cb(null, snippet.convert(cmd.family, cmd.target));
83+
cb(null, snippet.convert(cmd.target, cmd.client));
9084
};
9185

9286
async.map(sources, iterator, function (err, results) {
@@ -102,10 +96,10 @@ async.waterfall([
10296

10397
var filename = path.format({
10498
dir: dir,
105-
base: name + HTTPSnippet.extname(cmd.family, cmd.target)
99+
base: name + HTTPSnippet.extname(cmd.target)
106100
});
107101

108-
fs.writeFile(filename, snippets[index]);
102+
fs.writeFile(filename, snippets[index] + '\n');
109103
};
110104

111105
async.each(files, iterator);

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"main": "./src/index.js",
66
"bin": "./bin/httpsnippet",
77
"scripts": {
8-
"test": "mocha --recursive --reporter spec",
8+
"test": "mocha --reporter nyan",
99
"coverage": "mocha -r blanket -R mocha-lcov-reporter > test/lcov.info",
1010
"html-cov": "mocha -r blanket -R html-cov > test/coverage.html",
1111
"codeclimate": "codeclimate < test/lcov.info"
@@ -27,6 +27,7 @@
2727
"devDependencies": {
2828
"blanket": "^1.1.6",
2929
"codeclimate-test-reporter": "0.0.4",
30+
"glob": "^5.0.1",
3031
"mocha": "^2.1.0",
3132
"mocha-lcov-reporter": "0.0.2",
3233
"should": "^5.0.1"
@@ -37,6 +38,6 @@
3738
"commander": "^2.6.0",
3839
"debug": "^2.1.1",
3940
"har-validator": "^1.1.2",
40-
"requireindex": "^1.1.0"
41+
"require-directory": "^2.1.0"
4142
}
4243
}

src/index.js

Lines changed: 33 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33
var debug = require('debug')('httpsnippet');
4-
var mapper = require('./mapper');
4+
var reducer = require('./reducer');
55
var qs = require('querystring');
66
var targets = require('./targets');
77
var url = require('url');
@@ -37,21 +37,21 @@ var HTTPSnippet = function (req, lang) {
3737
if (this.source.queryString && this.source.queryString.length) {
3838
debug('queryString found, constructing queryString pair map');
3939

40-
this.source.queryString.map(mapper(this.source.queryObj));
40+
this.source.queryObj = this.source.queryString.reduce(reducer, {});
4141
}
4242

4343
// construct headers objects
4444
if (this.source.headers && this.source.headers.length) {
4545
debug('headers found, constructing header pair map');
4646

47-
this.source.headers.map(mapper(this.source.headersObj));
47+
this.source.headersObj = this.source.headers.reduce(reducer, {});
4848
}
4949

5050
// deconstruct the uri
5151
this.source.uriObj = url.parse(this.source.url, true, true);
5252

5353
// merge all possible queryString values
54-
this.source.queryString = util._extend(this.source.uriObj.query, this.source.queryObj);
54+
this.source.queryObj = this.source.queryString = util._extend(this.source.uriObj.query, this.source.queryObj);
5555

5656
// reset uriObj values for a clean url
5757
this.source.uriObj.query = null;
@@ -71,16 +71,12 @@ var HTTPSnippet = function (req, lang) {
7171
}.bind(this));
7272
};
7373

74-
HTTPSnippet.prototype.getSource = function () {
75-
return this.source;
76-
};
77-
78-
HTTPSnippet.prototype.convert = function (family, target, opts) {
79-
if (!opts && target) {
80-
opts = target;
74+
HTTPSnippet.prototype.convert = function (target, client, opts) {
75+
if (!opts && client) {
76+
opts = client;
8177
}
8278

83-
var func = this._matchTarget(family, target);
79+
var func = this._matchTarget(target, client);
8480

8581
if (func) {
8682
return func.call(this, opts);
@@ -89,107 +85,49 @@ HTTPSnippet.prototype.convert = function (family, target, opts) {
8985
return false;
9086
};
9187

92-
HTTPSnippet.prototype._matchTarget = function (familyName, target) {
88+
HTTPSnippet.prototype._matchTarget = function (target, client) {
9389
// does it exist?
94-
if (targets[familyName] === undefined) {
90+
if (!targets.hasOwnProperty(target)) {
9591
return false;
9692
}
9793

98-
// isolate the family
99-
var family = targets[familyName];
100-
101-
// childless targets
102-
if (typeof family === 'function') {
103-
return family;
94+
if (typeof targets[target] === 'function') {
95+
return targets[target];
10496
}
10597

106-
// find the first default target
107-
var defaultTarget = family._familyInfo().default;
108-
10998
// shorthand
110-
if (!target || typeof target === 'object') {
111-
target = defaultTarget;
112-
}
113-
114-
// asking for a particular target
115-
if (typeof target === 'string') {
116-
// attempt to call the first one we find
117-
if (typeof family[target] !== 'function') {
118-
target = defaultTarget;
119-
}
120-
121-
// last chance
122-
if (typeof family[target] === 'function') {
123-
return family[target];
124-
}
99+
if (typeof client === 'string' && typeof targets[target][client] === 'function') {
100+
return targets[target][client];
125101
}
126102

127-
return false;
103+
// default target
104+
return targets[target][targets[target].info.default];
128105
};
129106

130107
// exports
131-
132108
module.exports = HTTPSnippet;
133109

134-
module.exports._targets = function () {
135-
return Object.keys(targets);
136-
};
110+
module.exports.availableTargets = function () {
111+
return Object.keys(targets).map(function (key) {
112+
var target = util._extend({}, targets[key].info);
113+
var clients = Object.keys(targets[key])
137114

138-
module.exports._familyInfo = function (family) {
139-
if (targets[family] && targets[family]._familyInfo) {
140-
return targets[family]._familyInfo();
141-
}
115+
.filter(function (prop) {
116+
return !~['info', 'index'].indexOf(prop);
117+
})
142118

143-
return false;
144-
};
119+
.map(function (client) {
120+
return targets[key][client].info;
121+
});
145122

146-
module.exports.info = function (family, target) {
147-
if (!targets[family]) {
148-
return false;
149-
}
150-
151-
if (typeof targets[family] === 'function') {
152-
return targets[family].info();
153-
}
154-
155-
// get all info for all family members
156-
if (!target && typeof targets[family] === 'object') {
157-
var results = {
158-
family: family
159-
};
160-
161-
results.members = Object.keys(targets[family])
162-
.filter(function (key) {
163-
return key !== '_familyInfo';
164-
})
165-
166-
.map(function (target) {
167-
var info = targets[family][target].info();
168-
169-
delete info.family;
170-
171-
return info;
172-
});
173-
174-
return results;
175-
}
123+
if (clients.length) {
124+
target.clients = clients;
125+
}
176126

177-
if (typeof targets[family] === 'object' && typeof targets[family][target] === 'function') {
178-
return targets[family][target].info();
179-
}
127+
return target;
128+
});
180129
};
181130

182-
module.exports.extname = function (family, target) {
183-
if (!targets[family]) {
184-
return '';
185-
}
186-
187-
if (typeof targets[family] === 'function') {
188-
return targets[family].info().extname;
189-
}
190-
191-
// get all info for all family members
192-
if (!target && typeof targets[family] === 'object') {
193-
return targets[family]._familyInfo().extname;
194-
}
131+
module.exports.extname = function (target) {
132+
return targets[target] ? targets[target].info.extname : '';
195133
};

src/mapper.js

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/reducer.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
'use strict';
2+
3+
module.exports = function (obj, pair) {
4+
if (obj[pair.name] === undefined) {
5+
obj[pair.name] = pair.value;
6+
return obj;
7+
}
8+
9+
// convert to array
10+
var arr = new Array(obj[pair.name], pair.value);
11+
12+
obj[pair.name] = arr;
13+
14+
return obj;
15+
};

src/targets/curl.js

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ module.exports = function (options) {
3838
}
3939

4040
// construct post params
41-
if (!this.source.postData.text && this.source.postData.params && this.source.postData.params.length) {
41+
if (!this.source.postData.text && this.source.postData.params) {
4242
this.source.postData.params.map(function (param) {
4343
code.push(util.format('%s "%s=%s"', opts.short ? '-F' : '--form', param.name, param.value));
4444
});
@@ -47,12 +47,10 @@ module.exports = function (options) {
4747
return code.join(opts.indent !== false ? ' \\\n' + opts.indent : ' ');
4848
};
4949

50-
module.exports.info = function () {
51-
return {
52-
key: 'curl',
53-
title: 'cURL',
54-
link: 'http://curl.haxx.se/',
55-
description: 'curl is a command line tool and library for transferring data with URL syntax',
56-
extname: '.sh'
57-
};
50+
module.exports.info = {
51+
key: 'curl',
52+
title: 'cURL',
53+
link: 'http://curl.haxx.se/',
54+
description: 'curl is a command line tool and library for transferring data with URL syntax',
55+
extname: '.sh'
5856
};

src/targets/httpie.js

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,10 @@ module.exports = function (options) {
108108
return code.join(opts.indent !== false ? ' \\\n' + opts.indent : ' ');
109109
};
110110

111-
module.exports.info = function () {
112-
return {
113-
key: 'httpie',
114-
title: 'HTTPie',
115-
link: 'http://httpie.org/',
116-
description: 'a CLI, cURL-like tool for humans',
117-
extname: '.sh'
118-
};
111+
module.exports.info = {
112+
key: 'httpie',
113+
title: 'HTTPie',
114+
link: 'http://httpie.org/',
115+
description: 'a CLI, cURL-like tool for humans',
116+
extname: '.sh'
119117
};

src/targets/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
'use strict';
22

3-
module.exports = require('requireindex')(__dirname);
3+
module.exports = require('require-directory')(module);

src/targets/node/index.js

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,3 @@
11
'use strict';
22

3-
module.exports = require('requireindex')(__dirname);
4-
5-
module.exports._familyInfo = function () {
6-
return {
7-
key: 'node',
8-
title: 'Node.JS',
9-
extname: '.js',
10-
default: 'native'
11-
};
12-
};
3+
module.exports = require('require-directory')(module);

0 commit comments

Comments
 (0)