Skip to content

Commit cbb4b18

Browse files
authoredMay 31, 2023
chore!: Normalize repository, dropping node <10.13 support (#76)
feat: Drop just-debounce from dependencies chore: Move args processing to separate file
1 parent c994409 commit cbb4b18

22 files changed

+470
-220
lines changed
 

‎.editorconfig

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# http://editorconfig.org
1+
# https://editorconfig.org
22
root = true
33

44
[*]

‎.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
coverage/

‎.eslintrc

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
{
2-
"extends": "gulp"
2+
"extends": "gulp",
3+
"rules": {
4+
"max-statements": 0
5+
}
36
}

‎.github/support.yml

-2
This file was deleted.

‎.github/workflows/dev.yml

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
name: dev
2+
on:
3+
pull_request:
4+
push:
5+
branches:
6+
- master
7+
- main
8+
env:
9+
CI: true
10+
11+
jobs:
12+
prettier:
13+
name: Format code
14+
runs-on: ubuntu-latest
15+
if: ${{ github.event_name == 'push' }}
16+
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v2
20+
21+
- name: Prettier
22+
uses: gulpjs/prettier_action@v3.0
23+
with:
24+
commit_message: 'chore: Run prettier'
25+
prettier_options: '--write .'
26+
27+
test:
28+
name: Tests for Node ${{ matrix.node }} on ${{ matrix.os }}
29+
runs-on: ${{ matrix.os }}
30+
31+
strategy:
32+
fail-fast: false
33+
matrix:
34+
node: [10, 12, 14, 16]
35+
os: [ubuntu-latest, windows-latest, macos-latest]
36+
37+
steps:
38+
- name: Clone repository
39+
uses: actions/checkout@v2
40+
41+
- name: Set Node.js version
42+
uses: actions/setup-node@v2
43+
with:
44+
node-version: ${{ matrix.node }}
45+
46+
- run: node --version
47+
- run: npm --version
48+
49+
- name: Install npm dependencies
50+
run: npm install
51+
52+
- name: Run lint
53+
run: npm run lint
54+
55+
- name: Run tests
56+
run: npm test
57+
58+
- name: Coveralls
59+
uses: coverallsapp/github-action@v1.1.2
60+
with:
61+
github-token: ${{ secrets.GITHUB_TOKEN }}
62+
flag-name: ${{matrix.os}}-node-${{ matrix.node }}
63+
parallel: true
64+
65+
coveralls:
66+
needs: test
67+
name: Finish up
68+
69+
runs-on: ubuntu-latest
70+
steps:
71+
- name: Coveralls Finished
72+
uses: coverallsapp/github-action@v1.1.2
73+
with:
74+
github-token: ${{ secrets.GITHUB_TOKEN }}
75+
parallel-finished: true

‎.github/workflows/release.yml

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: release
2+
on:
3+
push:
4+
branches:
5+
- master
6+
- main
7+
8+
jobs:
9+
release-please:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: GoogleCloudPlatform/release-please-action@v2
13+
with:
14+
token: ${{ secrets.GITHUB_TOKEN }}
15+
release-type: node
16+
package-name: release-please-action

‎.gitignore

+43-11
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,67 @@
11
# Logs
22
logs
33
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
47

58
# Runtime data
69
pids
710
*.pid
811
*.seed
12+
*.pid.lock
913

1014
# Directory for instrumented libs generated by jscoverage/JSCover
1115
lib-cov
1216

1317
# Coverage directory used by tools like istanbul
1418
coverage
1519

16-
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
20+
# nyc test coverage
21+
.nyc_output
22+
23+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
1724
.grunt
1825

19-
# Compiled binary addons (http://nodejs.org/api/addons.html)
26+
# Bower dependency directory (https://bower.io/)
27+
bower_components
28+
29+
# node-waf configuration
30+
.lock-wscript
31+
32+
# Compiled binary addons (https://nodejs.org/api/addons.html)
2033
build/Release
2134

22-
# Dependency directory
23-
# Commenting this out is preferred by some people, see
24-
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
25-
node_modules
35+
# Dependency directories
36+
node_modules/
37+
jspm_packages/
2638

27-
# Users Environment Variables
28-
.lock-wscript
39+
# TypeScript v1 declaration files
40+
typings/
41+
42+
# Optional npm cache directory
43+
.npm
44+
45+
# Optional eslint cache
46+
.eslintcache
47+
48+
# Optional REPL history
49+
.node_repl_history
50+
51+
# Output of 'npm pack'
52+
*.tgz
53+
54+
# Yarn Integrity file
55+
.yarn-integrity
56+
57+
# dotenv environment variables file
58+
.env
59+
60+
# next.js build output
61+
.next
2962

3063
# Garbage files
3164
.DS_Store
3265

33-
# Generated by integration tests
34-
test/fixtures/tmp
35-
test/fixtures/out
66+
# Test results
67+
test.xunit

‎.jscsrc

-3
This file was deleted.

‎.npmrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock=false

‎.prettierignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
coverage/
2+
.nyc_output/
3+
CHANGELOG.md

‎.travis.yml

-13
This file was deleted.

‎LICENSE

100755100644
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2017 Blaine Bublitz <blaine.bublitz@gmail.com>, Eric Schoffstall <yo@contra.io> and other contributors
3+
Copyright (c) 2017-2018, 2020, 2022-2023 Blaine Bublitz <blaine.bublitz@gmail.com> and Eric Schoffstall <yo@contra.io>
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

‎README.md

+16-18
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<p align="center">
2-
<a href="http://gulpjs.com">
2+
<a href="https://gulpjs.com">
33
<img height="257" width="114" src="https://raw.githubusercontent.com/gulpjs/artwork/master/gulp-2x.png">
44
</a>
55
</p>
66

77
# glob-watcher
88

9-
[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![AppVeyor Build Status][appveyor-image]][appveyor-url] [![Coveralls Status][coveralls-image]][coveralls-url] [![Gitter chat][gitter-image]][gitter-url]
9+
[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Coveralls Status][coveralls-image]][coveralls-url]
1010

1111
Watch globs and execute a function upon change, with intelligent defaults for debouncing and queueing.
1212

@@ -114,24 +114,22 @@ Options are passed directly to [chokidar][chokidar].
114114

115115
MIT
116116

117-
[micromatch]: https://github.com/micromatch/micromatch
118-
[normalize-path]: https://www.npmjs.com/package/normalize-path
119-
[micromatch-backslashes]: https://github.com/micromatch/micromatch#backslashes
120-
[async-completion]: https://github.com/gulpjs/async-done#completion-and-error-resolution
121-
[chokidar]: https://github.com/paulmillr/chokidar
122-
123-
[downloads-image]: http://img.shields.io/npm/dm/glob-watcher.svg
117+
<!-- prettier-ignore-start -->
118+
[downloads-image]: https://img.shields.io/npm/dm/glob-watcher.svg?style=flat-square
124119
[npm-url]: https://npmjs.com/package/glob-watcher
125-
[npm-image]: http://img.shields.io/npm/v/glob-watcher.svg
120+
[npm-image]: https://img.shields.io/npm/v/glob-watcher.svg?style=flat-square
126121

127-
[travis-url]: https://travis-ci.org/gulpjs/glob-watcher
128-
[travis-image]: http://img.shields.io/travis/gulpjs/glob-watcher.svg?label=travis-ci
129-
130-
[appveyor-url]: https://ci.appveyor.com/project/gulpjs/glob-watcher
131-
[appveyor-image]: https://img.shields.io/appveyor/ci/gulpjs/glob-watcher.svg?label=appveyor
122+
[ci-url]: https://github.com/gulpjs/glob-watcher/actions?query=workflow:dev
123+
[ci-image]: https://img.shields.io/github/workflow/status/gulpjs/glob-watcher/dev?style=flat-square
132124

133125
[coveralls-url]: https://coveralls.io/r/gulpjs/glob-watcher
134-
[coveralls-image]: http://img.shields.io/coveralls/gulpjs/glob-watcher/master.svg
126+
[coveralls-image]: https://img.shields.io/coveralls/gulpjs/glob-watcher/master.svg?style=flat-square
127+
<!-- prettier-ignore-end -->
135128

136-
[gitter-url]: https://gitter.im/gulpjs/gulp
137-
[gitter-image]: https://badges.gitter.im/gulpjs/gulp.png
129+
<!-- prettier-ignore-start -->
130+
[micromatch]: https://github.com/micromatch/micromatch
131+
[normalize-path]: https://www.npmjs.com/package/normalize-path
132+
[micromatch-backslashes]: https://github.com/micromatch/micromatch#backslashes
133+
[async-completion]: https://github.com/gulpjs/async-done#completion-and-error-resolution
134+
[chokidar]: https://github.com/paulmillr/chokidar
135+
<!-- prettier-ignore-end -->

‎appveyor.yml

-28
This file was deleted.

‎index.js

+16-105
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,32 @@
11
'use strict';
22

33
var chokidar = require('chokidar');
4-
var debounce = require('just-debounce');
54
var asyncDone = require('async-done');
6-
var defaults = require('object.defaults/immutable');
7-
var isNegatedGlob = require('is-negated-glob');
8-
var anymatch = require('anymatch');
9-
var normalize = require('normalize-path');
5+
var normalizeArgs = require('./lib/normalize-args');
6+
var debounce = require('./lib/debounce');
107

11-
var defaultOpts = {
12-
delay: 200,
13-
events: ['add', 'change', 'unlink'],
14-
ignored: [],
15-
ignoreInitial: true,
16-
queue: true,
17-
};
18-
19-
function listenerCount(ee, evtName) {
20-
if (typeof ee.listenerCount === 'function') {
21-
return ee.listenerCount(evtName);
22-
}
23-
24-
return ee.listeners(evtName).length;
25-
}
26-
27-
function hasErrorListener(ee) {
28-
return listenerCount(ee, 'error') !== 0;
8+
function watch(glob, options, cb) {
9+
return normalizeArgs(glob, options, cb, watchProc);
2910
}
3011

31-
function exists(val) {
32-
return val != null;
12+
function watchProc(globs, options, cb) {
13+
var watcher = chokidar.watch(globs, options);
14+
registerWatchEvent(watcher, options, cb);
15+
return watcher;
3316
}
3417

35-
function watch(glob, options, cb) {
36-
if (typeof options === 'function') {
37-
cb = options;
38-
options = {};
39-
}
40-
41-
var opt = defaults(options, defaultOpts);
42-
43-
if (!Array.isArray(opt.events)) {
44-
opt.events = [opt.events];
45-
}
46-
47-
if (Array.isArray(glob)) {
48-
// We slice so we don't mutate the passed globs array
49-
glob = glob.slice();
50-
} else {
51-
glob = [glob];
18+
function registerWatchEvent(watcher, opts, cb) {
19+
if (typeof cb !== 'function') {
20+
return;
5221
}
5322

5423
var queued = false;
5524
var running = false;
5625

57-
// These use sparse arrays to keep track of the index in the
58-
// original globs array
59-
var positives = new Array(glob.length);
60-
var negatives = new Array(glob.length);
61-
62-
// Reverse the glob here so we don't end up with a positive
63-
// and negative glob in position 0 after a reverse
64-
glob.reverse().forEach(sortGlobs);
65-
66-
function sortGlobs(globString, index) {
67-
var result = isNegatedGlob(globString);
68-
if (result.negated) {
69-
negatives[index] = result.pattern;
70-
} else {
71-
positives[index] = result.pattern;
72-
}
73-
}
74-
75-
var toWatch = positives.filter(exists);
76-
77-
function joinCwd(glob) {
78-
if (glob && opt.cwd) {
79-
return normalize(opt.cwd + '/' + glob);
80-
}
81-
82-
return glob;
83-
}
84-
85-
// We only do add our custom `ignored` if there are some negative globs
86-
// TODO: I'm not sure how to test this
87-
if (negatives.some(exists)) {
88-
var normalizedPositives = positives.map(joinCwd);
89-
var normalizedNegatives = negatives.map(joinCwd);
90-
var shouldBeIgnored = function(path) {
91-
var positiveMatch = anymatch(normalizedPositives, path, true);
92-
var negativeMatch = anymatch(normalizedNegatives, path, true);
93-
// If negativeMatch is -1, that means it was never negated
94-
if (negativeMatch === -1) {
95-
return false;
96-
}
97-
98-
// If the negative is "less than" the positive, that means
99-
// it came later in the glob array before we reversed them
100-
return negativeMatch < positiveMatch;
101-
};
102-
103-
opt.ignored = [].concat(opt.ignored, shouldBeIgnored);
104-
}
105-
var watcher = chokidar.watch(toWatch, opt);
106-
10726
function runComplete(err) {
10827
running = false;
10928

110-
if (err && hasErrorListener(watcher)) {
29+
if (err && watcher.listenerCount('error') > 0) {
11130
watcher.emit('error', err);
11231
}
11332

@@ -120,7 +39,7 @@ function watch(glob, options, cb) {
12039

12140
function onChange() {
12241
if (running) {
123-
if (opt.queue) {
42+
if (opts.queue) {
12443
queued = true;
12544
}
12645
return;
@@ -130,20 +49,12 @@ function watch(glob, options, cb) {
13049
asyncDone(cb, runComplete);
13150
}
13251

133-
var fn;
134-
if (typeof cb === 'function') {
135-
fn = debounce(onChange, opt.delay);
136-
}
52+
var debounced = debounce(onChange, opts.delay);
53+
opts.events.forEach(watchEvent);
13754

13855
function watchEvent(eventName) {
139-
watcher.on(eventName, fn);
56+
watcher.on(eventName, debounced);
14057
}
141-
142-
if (fn) {
143-
opt.events.forEach(watchEvent);
144-
}
145-
146-
return watcher;
14758
}
14859

14960
module.exports = watch;

‎lib/debounce.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'use strict';
2+
3+
function debounce(fn, delay) {
4+
var timeout;
5+
var args;
6+
var self;
7+
8+
return function() {
9+
self = this;
10+
args = arguments;
11+
clear();
12+
timeout = setTimeout(run, delay);
13+
};
14+
15+
function run() {
16+
clear();
17+
fn.apply(self, args);
18+
}
19+
20+
function clear() {
21+
clearTimeout(timeout);
22+
timeout = null;
23+
}
24+
}
25+
26+
module.exports = debounce;

‎lib/normalize-args.js

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict';
2+
3+
var defaultOpts = {
4+
delay: 200,
5+
events: ['add', 'change', 'unlink'],
6+
ignored: [],
7+
ignoreInitial: true,
8+
queue: true,
9+
};
10+
11+
function normalizeArgs(glob, options, cb, next) {
12+
if (typeof options === 'function') {
13+
cb = options;
14+
options = {};
15+
}
16+
17+
var opts = Object.assign({}, defaultOpts, options);
18+
19+
if (!Array.isArray(opts.events)) {
20+
opts.events = [opts.events];
21+
}
22+
23+
if (Array.isArray(glob)) {
24+
// We slice so we don't mutate the passed globs array
25+
glob = glob.slice();
26+
} else {
27+
glob = [glob];
28+
}
29+
30+
return next(glob, opts, cb);
31+
}
32+
33+
module.exports = normalizeArgs;

‎package.json

+25-23
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,46 @@
22
"name": "glob-watcher",
33
"version": "5.0.5",
44
"description": "Watch globs and execute a function upon change, with intelligent defaults for debouncing and queueing.",
5-
"author": "Gulp Team <team@gulpjs.com> (http://gulpjs.com/)",
5+
"author": "Gulp Team <team@gulpjs.com> (https://gulpjs.com/)",
66
"contributors": [],
77
"repository": "gulpjs/glob-watcher",
88
"license": "MIT",
99
"engines": {
10-
"node": ">= 0.10"
10+
"node": ">= 10.13.0"
1111
},
1212
"main": "index.js",
1313
"files": [
14-
"index.js"
14+
"index.js",
15+
"lib/"
1516
],
1617
"scripts": {
1718
"lint": "eslint .",
1819
"pretest": "npm run lint",
19-
"test": "mocha --async-only",
20-
"cover": "istanbul cover _mocha --report lcovonly",
21-
"coveralls": "npm run cover && istanbul-coveralls"
20+
"test": "nyc mocha test test/lib --async-only"
2221
},
2322
"dependencies": {
24-
"anymatch": "^2.0.0",
25-
"async-done": "^1.2.0",
26-
"chokidar": "^2.0.0",
27-
"is-negated-glob": "^1.0.0",
28-
"just-debounce": "^1.0.0",
29-
"normalize-path": "^3.0.0",
30-
"object.defaults": "^1.1.0"
23+
"async-done": "^2.0.0",
24+
"chokidar": "^3.5.3"
3125
},
3226
"devDependencies": {
33-
"coveralls": "^2.11.2",
34-
"eslint": "^2.13.1",
35-
"eslint-config-gulp": "^3.0.1",
36-
"expect": "^1.16.0",
37-
"istanbul": "^0.4.0",
38-
"istanbul-coveralls": "^1.0.1",
39-
"mocha": "^2.0.0",
40-
"mocha-lcov-reporter": "^1.2.0",
41-
"rimraf": "^2.6.1",
42-
"through2": "^2.0.1"
27+
"eslint": "^7.32.0",
28+
"eslint-config-gulp": "^5.0.1",
29+
"expect": "^27.5.1",
30+
"mocha": "^8.4.0",
31+
"normalize-path": "^3.0.0",
32+
"nyc": "^15.1.0",
33+
"rimraf": "^3.0.2",
34+
"sinon": "^14.0.0",
35+
"through2": "^4.0.2"
36+
},
37+
"nyc": {
38+
"reporter": [
39+
"lcov",
40+
"text-summary"
41+
]
42+
},
43+
"prettier": {
44+
"singleQuote": true
4345
},
4446
"keywords": [
4547
"watch",

‎test/.eslintrc

-3
This file was deleted.

‎test/index.js

+32-11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ var fs = require('fs');
44
var path = require('path');
55

66
var expect = require('expect');
7+
var sinon = require('sinon');
78
var rimraf = require('rimraf');
89
var through = require('through2');
910
var normalizePath = require('normalize-path');
@@ -21,8 +22,8 @@ describe('glob-watcher', function() {
2122
var outFile1 = path.join(outDir, 'changed.js');
2223
var outFile2 = path.join(outDir, 'added.js');
2324
var globPattern = '**/*.js';
24-
var outGlob = normalizePath(path.join(outDir, globPattern));
25-
var singleAdd = normalizePath(path.join(outDir, 'changed.js'));
25+
var outGlob = path.join(outDir, globPattern);
26+
var singleAdd = path.join(outDir, 'changed.js');
2627
var ignoreGlob = '!' + singleAdd;
2728

2829
function changeFile() {
@@ -257,10 +258,9 @@ describe('glob-watcher', function() {
257258
});
258259

259260
it('watches exactly the given event', function(done) {
260-
var spy = expect.createSpy()
261-
.andCall(function(cb) {
261+
var spy = sinon.spy(function(cb) {
262262
cb();
263-
spy.andThrow(new Error('`Add` handler called for `change` event'));
263+
expect(spy.callCount).toEqual(1);
264264
setTimeout(done, 500);
265265
changeFile();
266266
});
@@ -271,14 +271,18 @@ describe('glob-watcher', function() {
271271
});
272272

273273
it('accepts multiple events to watch', function(done) {
274-
var spy = expect.createSpy()
275-
.andThrow(new Error('`Add`/`Unlink` handler called for `change` event'));
274+
var spy = sinon.spy(function(cb) {
275+
cb();
276+
if (spy.callCount === 2) {
277+
done();
278+
}
279+
});
276280

277-
watcher = watch(outGlob, { events: ['add', 'unlink'] }, spy);
281+
watcher = watch(outGlob, { events: ['add', 'change'] }, spy);
278282

279-
watcher.on('ready', function() {
280-
changeFile();
281-
setTimeout(done, 500);
283+
watcher.on('ready', addFile);
284+
watcher.on('add', function() {
285+
setTimeout(changeFile, 500);
282286
});
283287
});
284288

@@ -309,6 +313,23 @@ describe('glob-watcher', function() {
309313
watcher.on('ready', changeFile);
310314
});
311315

316+
it('can re-add a glob after it has been negated (unix style path)', function(done) {
317+
watcher = watch([
318+
normalizePath(outGlob),
319+
normalizePath(ignoreGlob),
320+
normalizePath(singleAdd),
321+
]);
322+
323+
watcher.once('change', function(filepath) {
324+
// chokidar pass windows style path on windows.
325+
expect(filepath).toEqual(singleAdd);
326+
done();
327+
});
328+
329+
// We default `ignoreInitial` to true, so always wait for `on('ready')`
330+
watcher.on('ready', changeFile);
331+
});
332+
312333
it('does not mutate the globs array', function(done) {
313334
var globs = [outGlob, ignoreGlob, singleAdd];
314335
watcher = watch(globs);

‎test/lib/debounce.test.js

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
'use strict';
2+
3+
var expect = require('expect');
4+
var sinon = require('sinon');
5+
var debounce = require('../../lib/debounce');
6+
7+
describe('lib/debounce', function() {
8+
9+
it('should call an original function with specified delay', function(done) {
10+
expect.assertions(1);
11+
12+
var executed = false;
13+
var fn = debounce(function() {
14+
executed = true;
15+
}, 10);
16+
17+
fn();
18+
19+
expect(executed).toBeFalsy();
20+
21+
setTimeout(function() {
22+
expect(executed).toBeTruthy();
23+
done();
24+
}, 11);
25+
});
26+
27+
it('should extend delay against multiple calls', function(done) {
28+
expect.assertions(1);
29+
30+
var fn = debounce(function(a) {
31+
expect(a).toBe(3);
32+
done();
33+
}, 50);
34+
35+
fn(1);
36+
fn(2);
37+
38+
setTimeout(function() {
39+
fn(3);
40+
}, 3);
41+
});
42+
43+
it('should extends delay if a preceding call doesn\'t run yet', function(done) {
44+
expect.assertions(1);
45+
46+
var fn = debounce(function(a) {
47+
expect(a).toBe(3);
48+
done();
49+
}, 10);
50+
51+
fn(1);
52+
53+
setTimeout(function() {
54+
fn(2);
55+
56+
setTimeout(function() {
57+
fn(3);
58+
}, 5);
59+
}, 5);
60+
});
61+
62+
it('should run if a preceding call already run', function(done) {
63+
expect.assertions(2);
64+
65+
var spy = sinon.spy(function(a) {
66+
switch (spy.callCount) {
67+
case 1:
68+
expect(a).toBe(2);
69+
break;
70+
case 2:
71+
expect(a).toBe(3);
72+
done();
73+
break;
74+
default:
75+
throw new Error();
76+
}
77+
});
78+
var fn = debounce(spy, 6);
79+
80+
fn(1);
81+
82+
setTimeout(function() {
83+
fn(2);
84+
85+
setTimeout(function() {
86+
fn(3);
87+
}, 10);
88+
}, 3);
89+
});
90+
});

‎test/lib/normalize-args.test.js

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
'use strict';
2+
3+
var expect = require('expect');
4+
var normalizeArgs = require('../../lib/normalize-args');
5+
6+
describe('lib/normalize-args', function() {
7+
8+
it('should normalize glob to an array', function(done) {
9+
var opts0 = {
10+
delay: 500,
11+
events: ['all'],
12+
ignored: ['.*.txt'],
13+
ignoreInitial: false,
14+
queue: false,
15+
persistent: true,
16+
};
17+
var cb0 = function() {};
18+
19+
normalizeArgs('*.txt', opts0, cb0, function(glob, opts, cb) {
20+
expect(Array.isArray(glob)).toBeTruthy();
21+
expect(opts).not.toBe(opts0);
22+
expect(opts).toEqual(opts0);
23+
expect(cb).toBe(cb0);
24+
done();
25+
});
26+
});
27+
28+
it('should complement options with default options', function(done) {
29+
var glob0 = ['*.txt'];
30+
var cb0 = function() {};
31+
32+
normalizeArgs(glob0, {}, cb0, function(glob, opts, cb) {
33+
expect(glob).not.toBe(glob0);
34+
expect(glob).toEqual(glob0);
35+
expect(opts).toEqual({
36+
delay: 200,
37+
events: ['add', 'change', 'unlink'],
38+
ignored: [],
39+
ignoreInitial: true,
40+
queue: true,
41+
});
42+
expect(cb).toBe(cb0);
43+
done();
44+
});
45+
});
46+
47+
it('should normalize options.events to an array', function(done) {
48+
var glob0 = ['*.txt'];
49+
var opts0 = {
50+
events: 'all',
51+
};
52+
var cb0 = function() {};
53+
54+
normalizeArgs(glob0, opts0, cb0, function(glob, opts, cb) {
55+
expect(glob).not.toBe(glob0);
56+
expect(glob).toEqual(glob0);
57+
expect(opts).toEqual({
58+
delay: 200,
59+
events: ['all'],
60+
ignored: [],
61+
ignoreInitial: true,
62+
queue: true,
63+
});
64+
expect(cb).toBe(cb0);
65+
done();
66+
});
67+
});
68+
69+
it('should change 2nd arg to cb if 2nd arg is a function', function(done) {
70+
var glob0 = ['*.txt'];
71+
var cb0 = function() {};
72+
normalizeArgs(glob0, cb0, undefined, function(glob, opts, cb) {
73+
expect(glob).not.toBe(glob0);
74+
expect(glob).toEqual(glob0);
75+
expect(opts).toEqual({
76+
delay: 200,
77+
events: ['add', 'change', 'unlink'],
78+
ignored: [],
79+
ignoreInitial: true,
80+
queue: true,
81+
});
82+
expect(cb).toBe(cb0);
83+
done();
84+
});
85+
});
86+
87+
});

0 commit comments

Comments
 (0)
Please sign in to comment.