Adding upstream version 1.2.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
eac40c2ddc
commit
e864a6175d
14 changed files with 584 additions and 0 deletions
7
.babelrc
Normal file
7
.babelrc
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"modules": "umd",
|
||||||
|
"loose": "all",
|
||||||
|
"compact": true,
|
||||||
|
"comments": false,
|
||||||
|
"stage": 0
|
||||||
|
}
|
50
.eslintrc
Normal file
50
.eslintrc
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
{
|
||||||
|
"parser": "babel-eslint",
|
||||||
|
"extends": "eslint:recommended",
|
||||||
|
"env": {
|
||||||
|
"browser": true
|
||||||
|
},
|
||||||
|
"ecmaFeatures": {
|
||||||
|
"modules": true,
|
||||||
|
"jsx": true
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"no-unused-vars": [1, { "args": "after-used" }],
|
||||||
|
"no-cond-assign": 1,
|
||||||
|
"semi": 2,
|
||||||
|
"camelcase": 0,
|
||||||
|
"comma-style": 2,
|
||||||
|
"comma-dangle": [2, "never"],
|
||||||
|
"indent": [2, "tab", {"SwitchCase": 1}],
|
||||||
|
"no-mixed-spaces-and-tabs": [2, "smart-tabs"],
|
||||||
|
"no-trailing-spaces": [2, { "skipBlankLines": true }],
|
||||||
|
"max-nested-callbacks": [2, 3],
|
||||||
|
"no-eval": 2,
|
||||||
|
"no-implied-eval": 2,
|
||||||
|
"no-new-func": 2,
|
||||||
|
"guard-for-in": 2,
|
||||||
|
"eqeqeq": 2,
|
||||||
|
"no-else-return": 2,
|
||||||
|
"no-redeclare": 2,
|
||||||
|
"no-dupe-keys": 2,
|
||||||
|
"radix": 2,
|
||||||
|
"strict": [2, "never"],
|
||||||
|
"no-shadow": 0,
|
||||||
|
"callback-return": [1, ["callback", "cb", "next", "done"]],
|
||||||
|
"no-delete-var": 2,
|
||||||
|
"no-undef-init": 2,
|
||||||
|
"no-shadow-restricted-names": 2,
|
||||||
|
"handle-callback-err": 0,
|
||||||
|
"no-lonely-if": 2,
|
||||||
|
"space-return-throw-case": 2,
|
||||||
|
"constructor-super": 2,
|
||||||
|
"no-this-before-super": 2,
|
||||||
|
"no-dupe-class-members": 2,
|
||||||
|
"no-const-assign": 2,
|
||||||
|
"prefer-spread": 2,
|
||||||
|
"no-useless-concat": 2,
|
||||||
|
"no-var": 2,
|
||||||
|
"object-shorthand": 2,
|
||||||
|
"prefer-arrow-callback": 2
|
||||||
|
}
|
||||||
|
}
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
npm-debug.log
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
.DS_Store
|
1
.travis.yml
Normal file
1
.travis.yml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
language: node_js
|
20
LICENSE
Normal file
20
LICENSE
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2017 Jason Miller
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
120
README.md
Normal file
120
README.md
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
# decko [](https://npmjs.com/package/decko) [](https://travis-ci.org/developit/decko)
|
||||||
|
|
||||||
|
A concise implementation of the three most useful [decorators](https://github.com/wycats/javascript-decorators):
|
||||||
|
|
||||||
|
- `@bind`: make the value of `this` constant within a method
|
||||||
|
- `@debounce`: throttle calls to a method
|
||||||
|
- `@memoize`: cache return values based on arguments
|
||||||
|
|
||||||
|
Decorators help simplify code by replacing the noise of common patterns with declarative annotations.
|
||||||
|
Conversely, decorators can also be overused and create obscurity.
|
||||||
|
Decko establishes 3 standard decorators that are immediately recognizable, so you can avoid creating decorators in your own codebase.
|
||||||
|
|
||||||
|
> 💡 **Tip:** decko is particularly well-suited to [**Preact Classful Components**](https://github.com/developit/preact).
|
||||||
|
>
|
||||||
|
> 💫 **Note:**
|
||||||
|
> - For Babel 6+, be sure to install [babel-plugin-transform-decorators-legacy](https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy).
|
||||||
|
> - For Typescript, be sure to enable `{"experimentalDecorators": true}` in your tsconfig.json.
|
||||||
|
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Available on [npm](https://npmjs.com/package/decko):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i -S decko
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Each decorator method is available as a named import.
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { bind, memoize, debounce } from 'decko';
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### `@bind`
|
||||||
|
|
||||||
|
```js
|
||||||
|
class Example {
|
||||||
|
@bind
|
||||||
|
foo() {
|
||||||
|
// the value of `this` is always the object from which foo() was referenced.
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let e = new Example();
|
||||||
|
assert.equal(e.foo.call(null), e);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `@memoize`
|
||||||
|
|
||||||
|
> Cache values returned from the decorated function.
|
||||||
|
> Uses the first argument as a cache key.
|
||||||
|
> _Cache keys are always converted to strings._
|
||||||
|
>
|
||||||
|
> ##### Options:
|
||||||
|
>
|
||||||
|
> `caseSensitive: false` - _Makes cache keys case-insensitive_
|
||||||
|
>
|
||||||
|
> `cache: {}` - _Presupply cache storage, for seeding or sharing entries_
|
||||||
|
|
||||||
|
```js
|
||||||
|
class Example {
|
||||||
|
@memoize
|
||||||
|
expensive(key) {
|
||||||
|
let start = Date.now();
|
||||||
|
while (Date.now()-start < 500) key++;
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let e = new Example();
|
||||||
|
|
||||||
|
// this takes 500ms
|
||||||
|
let one = e.expensive(1);
|
||||||
|
|
||||||
|
// this takes 0ms
|
||||||
|
let two = e.expensive(1);
|
||||||
|
|
||||||
|
// this takes 500ms
|
||||||
|
let three = e.expensive(2);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### `@debounce`
|
||||||
|
|
||||||
|
> Throttle calls to the decorated function. To debounce means "call this at most once per N ms".
|
||||||
|
> All outward function calls get collated into a single inward call, and only the latest (most recent) arguments as passed on to the debounced function.
|
||||||
|
>
|
||||||
|
> ##### Options:
|
||||||
|
>
|
||||||
|
> `delay: 0` - _The number of milliseconds to buffer calls for._
|
||||||
|
|
||||||
|
```js
|
||||||
|
class Example {
|
||||||
|
@debounce
|
||||||
|
foo() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let e = new Example();
|
||||||
|
|
||||||
|
// this will only call foo() once:
|
||||||
|
for (let i=1000; i--) e.foo();
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
MIT
|
33
package.json
Normal file
33
package.json
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"name": "decko",
|
||||||
|
"version": "1.2.0",
|
||||||
|
"main": "dist/decko.js",
|
||||||
|
"types": "dist/decko.d.ts",
|
||||||
|
"description": "A collection of the most useful property decorators.",
|
||||||
|
"scripts": {
|
||||||
|
"build": "mkdir -p dist && babel -f src/decko.js -s -o $npm_package_main < src/decko.js && npm run build:ts",
|
||||||
|
"build:ts": "cp src/decko.d.ts dist/",
|
||||||
|
"test": "npm run test:ts && eslint {src,tests}/**.js && mocha --compilers js:babel/register tests/**/*.js",
|
||||||
|
"test:ts": "tsc -p ./",
|
||||||
|
"style:ts": "tsfmt -r",
|
||||||
|
"prepublish": "npm run build",
|
||||||
|
"release": "npm run build && git commit -am $npm_package_version && git tag $npm_package_version && git push && git push --tags && npm publish"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src",
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git://github.com/developit/decko.git"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"babel": "^5.8.21",
|
||||||
|
"babel-eslint": "^4.1.6",
|
||||||
|
"chai": "^3.2.0",
|
||||||
|
"eslint": "^1.10.3",
|
||||||
|
"mocha": "^2.3.0",
|
||||||
|
"typescript": "2.1.6",
|
||||||
|
"typescript-formatter": "4.1.1"
|
||||||
|
}
|
||||||
|
}
|
30
src/decko.d.ts
vendored
Normal file
30
src/decko.d.ts
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export function bind<T>(
|
||||||
|
target: Object,
|
||||||
|
propertyKey: string | symbol,
|
||||||
|
descriptor?: TypedPropertyDescriptor<T>
|
||||||
|
): TypedPropertyDescriptor<T> | void;
|
||||||
|
export function bind(): MethodDecorator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param caseSensitive Makes cache keys case-insensitive
|
||||||
|
* @param cache Presupply cache storage, for seeding or sharing entries
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function memoize<T>(
|
||||||
|
target: Object,
|
||||||
|
propertyKey: string | symbol,
|
||||||
|
descriptor?: TypedPropertyDescriptor<T>
|
||||||
|
): TypedPropertyDescriptor<T> | void;
|
||||||
|
export function memoize(caseSensitive?: boolean, cache?: Object): MethodDecorator;
|
||||||
|
/**
|
||||||
|
* @param delay number
|
||||||
|
*/
|
||||||
|
export function debounce<T>(
|
||||||
|
target: Object,
|
||||||
|
propertyKey: string | symbol,
|
||||||
|
descriptor?: TypedPropertyDescriptor<T>
|
||||||
|
): TypedPropertyDescriptor<T> | void;
|
||||||
|
export function debounce(delay?: number): MethodDecorator;
|
98
src/decko.js
Normal file
98
src/decko.js
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
|
||||||
|
const EMPTY = {};
|
||||||
|
const HOP = Object.prototype.hasOwnProperty;
|
||||||
|
|
||||||
|
let fns = {
|
||||||
|
/** let cachedFn = memoize(originalFn); */
|
||||||
|
memoize(fn, opt=EMPTY) {
|
||||||
|
let cache = opt.cache || {};
|
||||||
|
return function(...a) {
|
||||||
|
let k = String(a[0]);
|
||||||
|
if (opt.caseSensitive===false) k = k.toLowerCase();
|
||||||
|
return HOP.call(cache,k) ? cache[k] : (cache[k] = fn.apply(this, a));
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
/** let throttled = debounce(10, console.log); */
|
||||||
|
debounce(fn, opts) {
|
||||||
|
if (typeof opts==='function') { let p = fn; fn = opts; opts = p; }
|
||||||
|
let delay = opts && opts.delay || opts || 0,
|
||||||
|
args, context, timer;
|
||||||
|
return function(...a) {
|
||||||
|
args = a;
|
||||||
|
context = this;
|
||||||
|
if (!timer) timer = setTimeout( () => {
|
||||||
|
fn.apply(context, args);
|
||||||
|
args = context = timer = null;
|
||||||
|
}, delay);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
bind(target, key, { value: fn }) {
|
||||||
|
return {
|
||||||
|
configurable: true,
|
||||||
|
get() {
|
||||||
|
let value = fn.bind(this);
|
||||||
|
Object.defineProperty(this, key, {
|
||||||
|
value,
|
||||||
|
configurable: true,
|
||||||
|
writable: true
|
||||||
|
});
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
let memoize = multiMethod(fns.memoize),
|
||||||
|
debounce = multiMethod(fns.debounce),
|
||||||
|
bind = multiMethod((f,c)=>f.bind(c), ()=>fns.bind);
|
||||||
|
|
||||||
|
export { memoize, debounce, bind };
|
||||||
|
export default { memoize, debounce, bind };
|
||||||
|
|
||||||
|
|
||||||
|
/** Creates a function that supports the following calling styles:
|
||||||
|
* d() - returns an unconfigured decorator
|
||||||
|
* d(opts) - returns a configured decorator
|
||||||
|
* d(fn, opts) - returns a decorated proxy to `fn`
|
||||||
|
* d(target, key, desc) - the decorator itself
|
||||||
|
*
|
||||||
|
* @Example:
|
||||||
|
* // simple identity deco:
|
||||||
|
* let d = multiMethod( fn => fn );
|
||||||
|
*
|
||||||
|
* class Foo {
|
||||||
|
* @d
|
||||||
|
* bar() { }
|
||||||
|
*
|
||||||
|
* @d()
|
||||||
|
* baz() { }
|
||||||
|
*
|
||||||
|
* @d({ opts })
|
||||||
|
* bat() { }
|
||||||
|
*
|
||||||
|
* bap = d(() => {})
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
function multiMethod(inner, deco) {
|
||||||
|
deco = deco || inner.decorate || decorator(inner);
|
||||||
|
let d = deco();
|
||||||
|
return (...args) => {
|
||||||
|
let l = args.length;
|
||||||
|
return (l<2 ? deco : (l>2 ? d : inner))(...args);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns function supports the forms:
|
||||||
|
* deco(target, key, desc) -> decorate a method
|
||||||
|
* deco(Fn) -> call the decorator proxy on a function
|
||||||
|
*/
|
||||||
|
function decorator(fn) {
|
||||||
|
return opt => (
|
||||||
|
typeof opt==='function' ? fn(opt) : (target, key, desc) => {
|
||||||
|
desc.value = fn(desc.value, opt, target, key, desc);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
37
tests/bind.js
Normal file
37
tests/bind.js
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import { bind } from '..';
|
||||||
|
import { expect } from 'chai';
|
||||||
|
|
||||||
|
/*global describe,it*/
|
||||||
|
|
||||||
|
describe('bind()', () => {
|
||||||
|
it('should bind when used as a simple decorator', next => {
|
||||||
|
let c = {
|
||||||
|
@bind
|
||||||
|
foo() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(c.foo()).to.equal(c);
|
||||||
|
|
||||||
|
let p = c.foo;
|
||||||
|
expect(p()).to.equal(c);
|
||||||
|
|
||||||
|
let a = {};
|
||||||
|
expect(c.foo.call(a)).to.equal(c);
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should bind when used as a function', next => {
|
||||||
|
let ctx = {},
|
||||||
|
c = bind(function(){ return this; }, ctx);
|
||||||
|
|
||||||
|
expect(c()).to.equal(ctx);
|
||||||
|
|
||||||
|
let a = {};
|
||||||
|
expect(c.call(a)).to.equal(ctx);
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
});
|
71
tests/debounce.js
Normal file
71
tests/debounce.js
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
import { debounce } from '..';
|
||||||
|
import { expect } from 'chai';
|
||||||
|
|
||||||
|
/*global describe,it*/
|
||||||
|
|
||||||
|
describe('debounce()', () => {
|
||||||
|
it('should debounce when used as a simple decorator', next => {
|
||||||
|
let c = {
|
||||||
|
calls: 0,
|
||||||
|
args: null,
|
||||||
|
|
||||||
|
@debounce
|
||||||
|
foo(...args) {
|
||||||
|
c.calls++;
|
||||||
|
c.args = args;
|
||||||
|
c.context = this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(c).to.have.property('calls', 0);
|
||||||
|
c.foo(1);
|
||||||
|
expect(c).to.have.property('calls', 0);
|
||||||
|
c.foo(2);
|
||||||
|
c.foo(3);
|
||||||
|
setTimeout( () => {
|
||||||
|
expect(c).to.have.property('calls', 1);
|
||||||
|
expect(c.args).to.deep.equal([3]);
|
||||||
|
expect(c.context).to.equal(c);
|
||||||
|
|
||||||
|
next();
|
||||||
|
}, 20);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should debounce when used as a function', next => {
|
||||||
|
let c = debounce( (...args) => {
|
||||||
|
m.calls++;
|
||||||
|
m.args = args;
|
||||||
|
}),
|
||||||
|
m = { calls:0, args:null };
|
||||||
|
|
||||||
|
expect(m).to.have.property('calls', 0);
|
||||||
|
c(1);
|
||||||
|
expect(m).to.have.property('calls', 0);
|
||||||
|
c(2);
|
||||||
|
c(3);
|
||||||
|
setTimeout( () => {
|
||||||
|
expect(m).to.have.property('calls', 1);
|
||||||
|
expect(m.args).to.deep.equal([3]);
|
||||||
|
|
||||||
|
next();
|
||||||
|
}, 20);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support passing a delay', next => {
|
||||||
|
let c = debounce(5, (...args) => {
|
||||||
|
m.calls.push(args);
|
||||||
|
}),
|
||||||
|
m = { calls:[] };
|
||||||
|
|
||||||
|
c(1);
|
||||||
|
setTimeout(()=> c(2), 1);
|
||||||
|
setTimeout(()=> c(3), 10);
|
||||||
|
setTimeout(()=> c(4), 14);
|
||||||
|
setTimeout(()=> c(5), 22);
|
||||||
|
expect(m.calls).to.have.length(0);
|
||||||
|
setTimeout( () => {
|
||||||
|
expect(m.calls).to.deep.equal([ [2], [4], [5] ]);
|
||||||
|
next();
|
||||||
|
}, 30);
|
||||||
|
});
|
||||||
|
});
|
17
tests/index.ts
Normal file
17
tests/index.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import { bind, debounce, memoize } from '..';
|
||||||
|
class C {
|
||||||
|
@bind
|
||||||
|
foo() { }
|
||||||
|
|
||||||
|
@debounce
|
||||||
|
moo() { }
|
||||||
|
|
||||||
|
@debounce(1000)
|
||||||
|
mooWithCustomDelay() { }
|
||||||
|
|
||||||
|
@memoize
|
||||||
|
mem() { }
|
||||||
|
|
||||||
|
@memoize(true)
|
||||||
|
memWithConfig() { }
|
||||||
|
}
|
72
tests/memoize.js
Normal file
72
tests/memoize.js
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
import { memoize } from '..';
|
||||||
|
import { expect } from 'chai';
|
||||||
|
|
||||||
|
/*global describe,it*/
|
||||||
|
|
||||||
|
describe('memoize()', () => {
|
||||||
|
it('should memoize when used as a simple decorator', next => {
|
||||||
|
let c = {
|
||||||
|
@memoize
|
||||||
|
foo(key) {
|
||||||
|
c[key] = (c[key] || 0) + 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(c).not.to.have.property('a');
|
||||||
|
c.foo('a');
|
||||||
|
expect(c).to.have.property('a', 1);
|
||||||
|
c.foo('a');
|
||||||
|
c.foo('a');
|
||||||
|
expect(c).to.have.property('a', 1);
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should memoize when used as a function', next => {
|
||||||
|
let c = memoize( key => {
|
||||||
|
m[key] = (m[key] || 0) + 1;
|
||||||
|
}),
|
||||||
|
m = {};
|
||||||
|
|
||||||
|
expect(m).not.to.have.property('a');
|
||||||
|
c('a');
|
||||||
|
expect(m).to.have.property('a', 1);
|
||||||
|
c('a');
|
||||||
|
c('a');
|
||||||
|
expect(m).to.have.property('a', 1);
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should memoize when called without arguments', next => {
|
||||||
|
let c = memoize( key => {
|
||||||
|
m[key] = (m[key] || 0) + 1;
|
||||||
|
}),
|
||||||
|
m = {};
|
||||||
|
|
||||||
|
expect(m).not.to.have.property('undefined');
|
||||||
|
c();
|
||||||
|
expect(m).to.have.property('undefined', 1);
|
||||||
|
c();
|
||||||
|
c();
|
||||||
|
expect(m).to.have.property('undefined', 1);
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should memoize when called with an empty string', next => {
|
||||||
|
let c = memoize( key => {
|
||||||
|
m[key] = (m[key] || 0) + 1;
|
||||||
|
}),
|
||||||
|
m = {};
|
||||||
|
|
||||||
|
expect(m).not.to.have.property('');
|
||||||
|
c('');
|
||||||
|
expect(m).to.have.property('', 1);
|
||||||
|
c('');
|
||||||
|
c('');
|
||||||
|
expect(m).to.have.property('', 1);
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
});
|
24
tsconfig.json
Normal file
24
tsconfig.json
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "es2015",
|
||||||
|
"target": "es2016",
|
||||||
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"es2016"
|
||||||
|
],
|
||||||
|
"baseUrl": "./",
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"sourceMap": false,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"strictNullChecks": true,
|
||||||
|
"declaration": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"pretty": true,
|
||||||
|
"outDir": "ts-output"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/decko.d.ts",
|
||||||
|
"tests/index.ts"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue