Skip to content

Commit

Permalink
Merge pull request #1 from evan-king/browser-support
Browse files Browse the repository at this point in the history
Code coverage and preparation for browser support
  • Loading branch information
Evan King committed Jun 19, 2016
2 parents d1319d2 + bcb8dd9 commit 21e0ec7
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 26 deletions.
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
node_modules/*
npm-debug.loc
coverage/
node_modules/
dist/
npm-debug.log
5 changes: 4 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
test.js
test/
coverage/
build.js
dist/test.js
.travis.yml
.npmignore
10 changes: 8 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
language: node_js
node_js:
- 5.3.0
- 4
- 5

script:
- ./node_modules/.bin/mocha test.js
- npm run-script travis

after_script:
- npm install coveralls@2.10.0
- cat ./coverage/lcov.info | coveralls
23 changes: 14 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
[![version][version-img]][version-url]
[![npm][npmjs-img]][npmjs-url]
[![build status][travis-img]][travis-url]
[![Coveralls][coveralls-img]][coveralls-url]
[![deps status][daviddm-img]][daviddm-url]
[![mit license][license-img]][license-url]

Expand Down Expand Up @@ -60,6 +61,10 @@ for(var key in myEnum) {
keys; // => ['a', 'c', 'b']
```

## In the Browser

Coming soon.

## API

### Construction
Expand Down Expand Up @@ -248,9 +253,9 @@ play nicely with other tools that do. For arrays only.
const colorEnum = Enum(['RED', 'BLUE', 'COUNTRY_ROSE'], Enum.idString);
colorEnum.map; // => {RED: 'red', BLUE: 'blue', COUNTRY_ROSE: 'country-rose'}
```
Provides conversion from `SCREAMING_SNAKE_CASE` to `winding-river-format`, as
Provides conversion from `SCREAMING_SNAKE` to `winding-river` format, as
an option for working with classic c-style constant naming conventions, where
string values are also needed. For objects only.
string values are also needed. For arrays only.

#### Example custom transforms

Expand Down Expand Up @@ -278,9 +283,9 @@ evenEnum.map; // => {a: 2, b: 4}
By design, primitive-enum does not allow the same value to be used as two different keys
nor as two different values. Additionally, no same value may be used as both enum key
and enum value, except in the case of matching key-value pairs where key == value. This
is partly to enforce good enum-defining conventions, and partly to minimize limitations
of using the most convenient means of performing enum lookups - which works with keys and
values interchangeably.
is partly to enforce good enum-defining conventions, but primarily to minimize limitations
of using the most concise means of performing enum lookups - which map keys and values
interchangeably.

Lastly, all enum keys and values are expected to be simple primitives, castable to strings.
Instead supplying custom objects which cast to (unique) strings may also work, but is not
Expand All @@ -290,12 +295,12 @@ explicitly supported.

The following features are planned for the 1.0 release:

- Package for client-side use (with browser testing and elimination of es6 dependencies).
- Add support for aliases (`options.aliases` probably as map of key => [alternate keys]).
- Package for client-side use (include es5-compatible `dist/primitive-enum.js` with browser test coverage).

The following feature is being (weakly) considered:
And for subsequent 1.x releases:

- Throw errors where possible when referencing an invalid enum key or value.
- Add minified source `dist/primitive-enum.min.js`.
- Add support for aliases (`options.aliases` probably as map of key => [alternate keys]).

[version-url]: https://github.com/evan-king/node-primitive-enum/releases
[version-img]: https://img.shields.io/github/release/evan-king/node-primitive-enum.svg?style=flat
Expand Down
61 changes: 61 additions & 0 deletions build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"use strict";

const
fs = require('fs'),
babel = require('babel-core'),
babelify = require('babelify'),
browserify = require('browserify'),
dependencyShim = require('browserify-global-shim');

fs.existsSync("dist") || fs.mkdirSync("dist");

const babelConfig = {
comments: false,
plugins: [
// TODO: after establishing broad-spectrum browser support, look into pruning this list
require("babel-plugin-transform-es2015-template-literals"),
require("babel-plugin-transform-es2015-literals"),
require("babel-plugin-transform-es2015-function-name"),
require("babel-plugin-transform-es2015-arrow-functions"),
require("babel-plugin-transform-es2015-block-scoped-functions"),
require("babel-plugin-transform-es2015-classes"),
require("babel-plugin-transform-es2015-object-super"),
require("babel-plugin-transform-es2015-shorthand-properties"),
require("babel-plugin-transform-es2015-duplicate-keys"),
require("babel-plugin-transform-es2015-computed-properties"),
require("babel-plugin-transform-es2015-for-of"),
require("babel-plugin-transform-es2015-sticky-regex"),
require("babel-plugin-transform-es2015-unicode-regex"),
require("babel-plugin-check-es2015-constants"),
require("babel-plugin-transform-es2015-spread"),
require("babel-plugin-transform-es2015-parameters"),
require("babel-plugin-transform-es2015-destructuring"),
require("babel-plugin-transform-es2015-block-scoping"),
require("babel-plugin-transform-es2015-typeof-symbol"),
//require("babel-plugin-transform-es2015-modules-commonjs"), // breaks exposure via global
[require("babel-plugin-transform-regenerator"), { async: false, asyncGenerators: false }],
]
};

// Transform library to valid es5 for running in browser
// (Note: must be sync else cannot share babelConfig which browserify mutates)
fs.writeFile(
'dist/primitive-enum.js',
//fs.readFileSync('./index.js')
babel.transformFileSync('./index.js', babelConfig).code
);

// Transform tests to valid es5 for running in browser
browserify()
.transform(babelify, {
comments: false,
presets: ['es2015'],
})
.transform(dependencyShim.configure({
'chai': 'chai',
'../index': 'PrimitiveEnum',
}))
.require('./test/test.js', {entry: true})
.bundle()
.on("error", err => console.log("Error: " + err.message))
.pipe(fs.createWriteStream('dist/test.js'));
27 changes: 25 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
"use strict";

(function(root) {


/**
* Enum builder - wraps arrays and maps in a function that
* supplies (precomputed) key and value lists, maps, and
Expand Down Expand Up @@ -78,7 +81,7 @@ const Enum = function PrimitiveEnumBuilder(inputMap, options) {
map[''+key] = val;
reverseMap[''+val] = key;
prop(key, val, true);
prop(val, key);
if(''+key !== ''+val) prop(val, key);
}

let transform = opts.transform;
Expand Down Expand Up @@ -164,4 +167,24 @@ eprop('resetDefaultTransforms', function() {
Enum.defaultTransform = Enum.identity;
});

module.exports = Enum;
// Determine how to publish the library
if(typeof module === 'object' && typeof module.exports === 'object') {
// Publish CommonJS module
module.exports = Enum;
} else {
// Globally expose PrimitiveEnum, allowing rollback via PrimtiveEnum.noConflict()
var origModule = root.PrimitiveEnum;
root.PrimitiveEnum = Enum;
eprop('noConflict', function() {
root.PrimitiveEnum = origModule;
return Enum;
});

if(typeof define === 'function' && define.amd) {
// Also expose as AMD
define('PrimitiveEnum', [], () => Enum);
}
}


})(this);
16 changes: 14 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
{
"name": "primitive-enum",
"version": "0.9.5",
"version": "0.9.6",
"description": "Lightweight enums with primitive datatypes",
"main": "index.js",
"scripts": {
"test": "mocha"
"test": "istanbul cover --report html -x dist/ _mocha -- test/**/*.js",
"travis": "istanbul cover --report lcovonly -x dist/ _mocha",
"posttravis": "istanbul check-coverage --statements $npm_package_config_min_coverage --branches $npm_package_config_min_coverage --lines $npm_package_config_min_coverage"
},
"config": {
"min_coverage": 60
},
"repository": {
"type": "git",
Expand All @@ -24,7 +29,14 @@
},
"homepage": "https://github.com/evan-king/node-primitive-enum#readme",
"devDependencies": {
"babel-core": "^6.7.6",
"babel-polyfill": "^6.7.4",
"babel-preset-es2015": "^6.6.0",
"babelify": "^7.2.0",
"browserify": "^13.0.0",
"browserify-global-shim": "^1.0.3",
"chai": "^3.5.0",
"istanbul": "^0.4.3",
"mocha": "^2.4.5"
}
}
31 changes: 31 additions & 0 deletions test/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>PrimitiveEnum Browser Tests</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.4.5/mocha.min.css" rel="stylesheet" />
</head>
<body>

<div id="mocha"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.4.5/mocha.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.5.0/chai.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.2.0/require.js"></script>
<script>
var PrimitiveEnum = 'original';
</script>
<script src="../dist/primitive-enum.js"></script>

<script>
mocha.checkLeaks();
mocha.setup('bdd');
</script>
<script src="../dist/test.js"></script>
<script>
mocha.run();
</script>
</body>
</html>

40 changes: 32 additions & 8 deletions test.js → test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const
expect = require('chai').expect,
Enum = require('./index');
Enum = require('../index');

describe('PrimitiveEnumBuilder', function() {

Expand All @@ -28,21 +28,21 @@ describe('PrimitiveEnumBuilder', function() {
});

it('rejects duplicate keys or values', function(done) {
expect(() => Enum(['a', 'a'])).throw;
expect(() => Enum({a: 1, b: 1})).throw;
expect(() => Enum(['a', 'a'])).throw();
expect(() => Enum({a: 1, b: 1})).throw();
done();
});

it('rejects maps with lookup conflict', function(done) {
expect(Enum.bind(null, {a: 'x', b: 'x'})).throw;
expect(Enum.bind(null, {a: 'b', b: 'c'})).throw;
expect(Enum.bind(null, ['a', 'a', 'b'])).throw;
expect(Enum.bind(null, {a: 'x', b: 'x'})).throw();
expect(Enum.bind(null, {a: 'b', b: 'c'})).throw();
expect(Enum.bind(null, ['a', 'a', 'b'])).throw();
done();
});

it('rejects enum values duplicating unrelated keys', function(done) {
expect(() => Enum({a: 'b', b: 'c'})).throw;
expect(() => Enum({a: 'a', b: 'b'})).not.throw;
expect(() => Enum({a: 'b', b: 'c'})).throw();
expect(() => Enum({a: 'a', b: 'b'})).not.throw();
done();
});

Expand Down Expand Up @@ -195,3 +195,27 @@ describe('PrimitiveEnum instances', function() {
});

});

if(typeof window === "object") {
describe('PrimitiveEnum in the browser', function() {

it('is available as an AMD module', function(done) {
requirejs(['PrimitiveEnum'], function(internal) {
const testEnum = internal(['a', 'b']);
expect(testEnum.map).eql({a: 1, b: 2});
done();
});
});

it('is available as a global', function() {
expect(window.PrimitiveEnum).eql(Enum);
});

it('supports isolation via noConflict', function() {
const LocalEnum = window.PrimitiveEnum.noConflict();
expect(LocalEnum).eql(Enum);
expect(window.PrimitiveEnum).eql('original'); // preset in test.html
});

});
}

0 comments on commit 21e0ec7

Please sign in to comment.