├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── package.json ├── src └── index.js └── test ├── enums-tests.js └── spec.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | node_modules 4 | 5 | # Files created by build scripts 6 | test-es5 7 | lib -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # source 2 | src 3 | 4 | # tests 5 | test 6 | test-es5 7 | 8 | # config 9 | .travis.yml -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | before_install: 3 | - "npm install npm -g" 4 | node_js: 5 | - "node" 6 | - "iojs" 7 | env: 8 | - BUILD=build TEST_SUITE=test 9 | - BUILD=build-test-es5 TEST_SUITE=test-es5 10 | script: 11 | - npm run $BUILD 12 | - npm run $TEST_SUITE -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Liad Yosef 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Enumish 2 | =========== 3 | 4 | [![Version](http://img.shields.io/npm/v/enumish.svg)](https://www.npmjs.org/package/enumish) 5 | [![Build Status](https://travis-ci.org/liady/enumish.svg?branch=master)](https://travis-ci.org/liady/enumish) 6 | 7 | > Easily create Enum-like objects. 8 | 9 | ## Installation 10 | ```sh 11 | npm install enumish --save 12 | ``` 13 | 14 | ## Usage 15 | ### Basic 16 | Import the library and invoke it with a list of strings (for mirrored values): 17 | ```js 18 | import enums from 'enumish'; 19 | 20 | // basic usage 21 | const Directions = enums('TOP', 'LEFT', 'RIGHT', 'BOTTOM', 'CENTER'); 22 | 23 | // result 24 | Directions.TOP === 'TOP'; // true 25 | ``` 26 | ### Custom values 27 | Some of the arguments can be objects, for custom values: 28 | ```js 29 | // custom values 30 | const SideBarComponents = enums('ICON_PICKER', { 31 | LAYOUT_SELECTOR: 'LayoutSelector', 32 | COLOR_PICKER: 'ColorPickerSection' 33 | }); 34 | 35 | // result 36 | SideBarComponents.ICON_PICKER === 'ICON_PICKER'; // true 37 | SideBarComponents.LAYOUT_SELECTOR === 'LayoutSelector'; // true 38 | ``` 39 | ### Converter function 40 | You can supply the keys as an array, and a converter function for the second argument: 41 | ```js 42 | // custom converter function as the second argument 43 | const Icons = enums(['BOLD', 'ITALIC'], val => val.toLowerCase()); 44 | 45 | // result 46 | Icons.BOLD === 'bold'; // true 47 | ``` 48 | Further usage can be found in the [tests](https://github.com/liady/enumish/blob/master/test/spec.js). 49 | 50 | ## Test 51 | ```sh 52 | npm run test 53 | ``` 54 | 55 | ## Configuration 56 | Built using [Library Starter Light](https://github.com/liady/es6-lib-starter-light). 57 | 58 | ## License 59 | MIT 60 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "enumish", 3 | "description": "Create Enum-like objects easily", 4 | "version": "1.0.2", 5 | "main": "./lib/index.js", 6 | "devDependencies": { 7 | "babel-cli": "^6.2.4", 8 | "babel-plugin-transform-object-assign": "^6.5.0", 9 | "babel-preset-es2015": "^6.3.13", 10 | "babel-register": "^6.2.0", 11 | "mocha": "^2.2.5" 12 | }, 13 | "scripts": { 14 | "build": "babel src --out-dir lib", 15 | "build-test-es5": "npm run build && babel test --out-dir test-es5 && sed -i 's/\\/src\\//\\/lib\\//' test-es5/*.js", 16 | "watch": "babel src --out-dir lib --watch", 17 | "test": "mocha --ui tdd --compilers js:babel-register", 18 | "test-es5": "mocha --ui tdd test-es5", 19 | "prepublish": "npm run build" 20 | }, 21 | "babel": { 22 | "presets": ["es2015"], 23 | "plugins": ["transform-object-assign"] 24 | }, 25 | "keywords": [ 26 | "enum", 27 | "enums", 28 | "consts", 29 | "contants", 30 | "easy" 31 | ], 32 | "author": { 33 | "name": "Liad Yosef", 34 | "url": "https://github.com/liady" 35 | }, 36 | "license": "MIT", 37 | "repository": { 38 | "type": "git", 39 | "url": "https://github.com/liady/enumish" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Create constants object from descriptor 3 | */ 4 | export default function createConstants(...args) { 5 | const descriptor = args.length && Array.isArray(args[0]) ? args[0] : args; 6 | const converter = args.length && (typeof args[1] === 'function') ? args[1] : (val => val); 7 | return mergeArrayToObject(descriptor, converter); 8 | } 9 | 10 | /** 11 | * Create constants object from an array 12 | */ 13 | function mergeArrayToObject(origArr, converter) { 14 | const arr = [].concat(origArr || []); 15 | return Object.freeze(arr.reduce((obj, val) => Object.assign(obj, mirrorValue(val, converter)), {})); 16 | } 17 | 18 | /** 19 | * Create an object from a value 20 | */ 21 | function mirrorValue(val = {}, converter) { 22 | return typeof val === 'object' ? val : { [val]: converter(val) }; 23 | } -------------------------------------------------------------------------------- /test/enums-tests.js: -------------------------------------------------------------------------------- 1 | /* global test */ 2 | /* global suite */ 3 | 4 | import * as assert from 'assert'; 5 | import enums from '../src/index'; 6 | import tests from './spec'; 7 | 8 | //------------------------------------------------- 9 | suite('Enums: spread arguments', () => { 10 | 11 | test('basic', () => { 12 | const { input, expectation } = tests.BASIC; 13 | assert.ok(compareObjects(enums(...input), expectation)); 14 | }); 15 | 16 | test('handles objects', () => { 17 | const { input, expectation } = tests.OBJECTS; 18 | assert.ok(compareObjects(enums(...input), expectation)); 19 | }); 20 | 21 | test('handles overrides', () => { 22 | const { input, expectation } = tests.OVERRIDES; 23 | assert.ok(compareObjects(enums(...input), expectation)); 24 | }); 25 | 26 | test('considers only first argument if array', () => { 27 | const input = [tests.BASIC.input, tests.OBJECTS.input]; 28 | const expectation = tests.BASIC.expectation; 29 | assert.ok(compareObjects(enums(...input), expectation)); 30 | }); 31 | }); 32 | 33 | //------------------------------------------------- 34 | suite('Enums: array argument', () => { 35 | 36 | test('basic', () => { 37 | const { input, expectation } = tests.BASIC; 38 | assert.ok(compareObjects(enums(input), expectation)); 39 | }); 40 | 41 | test('handles objects', () => { 42 | const { input, expectation } = tests.OBJECTS; 43 | assert.ok(compareObjects(enums(input), expectation)); 44 | }); 45 | 46 | test('handles overrides', () => { 47 | const { input, expectation } = tests.OVERRIDES; 48 | assert.ok(compareObjects(enums(input), expectation)); 49 | }); 50 | 51 | test('respects converter function', () => { 52 | const { input, expectation } = tests.CONVERTER; 53 | assert.ok(compareObjects(enums(input, val => val.toLowerCase()), expectation)); 54 | }); 55 | 56 | }); 57 | 58 | //------------------------------------------------- 59 | suite('Enums: result object', () => { 60 | 61 | test('is frozen', () => { 62 | const CONSTANTS = enums(tests.BASIC.input); 63 | let throws = false; 64 | try { 65 | CONSTANTS['A'] = 'C'; 66 | } catch (e) { 67 | throws = true; 68 | } 69 | assert.ok(throws); 70 | }); 71 | }); 72 | 73 | //------------------------------------------------- 74 | // Helpers 75 | //------------------------------------------------- 76 | function compareObjects(a, b) { 77 | return Object.keys(a).length === Object.keys(b).length && 78 | Object.keys(a).every(val => a[val] === b[val]); 79 | } -------------------------------------------------------------------------------- /test/spec.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 3 | // spec for basic tests 4 | BASIC: { 5 | input: ['A', 'B'], 6 | expectation: { 7 | 'A': 'A', 8 | 'B': 'B' 9 | } 10 | }, 11 | 12 | // spec for testing with objects 13 | OBJECTS: { 14 | input: ['A', 'B', { 15 | 'C': 'c', 16 | 'D': 'd' 17 | }], 18 | expectation: { 19 | 'A': 'A', 20 | 'B': 'B', 21 | 'C': 'c', 22 | 'D': 'd' 23 | } 24 | }, 25 | 26 | // spec for testing overrides 27 | OVERRIDES: { 28 | input: ['A', 'B', { 29 | 'C': 'c', 30 | 'D': 'd' 31 | }, 32 | 'C', { 33 | 'A': 'a' 34 | }], 35 | expectation: { 36 | 'A': 'a', 37 | 'B': 'B', 38 | 'C': 'C', 39 | 'D': 'd' 40 | } 41 | }, 42 | 43 | // spec for testing converter function (toLowerCase) 44 | CONVERTER: { 45 | input: ['A', 'B', { 46 | 'C': 'c', 47 | 'D': 'd' 48 | }], 49 | expectation: { 50 | 'A': 'a', 51 | 'B': 'b', 52 | 'C': 'c', 53 | 'D': 'd' 54 | } 55 | } 56 | } --------------------------------------------------------------------------------