From 08e876a74b3d5f617c5dbf79437c5f2fe5721bf7 Mon Sep 17 00:00:00 2001 From: Matthew Francis Brunetti Date: Mon, 26 Feb 2018 03:23:35 -0300 Subject: [PATCH 01/10] Configure Appveyor --- appveyor.yml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index aa0cee3e..f55b8a4b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,3 +1,13 @@ -version: 4.0.{build} -build: - verbosity: minimal +version: "{build}" +build: off +environment: + matrix: + - nodejs_version: "4" + - nodejs_version: "6" + - nodejs_version: "8" + - nodejs_version: "9" +install: + - ps: Install-Product node $env:nodejs_version + - npm install +test_script: + - npm test From 257c1d5f662328a1ef3cf34a599788991f98da38 Mon Sep 17 00:00:00 2001 From: Matthew Francis Brunetti Date: Sun, 25 Feb 2018 21:39:58 -0300 Subject: [PATCH 02/10] Don't use glob in package test script --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 104d4154..fa101feb 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/main.js", "scripts": { "pretest": "npm run lint", - "test": "lab test/* -r lcov | coveralls", + "test": "lab -r lcov | coveralls", "lint": "standard", "postlint": "npm run lint-md", "lint-md": "standard-markdown" From 1232c8efdbaae7b68b6f0cfa76ea806305c06cb5 Mon Sep 17 00:00:00 2001 From: Matthew Francis Brunetti Date: Mon, 26 Feb 2018 04:40:31 -0300 Subject: [PATCH 03/10] Report test coverage only on Travis --- .travis.yml | 4 ++++ appveyor.yml | 3 ++- package.json | 6 +++--- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3ebfa5fc..fab8b3b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,3 +5,7 @@ node_js: - 6 - 8 - 9 + +script: + - npm run lint + - npm run coverage diff --git a/appveyor.yml b/appveyor.yml index f55b8a4b..ae0252f1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,4 +10,5 @@ install: - ps: Install-Product node $env:nodejs_version - npm install test_script: - - npm test + - npm run lint + - npm run test diff --git a/package.json b/package.json index fa101feb..322e819c 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,11 @@ "description": "Loads environment variables from .env file", "main": "lib/main.js", "scripts": { - "pretest": "npm run lint", - "test": "lab -r lcov | coveralls", + "test": "lab", "lint": "standard", "postlint": "npm run lint-md", - "lint-md": "standard-markdown" + "lint-md": "standard-markdown", + "coverage": "lab -r lcov | coveralls" }, "repository": { "type": "git", From 78110996afa818eb78b9a47bd3759da8fea7f687 Mon Sep 17 00:00:00 2001 From: Matthew Francis Brunetti Date: Mon, 26 Feb 2018 05:19:28 -0300 Subject: [PATCH 04/10] Also report test *output* on Travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index fab8b3b0..263ce3dd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,4 +8,5 @@ node_js: script: - npm run lint + - npm run test - npm run coverage From 1fcf13b3c18f46b94cc922800f7007506d9b812f Mon Sep 17 00:00:00 2001 From: Matthew Francis Brunetti Date: Sun, 25 Feb 2018 21:45:07 -0300 Subject: [PATCH 05/10] Fix test; Account for possibility of spaces in node binary path --- test/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/config.js b/test/config.js index ab5b6fc2..a57feff1 100644 --- a/test/config.js +++ b/test/config.js @@ -12,7 +12,7 @@ describe('config', function () { describe('preload', function () { it('loads .env', function (done) { cp.exec( - nodeBinary + ' -r ../config -e "console.log(process.env.BASIC)" dotenv_config_path=./test/.env', + '"' + nodeBinary + '" -r ../config -e "console.log(process.env.BASIC)" dotenv_config_path=./test/.env', function (err, stdout, stderr) { if (err) { return done(err) From d25aee47ac3a5c79fdc85a478f0b4954957172d9 Mon Sep 17 00:00:00 2001 From: Matthew Francis Brunetti Date: Mon, 26 Feb 2018 06:15:19 -0300 Subject: [PATCH 06/10] Call `dotenv.parse` in lib rather than `parse` so it can be stubbed for tests 4 and 5 --- lib/main.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/main.js b/lib/main.js index 1f0df927..cc6fb924 100644 --- a/lib/main.js +++ b/lib/main.js @@ -3,12 +3,14 @@ const fs = require('fs') const path = require('path') +const dotenv = module.exports = {} + /* * Parses a string or buffer into an object * @param {(string|Buffer)} src - source to be parsed * @returns {Object} keys and values from src */ -function parse (src) { +dotenv.parse = function parse (src) { const obj = {} // convert Buffers before splitting into lines and processing @@ -45,7 +47,7 @@ function parse (src) { * @param {string} [options.encoding=utf8] - encoding of .env file * @returns {Object} parsed object or error */ -function config (options) { +dotenv.config = dotenv.load = function config (options) { let dotenvPath = path.resolve(process.cwd(), '.env') let encoding = 'utf8' @@ -60,7 +62,7 @@ function config (options) { try { // specifying an encoding returns a string instead of a buffer - const parsed = parse(fs.readFileSync(dotenvPath, { encoding })) + const parsed = dotenv.parse(fs.readFileSync(dotenvPath, { encoding })) Object.keys(parsed).forEach(function (key) { if (!process.env.hasOwnProperty(key)) { @@ -73,7 +75,3 @@ function config (options) { return { error: e } } } - -module.exports.config = config -module.exports.load = config -module.exports.parse = parse From 0a018500f6adb2470a9bdfc74d1b5980c1d5be8f Mon Sep 17 00:00:00 2001 From: Matthew Francis Brunetti Date: Mon, 26 Feb 2018 08:09:17 -0300 Subject: [PATCH 07/10] Fix test; remove incidental dependance on `typeof process.env.test` --- test/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/main.js b/test/main.js index f373ed50..8e5160b5 100644 --- a/test/main.js +++ b/test/main.js @@ -79,7 +79,7 @@ describe('dotenv', function () { // 'val' returned as value in `beforeEach`. should keep this '' dotenv.config() - process.env.test.should.eql('') + Boolean(process.env.test).should.eql(false) done() }) From 51c239e8675ec1c445fd9a4191a067007d78b86e Mon Sep 17 00:00:00 2001 From: Matthew Francis Brunetti Date: Mon, 26 Feb 2018 08:54:53 -0300 Subject: [PATCH 08/10] Update all test-related dependencies --- package.json | 8 +++--- test/main.js | 75 ++++++++++++++++++---------------------------------- 2 files changed, 29 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index 322e819c..3d87221f 100644 --- a/package.json +++ b/package.json @@ -28,10 +28,10 @@ "license": "BSD-2-Clause", "devDependencies": { "babel": "5.8.23", - "coveralls": "^2.11.9", - "lab": "11.1.0", - "should": "11.1.1", - "sinon": "1.17.6", + "coveralls": "^3.0.0", + "lab": "^15.2.2", + "should": "^13.2.1", + "sinon": "^4.4.2", "standard": "8.4.0", "standard-markdown": "2.2.0" }, diff --git a/test/main.js b/test/main.js index 8e5160b5..b28df816 100644 --- a/test/main.js +++ b/test/main.js @@ -14,170 +14,145 @@ var dotenv = require('../lib/main') var s describe('dotenv', function () { - beforeEach(function (done) { + beforeEach(function () { s = sinon.sandbox.create() - done() }) - afterEach(function (done) { + afterEach(function () { s.restore() - done() }) describe('config', function () { var readFileSyncStub, parseStub - beforeEach(function (done) { + beforeEach(function () { readFileSyncStub = s.stub(fs, 'readFileSync').returns('test=val') parseStub = s.stub(dotenv, 'parse').returns({test: 'val'}) - done() }) - it('takes option for path', function (done) { + it('takes option for path', function () { var testPath = 'test/.env' dotenv.config({path: testPath}) readFileSyncStub.args[0][0].should.eql(testPath) - done() }) - it('takes option for encoding', function (done) { + it('takes option for encoding', function () { var testEncoding = 'base64' dotenv.config({encoding: testEncoding}) readFileSyncStub.args[0][1].should.have.property('encoding', testEncoding) - done() }) - it('reads path with encoding, parsing output to process.env', function (done) { + it('reads path with encoding, parsing output to process.env', function () { dotenv.config() readFileSyncStub.callCount.should.eql(1) parseStub.callCount.should.eql(1) - done() }) - it('makes load a synonym of config', function (done) { + it('makes load a synonym of config', function () { dotenv.load() readFileSyncStub.callCount.should.eql(1) parseStub.callCount.should.eql(1) - done() }) - it('does not write over keys already in process.env', function (done) { + it('does not write over keys already in process.env', function () { process.env.test = 'test' // 'val' returned as value in `beforeEach`. should keep this 'test' dotenv.config() process.env.test.should.eql('test') - done() }) - it('does not write over keys already in process.env if the key has a falsy value', function (done) { + it('does not write over keys already in process.env if the key has a falsy value', function () { process.env.test = '' // 'val' returned as value in `beforeEach`. should keep this '' dotenv.config() Boolean(process.env.test).should.eql(false) - done() }) - it('returns parsed object', function (done) { + it('returns parsed object', function () { var env = dotenv.config() env.should.not.have.property('error') env.parsed.should.eql({ test: 'val' }) - done() }) - it('returns any errors thrown from reading file or parsing', function (done) { + it('returns any errors thrown from reading file or parsing', function () { readFileSyncStub.throws() var env = dotenv.config() env.should.have.property('error') env.error.should.be.instanceOf(Error) - done() }) }) describe('parse', function () { var parsed - before(function (done) { + before(function () { process.env.TEST = 'test' parsed = dotenv.parse(fs.readFileSync('test/.env', {encoding: 'utf8'})) - done() }) - it('should return an object', function (done) { + it('should return an object', function () { parsed.should.be.an.instanceOf(Object) - done() }) - it('should parse a buffer from a file into an object', function (done) { + it('should parse a buffer from a file into an object', function () { var buffer = new Buffer('BASIC=basic') var payload = dotenv.parse(buffer) payload.should.have.property('BASIC', 'basic') - done() }) - it('sets basic environment variable', function (done) { + it('sets basic environment variable', function () { parsed.BASIC.should.eql('basic') - done() }) - it('reads after a skipped line', function (done) { + it('reads after a skipped line', function () { parsed.AFTER_LINE.should.eql('after_line') - done() }) - it('defaults empty values to empty string', function (done) { + it('defaults empty values to empty string', function () { parsed.EMPTY.should.eql('') - done() }) - it('escapes double quoted values', function (done) { + it('escapes double quoted values', function () { parsed.DOUBLE_QUOTES.should.eql('double_quotes') - done() }) - it('escapes single quoted values', function (done) { + it('escapes single quoted values', function () { parsed.SINGLE_QUOTES.should.eql('single_quotes') - done() }) - it('expands newlines but only if double quoted', function (done) { + it('expands newlines but only if double quoted', function () { parsed.EXPAND_NEWLINES.should.eql('expand\nnewlines') parsed.DONT_EXPAND_NEWLINES_1.should.eql('dontexpand\\nnewlines') parsed.DONT_EXPAND_NEWLINES_2.should.eql('dontexpand\\nnewlines') - done() }) - it('ignores commented lines', function (done) { + it('ignores commented lines', function () { parsed.should.not.have.property('COMMENTS') - done() }) - it('respects equals signs in values', function (done) { + it('respects equals signs in values', function () { parsed.EQUAL_SIGNS.should.eql('equals==') - done() }) - it('retains inner quotes', function (done) { + it('retains inner quotes', function () { parsed.RETAIN_INNER_QUOTES.should.eql('{"foo": "bar"}') parsed.RETAIN_INNER_QUOTES_AS_STRING.should.eql('{"foo": "bar"}') - done() }) - it('retains spaces in string', function (done) { + it('retains spaces in string', function () { parsed.INCLUDE_SPACE.should.eql('some spaced out string') - done() }) - it('parses email addresses completely', function (done) { + it('parses email addresses completely', function () { parsed.should.have.property('USERNAME', 'therealnerdybeast@example.tld') - done() }) }) }) From 4b5bbcfee51b2416a3816219080fcc475e99ba35 Mon Sep 17 00:00:00 2001 From: Matthew Francis Brunetti Date: Mon, 26 Feb 2018 09:40:40 -0300 Subject: [PATCH 09/10] Revert "Update all test-related dependencies" This reverts commit 51c239e8675ec1c445fd9a4191a067007d78b86e. --- package.json | 8 +++--- test/main.js | 75 ++++++++++++++++++++++++++++++++++------------------ 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index 3d87221f..322e819c 100644 --- a/package.json +++ b/package.json @@ -28,10 +28,10 @@ "license": "BSD-2-Clause", "devDependencies": { "babel": "5.8.23", - "coveralls": "^3.0.0", - "lab": "^15.2.2", - "should": "^13.2.1", - "sinon": "^4.4.2", + "coveralls": "^2.11.9", + "lab": "11.1.0", + "should": "11.1.1", + "sinon": "1.17.6", "standard": "8.4.0", "standard-markdown": "2.2.0" }, diff --git a/test/main.js b/test/main.js index b28df816..8e5160b5 100644 --- a/test/main.js +++ b/test/main.js @@ -14,145 +14,170 @@ var dotenv = require('../lib/main') var s describe('dotenv', function () { - beforeEach(function () { + beforeEach(function (done) { s = sinon.sandbox.create() + done() }) - afterEach(function () { + afterEach(function (done) { s.restore() + done() }) describe('config', function () { var readFileSyncStub, parseStub - beforeEach(function () { + beforeEach(function (done) { readFileSyncStub = s.stub(fs, 'readFileSync').returns('test=val') parseStub = s.stub(dotenv, 'parse').returns({test: 'val'}) + done() }) - it('takes option for path', function () { + it('takes option for path', function (done) { var testPath = 'test/.env' dotenv.config({path: testPath}) readFileSyncStub.args[0][0].should.eql(testPath) + done() }) - it('takes option for encoding', function () { + it('takes option for encoding', function (done) { var testEncoding = 'base64' dotenv.config({encoding: testEncoding}) readFileSyncStub.args[0][1].should.have.property('encoding', testEncoding) + done() }) - it('reads path with encoding, parsing output to process.env', function () { + it('reads path with encoding, parsing output to process.env', function (done) { dotenv.config() readFileSyncStub.callCount.should.eql(1) parseStub.callCount.should.eql(1) + done() }) - it('makes load a synonym of config', function () { + it('makes load a synonym of config', function (done) { dotenv.load() readFileSyncStub.callCount.should.eql(1) parseStub.callCount.should.eql(1) + done() }) - it('does not write over keys already in process.env', function () { + it('does not write over keys already in process.env', function (done) { process.env.test = 'test' // 'val' returned as value in `beforeEach`. should keep this 'test' dotenv.config() process.env.test.should.eql('test') + done() }) - it('does not write over keys already in process.env if the key has a falsy value', function () { + it('does not write over keys already in process.env if the key has a falsy value', function (done) { process.env.test = '' // 'val' returned as value in `beforeEach`. should keep this '' dotenv.config() Boolean(process.env.test).should.eql(false) + done() }) - it('returns parsed object', function () { + it('returns parsed object', function (done) { var env = dotenv.config() env.should.not.have.property('error') env.parsed.should.eql({ test: 'val' }) + done() }) - it('returns any errors thrown from reading file or parsing', function () { + it('returns any errors thrown from reading file or parsing', function (done) { readFileSyncStub.throws() var env = dotenv.config() env.should.have.property('error') env.error.should.be.instanceOf(Error) + done() }) }) describe('parse', function () { var parsed - before(function () { + before(function (done) { process.env.TEST = 'test' parsed = dotenv.parse(fs.readFileSync('test/.env', {encoding: 'utf8'})) + done() }) - it('should return an object', function () { + it('should return an object', function (done) { parsed.should.be.an.instanceOf(Object) + done() }) - it('should parse a buffer from a file into an object', function () { + it('should parse a buffer from a file into an object', function (done) { var buffer = new Buffer('BASIC=basic') var payload = dotenv.parse(buffer) payload.should.have.property('BASIC', 'basic') + done() }) - it('sets basic environment variable', function () { + it('sets basic environment variable', function (done) { parsed.BASIC.should.eql('basic') + done() }) - it('reads after a skipped line', function () { + it('reads after a skipped line', function (done) { parsed.AFTER_LINE.should.eql('after_line') + done() }) - it('defaults empty values to empty string', function () { + it('defaults empty values to empty string', function (done) { parsed.EMPTY.should.eql('') + done() }) - it('escapes double quoted values', function () { + it('escapes double quoted values', function (done) { parsed.DOUBLE_QUOTES.should.eql('double_quotes') + done() }) - it('escapes single quoted values', function () { + it('escapes single quoted values', function (done) { parsed.SINGLE_QUOTES.should.eql('single_quotes') + done() }) - it('expands newlines but only if double quoted', function () { + it('expands newlines but only if double quoted', function (done) { parsed.EXPAND_NEWLINES.should.eql('expand\nnewlines') parsed.DONT_EXPAND_NEWLINES_1.should.eql('dontexpand\\nnewlines') parsed.DONT_EXPAND_NEWLINES_2.should.eql('dontexpand\\nnewlines') + done() }) - it('ignores commented lines', function () { + it('ignores commented lines', function (done) { parsed.should.not.have.property('COMMENTS') + done() }) - it('respects equals signs in values', function () { + it('respects equals signs in values', function (done) { parsed.EQUAL_SIGNS.should.eql('equals==') + done() }) - it('retains inner quotes', function () { + it('retains inner quotes', function (done) { parsed.RETAIN_INNER_QUOTES.should.eql('{"foo": "bar"}') parsed.RETAIN_INNER_QUOTES_AS_STRING.should.eql('{"foo": "bar"}') + done() }) - it('retains spaces in string', function () { + it('retains spaces in string', function (done) { parsed.INCLUDE_SPACE.should.eql('some spaced out string') + done() }) - it('parses email addresses completely', function () { + it('parses email addresses completely', function (done) { parsed.should.have.property('USERNAME', 'therealnerdybeast@example.tld') + done() }) }) }) From 042b0587b607f7eadac8a04ddbde6895da092e6e Mon Sep 17 00:00:00 2001 From: Matthew Francis Brunetti Date: Mon, 26 Feb 2018 09:45:47 -0300 Subject: [PATCH 10/10] Disable the "global variable leak detection" feature of lab --- .labrc.js | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .labrc.js diff --git a/.labrc.js b/.labrc.js new file mode 100644 index 00000000..39265f4e --- /dev/null +++ b/.labrc.js @@ -0,0 +1,3 @@ +module.exports = { + leaks: false +}