Skip to content

Commit a250c95

Browse files
committed
Tests updated to use jest
1 parent 9dc55e5 commit a250c95

File tree

13 files changed

+3610
-758
lines changed

13 files changed

+3610
-758
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
.idea/
2-
2+
coverage/
33
node_modules/

package.json

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,10 @@
1717
}
1818
],
1919
"dependencies": {
20-
"mkdirp": "~0.5.1"
20+
"mkdirp": "^1.0.4"
2121
},
2222
"devDependencies": {
23-
"@kwsites/file-exists": "^1.0.0",
24-
"expect.js": "^0.3.1",
25-
"mocha": "^6.1.4",
26-
"rimraf": "^2.6.3",
27-
"sinon": "^7.3.2"
23+
"jest": "^26.6.3"
2824
},
2925
"keywords": [
3026
"properties",
@@ -42,10 +38,36 @@
4238
"scripts": {
4339
"preversion": "npm test",
4440
"postversion": "npm publish && git push && git push --tags",
45-
"test": "mocha ./test/*.spec.js"
41+
"test": "jest --coverage"
4642
},
4743
"engines": {
4844
"node": ">=10"
4945
},
50-
"license": "MIT"
46+
"license": "MIT",
47+
"jest": {
48+
"roots": [
49+
"<rootDir>/src/",
50+
"<rootDir>/test/"
51+
],
52+
"coverageThreshold": {
53+
"global": {
54+
"branches": 80,
55+
"functions": 80,
56+
"lines": 80,
57+
"statements": 80
58+
}
59+
},
60+
"coveragePathIgnorePatterns": [
61+
"<rootDir>/test/"
62+
],
63+
"coverageReporters": [
64+
"json",
65+
"lcov",
66+
"text",
67+
"clover"
68+
],
69+
"testMatch": [
70+
"**/test/**/*.spec.*"
71+
]
72+
}
5173
}

src/properties-reader.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
const fs = require('fs');
1+
const {readFileSync, statSync} = require('fs');
22
const propertyAppender = require('./property-appender').propertyAppender;
33
const propertyWriter = require('./property-writer').propertyWriter;
44

5+
const SECTION = Symbol('SECTION');
6+
57
function PropertiesReader (sourceFile, encoding, options = {}) {
68
this._encoding = typeof encoding === 'string' && encoding || 'utf-8';
79
this._properties = {};
@@ -16,7 +18,7 @@ function PropertiesReader (sourceFile, encoding, options = {}) {
1618
* @type {String} The name of a section that should be prefixed on an property as it is added
1719
* @ignore
1820
*/
19-
PropertiesReader.prototype._section = '';
21+
PropertiesReader.prototype[SECTION] = '';
2022

2123
/**
2224
* Gets the number of properties that have been read into this PropertiesReader.
@@ -93,7 +95,7 @@ PropertiesReader.prototype.writer = function (writer) {
9395
PropertiesReader.prototype.append = function (sourceFile, encoding) {
9496

9597
if (sourceFile) {
96-
this.read(fs.readFileSync(sourceFile, typeof encoding === 'string' && encoding || this._encoding));
98+
this.read(readFileSync(sourceFile, typeof encoding === 'string' && encoding || this._encoding));
9799
}
98100

99101
return this;
@@ -106,7 +108,7 @@ PropertiesReader.prototype.append = function (sourceFile, encoding) {
106108
* @return {PropertiesReader} this instance
107109
*/
108110
PropertiesReader.prototype.read = function (input) {
109-
delete this._section;
111+
delete this[SECTION];
110112
('' + input).split('\n').forEach(this._readLine, this);
111113
return this;
112114
};
@@ -121,10 +123,10 @@ PropertiesReader.prototype._readLine = function (propertyString) {
121123
var property = !section && /^([^#=]+)(={0,1})(.*)$/.exec(propertyString);
122124

123125
if (section) {
124-
this._section = section[1];
126+
this[SECTION] = section[1];
125127
}
126128
else if (property) {
127-
section = this._section ? this._section + '.' : '';
129+
section = this[SECTION] ? this[SECTION] + '.' : '';
128130
this.set(section + property[1].trim(), property[3].trim());
129131
}
130132
}
@@ -295,15 +297,15 @@ PropertiesReader.prototype.bindToExpress = function (app, basePath, makePaths) {
295297

296298
this.each(function (key, value) {
297299
if (value && /\.(path|dir)$/.test(key)) {
298-
value = Path.join(basePath, Path.relative(basePath, value));
300+
value = Path.resolve(basePath, value);
299301
this.set(key, value);
300302

301303
try {
302304
var directoryPath = /dir$/.test(key) ? value : Path.dirname(value);
303305
if (makePaths) {
304306
require('mkdirp').sync(directoryPath);
305307
}
306-
else if (!fs.statSync(directoryPath).isDirectory()) {
308+
else if (!statSync(directoryPath).isDirectory()) {
307309
throw new Error("Path is not a directory that already exists");
308310
}
309311
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
const {join} = require('path');
2+
const {realpathSync} = require('fs');
3+
const {io} = require('./io');
4+
5+
module.exports.createTestContext = async function createTestContext () {
6+
const root = await io.mkdtemp();
7+
8+
const context = {
9+
path (...segments) {
10+
return join(root, ...segments);
11+
},
12+
async dir (...paths) {
13+
if (!paths.length) {
14+
return root;
15+
}
16+
17+
return await io.mkdir(context.path(...paths));
18+
},
19+
async file (path, content = `File content ${ path }`) {
20+
if (Array.isArray(path)) {
21+
await context.dir(path[0]);
22+
}
23+
24+
const pathArray = Array.isArray(path) ? path : [path];
25+
return await io.writeFile(context.path(...pathArray), content);
26+
},
27+
async files (...paths) {
28+
for (const path of paths) {
29+
await context.file(path);
30+
}
31+
},
32+
get root () {
33+
return root;
34+
},
35+
get rootResolvedPath () {
36+
return realpathSync(root);
37+
},
38+
};
39+
40+
return context;
41+
}

test/__fixtues__/io.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
const {existsSync, mkdir, mkdtemp, readFile, statSync, writeFile} = require('fs');
2+
3+
module.exports.io = {
4+
isdir (path) {
5+
try {
6+
return statSync(path).isDirectory();
7+
}
8+
catch (e) {
9+
return false;
10+
}
11+
},
12+
mkdir (path) {
13+
return new Promise((done, fail) => {
14+
if (existsSync(path)) {
15+
return done(path);
16+
}
17+
18+
mkdir(path, (err) => err ? fail(err) : done(path));
19+
});
20+
},
21+
mkdtemp () {
22+
return new Promise((done, fail) => {
23+
mkdtemp((process.env.TMPDIR || '/tmp/') + 'properties-reader-test-', (err, path) => {
24+
err ? fail(err) : done(path);
25+
});
26+
});
27+
},
28+
readFile (path, encoding = 'utf-8') {
29+
return new Promise((done, fail) => {
30+
readFile(path, encoding, (err, data) => {
31+
err ? fail(err) : done(data);
32+
})
33+
});
34+
},
35+
writeFile (path, content, encoding = 'utf-8') {
36+
return new Promise((done, fail) => {
37+
writeFile(path, content, encoding, (err) => {
38+
err ? fail(err) : done(path);
39+
})
40+
});
41+
},
42+
};

test/bind-to-server.spec.js

Lines changed: 51 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,76 @@
1-
const expect = require('expect.js');
2-
const {spy} = require('sinon');
1+
const {createTestContext} = require('./__fixtues__/create-test-context');
2+
const {io} = require('./__fixtues__/io');
33

4-
describe('bind-to-server', () => {
5-
6-
let properties;
4+
const propertiesReader = require('../');
75

8-
const tempFile = require('./utils/temporary-file');
9-
const {givenFilePropertiesReader} = require('./utils/bdd');
6+
describe('bind-to-server', () => {
107

11-
function givenTheProperties (content) {
12-
return properties = givenFilePropertiesReader(content);
13-
}
8+
let context;
9+
let app;
1410

15-
beforeEach(() => {
11+
beforeEach(async () => {
12+
context = await createTestContext();
13+
app = {
14+
set: jest.fn(),
15+
};
1616
});
17+
afterEach(() => jest.restoreAllMocks());
1718

18-
afterEach(() => tempFile.tearDown());
19+
it('Creates directories when necessary - absolute paths', async () => {
20+
const dirPath = context.path('foo');
21+
const file = `
22+
some.property.dir = ${ dirPath }
23+
foo.bar = A Value
24+
`;
1925

20-
it('Creates directories when necessary - absolute paths', () => {
21-
const dirPath = tempFile.pushDir('/tmp/' + Math.floor(Math.random() * 1e10).toString(16));
22-
const app = {set: spy()};
26+
propertiesReader(await context.file('properties.ini', file))
27+
.bindToExpress(app, null, true);
2328

24-
givenTheProperties(`
29+
expect(io.isdir(dirPath)).toBe(true);
30+
});
2531

32+
it('Does not create directories when already present', async () => {
33+
const dirPath = await context.dir('foo');
34+
const file = `
2635
some.property.dir = ${ dirPath }
27-
2836
foo.bar = A Value
37+
`;
2938

30-
`).bindToExpress(app, null, true);
39+
propertiesReader(await context.file('properties.ini', file))
40+
.bindToExpress(app, null, true);
3141

32-
expect(require('fs').statSync(dirPath).isDirectory()).to.be.ok();
42+
expect(io.isdir(dirPath)).toBe(true);
3343
});
3444

35-
it('Creates directories when necessary - relative paths', () => {
36-
const dirName = Math.floor(Math.random() * 1e10).toString(16);
37-
const dirBase = process.cwd();
38-
const dirPath = tempFile.pushDir(dirBase + '/' + dirName);
39-
const app = {set: spy()};
40-
41-
givenTheProperties(`
45+
it('Creates directories when necessary - relative paths', async () => {
46+
jest.spyOn(process, 'cwd').mockReturnValue(context.root);
4247

48+
const dirName = 'bar';
49+
const dirPath = context.path(dirName);
50+
const file = `
4351
some.property.dir = ${ dirName }
44-
4552
foo.bar = A Value
53+
`;
4654

47-
`).bindToExpress(app, dirBase, true);
55+
propertiesReader(await context.file('properties.ini', file))
56+
.bindToExpress(app, null, true);
4857

49-
expect(require('fs').statSync(dirPath).isDirectory()).to.be.ok();
58+
expect(io.isdir(dirPath)).toBe(true);
5059
});
5160

61+
it('Creates directories when necessary - relative path to explicit working directory', async () => {
62+
const dirName = 'bar';
63+
const dirPath = context.path(dirName);
64+
const file = `
65+
some.property.dir = ${ dirName }
66+
foo.bar = A Value
67+
`;
68+
69+
propertiesReader(await context.file('properties.ini', file))
70+
.bindToExpress(app, context.root, true);
71+
72+
expect(io.isdir(dirPath)).toBe(true);
73+
});
5274

5375
});
5476

0 commit comments

Comments
 (0)