jest-haste-map
Advanced tools
Comparing version 11.0.2 to 12.0.0
{ | ||
"name": "jest-haste-map", | ||
"version": "11.0.2", | ||
"version": "12.0.0", | ||
"repository": { | ||
@@ -22,5 +22,5 @@ "type": "git", | ||
"scripts": { | ||
"prepublish": "npm test", | ||
"test": "node -e \"const spawn = require('child_process').spawn, path=require('path'); spawn('node', [path.resolve('../../bin/jest.js')], {stdio:'inherit'})\"" | ||
"test": "../../bin/jest.js" | ||
} | ||
} | ||
@@ -0,1 +1,14 @@ | ||
/** | ||
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
* @emails oncall+jsinfra | ||
* | ||
* original author: dead_horse <dead_horse@qq.com> | ||
* ported by: yaycmyk <evan@yaycmyk.com> | ||
*/ | ||
// Copyright Joyent, Inc. and other Node contributors. | ||
@@ -22,6 +35,3 @@ // | ||
/* | ||
* original author: dead_horse <dead_horse@qq.com> | ||
* ported by: yaycmyk <evan@yaycmyk.com> | ||
*/ | ||
/* eslint-disable fb-www/soft-max-len */ | ||
'use strict'; | ||
@@ -35,2 +45,13 @@ | ||
if (parseInt(process.versions.node.split('.')[0], 10) >= 5) { | ||
it('exports path directly', () => { | ||
const path = require('path'); | ||
fp = require('../fastpath'); | ||
Object.keys(path).forEach(name => { | ||
expect(path[name]).toBe(fp[name]); | ||
}); | ||
}); | ||
return; | ||
} | ||
const actualPlatform = process.platform; | ||
@@ -37,0 +58,0 @@ const invalidInputTests = [ |
@@ -7,2 +7,4 @@ /** | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
* @emails oncall+jsinfra | ||
*/ | ||
@@ -247,3 +249,5 @@ 'use strict'; | ||
}, | ||
'Strawberry': {[H.GENERIC_PLATFORM]: ['/fruits/strawberry.js', H.MODULE]}, | ||
'Strawberry': { | ||
[H.GENERIC_PLATFORM]: ['/fruits/strawberry.js', H.MODULE], | ||
}, | ||
'Melon': {[H.GENERIC_PLATFORM]: ['/vegetables/melon.js', H.MODULE]}, | ||
@@ -272,3 +276,4 @@ }); | ||
return new HasteMap(defaultConfig).build().then(data => { | ||
expect(data.map['Strawberry'][H.GENERIC_PLATFORM][0]).toEqual('/fruits/strawberry.js'); | ||
expect(data.map.Strawberry[H.GENERIC_PLATFORM][0]) | ||
.toEqual('/fruits/strawberry.js'); | ||
@@ -345,4 +350,4 @@ expect(console.warn).toBeCalledWith([ | ||
expect(fs.readFileSync.mock.calls.length).toBe(1); | ||
expect(fs.readFileSync).toBeCalledWith(cacheFilePath, 'utf-8'); | ||
expect(fs.readFileSync).toBeCalledWith(cacheFilePath, 'utf-8'); | ||
expect(data.clocks).toEqual(mockClocks); | ||
@@ -390,4 +395,4 @@ expect(data.files).toEqual(initialData.files); | ||
map['Kiwi'] = map['Banana']; | ||
delete map['Banana']; | ||
map.Kiwi = map.Banana; | ||
delete map.Banana; | ||
expect(data.map).toEqual(map); | ||
@@ -420,3 +425,3 @@ }); | ||
const map = object(initialData.map); | ||
delete map['Banana']; | ||
delete map.Banana; | ||
expect(data.map).toEqual(map); | ||
@@ -423,0 +428,0 @@ }); |
@@ -7,2 +7,4 @@ /** | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
* @emails oncall+jsinfra | ||
*/ | ||
@@ -9,0 +11,0 @@ 'use strict'; |
@@ -7,2 +7,4 @@ /** | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
* @emails oncall+jsinfra | ||
*/ | ||
@@ -92,3 +94,2 @@ 'use strict'; | ||
'/vegetables/melon.json', | ||
'/vegetables/directory', | ||
].join('\n'); | ||
@@ -109,2 +110,3 @@ | ||
'f', | ||
'\(', | ||
'-iname', | ||
@@ -115,2 +117,3 @@ '*.js', | ||
'*.json', | ||
'\)', | ||
]); | ||
@@ -117,0 +120,0 @@ |
@@ -7,2 +7,4 @@ /** | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
* @emails oncall+jsinfra | ||
*/ | ||
@@ -213,5 +215,10 @@ 'use strict'; | ||
{ | ||
name: 'banana.js', | ||
exists: true, | ||
mtime_ms: {toNumber: () => 41}, | ||
}, | ||
{ | ||
name: 'tomato.js', | ||
exists: true, | ||
mtime_ms: {toNumber: () => 43}, | ||
mtime_ms: {toNumber: () => 31}, | ||
}, | ||
@@ -228,2 +235,5 @@ ], | ||
const mockMetadata = ['Banana', 41, 1, ['Raspberry']]; | ||
mockFiles['/fruits/banana.js'] = mockMetadata; | ||
const clocks = Object.assign(Object.create(null), { | ||
@@ -251,9 +261,72 @@ '/fruits': 'c:fake-clock:1', | ||
// /fruits/strawberry.js was removed from the file list. | ||
expect(data.files).toEqual({ | ||
'/fruits/kiwi.js': ['', 42, 0, []], | ||
'/fruits/tomato.js': ['', 43, 0, []], | ||
'/fruits/banana.js': mockMetadata, | ||
'/fruits/tomato.js': mockFiles['/fruits/tomato.js'], | ||
}); | ||
// Even though the file list was reset, old file objects are still reused | ||
// if no changes have been made. | ||
expect(data.files['/fruits/banana.js']).toBe(mockMetadata); | ||
expect(data.files['/fruits/tomato.js']) | ||
.toBe(mockFiles['/fruits/tomato.js']); | ||
}); | ||
}); | ||
pit('properly resets the file map when only one watcher is reset', () => { | ||
mockResponse = { | ||
'/fruits': { | ||
version: '4.5.0', | ||
clock: 'c:fake-clock:3', | ||
is_fresh_instance: false, | ||
files: [ | ||
{ | ||
name: 'kiwi.js', | ||
exists: true, | ||
mtime_ms: {toNumber: () => 42}, | ||
}, | ||
], | ||
}, | ||
'/vegetables': { | ||
version: '4.5.0', | ||
clock: 'c:fake-clock:4', | ||
is_fresh_instance: true, | ||
files: [ | ||
{ | ||
name: 'melon.json', | ||
exists: true, | ||
mtime_ms: {toNumber: () => 33}, | ||
}, | ||
], | ||
}, | ||
}; | ||
const clocks = Object.assign(Object.create(null), { | ||
'/fruits': 'c:fake-clock:1', | ||
'/vegetables': 'c:fake-clock:2', | ||
}); | ||
return watchmanCrawl( | ||
['/fruits', '/vegetables'], | ||
['js', 'json'], | ||
pearMatcher, | ||
{ | ||
clocks, | ||
files: mockFiles, | ||
} | ||
).then(data => { | ||
expect(data.clocks).toEqual({ | ||
'/fruits': 'c:fake-clock:3', | ||
'/vegetables': 'c:fake-clock:4', | ||
}); | ||
expect(data.files).toEqual({ | ||
'/fruits/kiwi.js': ['', 42, 0, []], | ||
'/vegetables/melon.json': ['', 33, 0, []], | ||
}); | ||
}); | ||
}); | ||
}); |
@@ -65,2 +65,5 @@ /** | ||
args.push('-type', 'f'); | ||
if (extensions.length) { | ||
args.push('\('); | ||
} | ||
extensions.forEach((ext, index) => { | ||
@@ -73,2 +76,5 @@ if (index) { | ||
}); | ||
if (extensions.length) { | ||
args.push('\)'); | ||
} | ||
@@ -88,3 +94,3 @@ const child = spawn('find', args); | ||
fs.stat(path, (err, stat) => { | ||
if (stat && !stat.isDirectory()) { | ||
if (!err && stat) { | ||
result.push([path, stat.mtime.getTime()]); | ||
@@ -111,2 +117,3 @@ } | ||
} else { | ||
// See ../constants.js | ||
files[name] = ['', mtime, 0, []]; | ||
@@ -113,0 +120,0 @@ } |
@@ -31,8 +31,3 @@ /** | ||
module.exports = function watchmanCrawl( | ||
roots, | ||
extensions, | ||
ignore, | ||
data | ||
) { | ||
module.exports = function watchmanCrawl(roots, extensions, ignore, data) { | ||
const client = new watchman.Client(); | ||
@@ -42,3 +37,2 @@ const cmd = denodeify(client.command.bind(client)); | ||
let files = data.files; | ||
let reset = false; | ||
@@ -76,4 +70,13 @@ return Promise.all(roots.map(root => cmd(['watch-project', root]))) | ||
} | ||
return cmd(['query', root, query]).then(response => ({root, response})); | ||
})).then(pairs => { | ||
// Reset the file map if watchman was restarted and sends us a list of | ||
// files. | ||
if (pairs.some(pair => pair.response.is_fresh_instance)) { | ||
files = Object.create(null); | ||
} | ||
return cmd(['query', root, query]).then(response => { | ||
pairs.forEach(pair => { | ||
const root = pair.root; | ||
const response = pair.response; | ||
if ('warning' in response) { | ||
@@ -83,9 +86,2 @@ console.warn('watchman warning: ', response.warning); | ||
// Reset the file map if watchman was restarted and sends us a list of | ||
// files. | ||
if (!reset && response.is_fresh_instance) { | ||
reset = true; | ||
files = Object.create(null); | ||
} | ||
clocks[root] = response.clock; | ||
@@ -98,5 +94,9 @@ response.files.forEach(fileData => { | ||
const mtime = fileData.mtime_ms.toNumber(); | ||
const isNew = !files[name] || files[name][H.MTIME] !== mtime; | ||
const isNew = | ||
!data.files[name] || data.files[name][H.MTIME] !== mtime; | ||
if (isNew) { | ||
// See ../constants.js | ||
files[name] = ['', mtime, 0, []]; | ||
} else { | ||
files[name] = data.files[name]; | ||
} | ||
@@ -106,3 +106,3 @@ } | ||
}); | ||
})); | ||
}); | ||
}) | ||
@@ -109,0 +109,0 @@ .then(() => { |
@@ -0,1 +1,11 @@ | ||
/** | ||
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
* @emails oncall+jsinfra | ||
*/ | ||
/*! | ||
@@ -38,3 +48,8 @@ * fast-path - index.js | ||
const all = Object.keys(exports).filter(name => name !== 'replace'); | ||
// fastpath is only useful on older versions of nodejs. | ||
if (parseInt(process.versions.node.split('.')[0], 10) >= 5) { | ||
module.exports = Object.assign({replace: () => {}}, path); | ||
return; | ||
} | ||
const IS_WINDOWS = process.platform === 'win32'; | ||
@@ -606,4 +621,8 @@ | ||
if (lastSep <= start) { | ||
if (device) { return device; } | ||
if (filename[0] === '/' || filename[0] === exports.sep) { return filename[0]; } | ||
if (device) { | ||
return device; | ||
} | ||
if (filename[0] === '/' || filename[0] === exports.sep) { | ||
return filename[0]; | ||
} | ||
@@ -616,9 +635,6 @@ return '.'; | ||
exports.replace = function(props) { | ||
if (!props) { props = all; } | ||
if (!Array.isArray(props)) { props = [props]; } | ||
props.forEach(name => { | ||
if (exports[name]) { path[name] = exports[name]; } | ||
}); | ||
exports.replace = function() { | ||
Object.keys(exports) | ||
.filter(name => name !== 'replace') | ||
.forEach(name => path[name] = exports[name]); | ||
}; |
137
src/index.js
@@ -91,18 +91,18 @@ /** | ||
* The HasteMap is created as follows: | ||
* * read data from the cache or create an empty structure. | ||
* * crawl the file system. | ||
* * empty cache: crawl the entire file system. | ||
* * cache available: | ||
* * if watchman is available: get file system delta changes. | ||
* * if watchman is unavailable: crawl the entire file system. | ||
* * build metadata objects for every file. This builds the `files` part of | ||
* the `HasteMap`. | ||
* * parse and extract metadata from changed files. | ||
* * this is done in parallel over worker processes to improve performance. | ||
* * the worst case is to parse all files. | ||
* * the best case is no file system access and retrieving all data from | ||
* the cache. | ||
* 1. read data from the cache or create an empty structure. | ||
* 2. crawl the file system. | ||
* * empty cache: crawl the entire file system. | ||
* * cache available: | ||
* * if watchman is available: get file system delta changes. | ||
* * if watchman is unavailable: crawl the entire file system. | ||
* * build metadata objects for every file. This builds the `files` part of | ||
* the `HasteMap`. | ||
* 3. parse and extract metadata from changed files. | ||
* * this is done in parallel over worker processes to improve performance. | ||
* * the worst case is to parse all files. | ||
* * the best case is no file system access and retrieving all data from | ||
* the cache. | ||
* * the average case is a small number of changed files. | ||
* * serialize the new `HasteMap` in a cache file so every worker process can | ||
* directly access it through `HasteMap.read()`. | ||
* 4. serialize the new `HasteMap` in a cache file. | ||
* Worker processes can directly access the cache through `HasteMap.read()`. | ||
* | ||
@@ -135,4 +135,4 @@ */ | ||
this._options.cacheDirectory, | ||
this._options.name, | ||
VERSION, | ||
this._options.name, | ||
this._options.roots.join(':'), | ||
@@ -148,6 +148,6 @@ this._options.extensions.join(':'), | ||
static getCacheFilePath(tmpdir) { | ||
static getCacheFilePath(tmpdir, name) { | ||
const hash = crypto.createHash('md5'); | ||
Array.from(arguments).slice(1).forEach(arg => hash.update(arg)); | ||
return path.join(tmpdir, hash.digest('hex')); | ||
Array.from(arguments).slice(2).forEach(arg => hash.update(arg)); | ||
return path.join(tmpdir, name + '-' + hash.digest('hex')); | ||
} | ||
@@ -158,4 +158,4 @@ | ||
this._buildPromise = this._buildFileMap() | ||
.then(data => this._buildHasteMap(data)) | ||
.then(data => this._persist(data)); | ||
.then(fileMap => this._buildHasteMap(fileMap)) | ||
.then(hasteMap => this._persist(hasteMap)); | ||
} | ||
@@ -165,6 +165,5 @@ return this._buildPromise; | ||
read() { | ||
return this._parse(fs.readFileSync(this._cachePath, 'utf-8')); | ||
} | ||
/** | ||
* Matches all files against a pattern. | ||
*/ | ||
matchFiles(pattern) { | ||
@@ -174,5 +173,5 @@ if (!(pattern instanceof RegExp)) { | ||
} | ||
return this.build().then(data => { | ||
return this.build().then(hasteMap => { | ||
const files = []; | ||
for (const file in data.files) { | ||
for (const file in hasteMap.files) { | ||
if (pattern.test(file)) { | ||
@@ -186,7 +185,12 @@ files.push(file); | ||
_persist(data) { | ||
fs.writeFileSync(this._cachePath, JSON.stringify(data), 'utf-8'); | ||
return data; | ||
/** | ||
* 1. read data from the cache or create an empty structure. | ||
*/ | ||
read() { | ||
return this._parse(fs.readFileSync(this._cachePath, 'utf-8')); | ||
} | ||
/** | ||
* 2. crawl the file system. | ||
*/ | ||
_buildFileMap() { | ||
@@ -198,6 +202,9 @@ const read = this._options.resetCache ? this._createEmptyMap : this.read; | ||
.catch(() => this._createEmptyMap()) | ||
.then(data => this._crawl(data)); | ||
.then(hasteMap => this._crawl(hasteMap)); | ||
} | ||
_buildHasteMap(data) { | ||
/** | ||
* 3. parse and extract metadata from changed files. | ||
*/ | ||
_buildHasteMap(hasteMap) { | ||
const map = Object.create(null); | ||
@@ -230,3 +237,3 @@ const mocks = Object.create(null); | ||
for (const filePath in data.files) { | ||
for (const filePath in hasteMap.files) { | ||
if (mocksPattern && mocksPattern.test(filePath)) { | ||
@@ -236,9 +243,9 @@ mocks[path.basename(filePath, path.extname(filePath))] = filePath; | ||
const fileData = data.files[filePath]; | ||
const moduleData = data.map[fileData[H.ID]]; | ||
if (fileData[H.VISITED]) { | ||
if (!fileData[H.ID]) { | ||
const fileMetadata = hasteMap.files[filePath]; | ||
const moduleMetadata = hasteMap.map[fileMetadata[H.ID]]; | ||
if (fileMetadata[H.VISITED]) { | ||
if (!fileMetadata[H.ID]) { | ||
continue; | ||
} else if (fileData[H.ID] && moduleData) { | ||
map[fileData[H.ID]] = moduleData; | ||
} else if (fileMetadata[H.ID] && moduleMetadata) { | ||
map[fileMetadata[H.ID]] = moduleMetadata; | ||
continue; | ||
@@ -250,9 +257,10 @@ } | ||
this._getWorker()({filePath}).then( | ||
data => { | ||
fileData[H.VISITED] = 1; | ||
if (data.id) { | ||
fileData[H.ID] = data.id; | ||
setModule(data.id, data.module); | ||
metadata => { | ||
// `1` for truthy values instead of `true` to save cache space. | ||
fileMetadata[H.VISITED] = 1; | ||
if (metadata.id) { | ||
fileMetadata[H.ID] = metadata.id; | ||
setModule(metadata.id, metadata.module); | ||
} | ||
fileData[H.DEPENDENCIES] = data.dependencies || []; | ||
fileMetadata[H.DEPENDENCIES] = metadata.dependencies || []; | ||
}, | ||
@@ -262,3 +270,3 @@ error => { | ||
// ignore the failure silently. | ||
delete data.files[filePath]; | ||
delete hasteMap.files[filePath]; | ||
} | ||
@@ -278,17 +286,28 @@ ) | ||
.then(() => { | ||
data.map = map; | ||
data.mocks = mocks; | ||
return data; | ||
hasteMap.map = map; | ||
hasteMap.mocks = mocks; | ||
return hasteMap; | ||
}); | ||
} | ||
/** | ||
* 4. serialize the new `HasteMap` in a cache file. | ||
*/ | ||
_persist(hasteMap) { | ||
fs.writeFileSync(this._cachePath, JSON.stringify(hasteMap), 'utf-8'); | ||
return hasteMap; | ||
} | ||
/** | ||
* Creates workers or parses files and extracts metadata in-process. | ||
*/ | ||
_getWorker() { | ||
if (!this._workerPromise) { | ||
if (this._options.maxWorkers === 1) { | ||
this._workerPromise = data => new Promise( | ||
(resolve, reject) => worker(data, (error, data) => { | ||
this._workerPromise = message => new Promise( | ||
(resolve, reject) => worker(message, (error, metadata) => { | ||
if (error) { | ||
reject(error); | ||
} else { | ||
resolve(data); | ||
resolve(metadata); | ||
} | ||
@@ -311,11 +330,11 @@ }) | ||
_parse(data) { | ||
data = JSON.parse(data); | ||
for (const key in data) { | ||
Object.setPrototypeOf(data[key], null); | ||
_parse(hasteMap) { | ||
hasteMap = JSON.parse(hasteMap); | ||
for (const key in hasteMap) { | ||
Object.setPrototypeOf(hasteMap[key], null); | ||
} | ||
return data; | ||
return hasteMap; | ||
} | ||
_crawl(data) { | ||
_crawl(hasteMap) { | ||
const crawl = | ||
@@ -328,3 +347,3 @@ (canUseWatchman && this._options.useWatchman) ? watchmanCrawl : nodeCrawl; | ||
this._ignore.bind(this), | ||
data | ||
hasteMap | ||
); | ||
@@ -331,0 +350,0 @@ } |
@@ -8,2 +8,4 @@ /** | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
* @emails oncall+jsinfra | ||
*/ | ||
@@ -26,13 +28,23 @@ | ||
it('extracts valid docblock', () => { | ||
const code = '/**'+os.EOL+' * @providesModule foo'+os.EOL+'*/'+os.EOL+'const x = foo;'; | ||
expect(docblock.extract(code)).toBe('/**'+os.EOL+' * @providesModule foo'+os.EOL+'*/'); | ||
const code = | ||
'/**' + os.EOL + ' * @providesModule foo' + os.EOL + '*/' + os.EOL + | ||
'const x = foo;'; | ||
expect(docblock.extract(code)).toBe( | ||
'/**' + os.EOL + ' * @providesModule foo' + os.EOL + '*/' | ||
); | ||
}); | ||
it('extracts valid docblock with more comments', () => { | ||
const code = '/**'+os.EOL+' * @providesModule foo'+os.EOL+'*/'+os.EOL+'const x = foo;'+os.EOL+'/**foo*/'; | ||
expect(docblock.extract(code)).toBe('/**'+os.EOL+' * @providesModule foo'+os.EOL+'*/'); | ||
const code = | ||
'/**' + os.EOL + ' * @providesModule foo' + os.EOL + '*/' + os.EOL + | ||
'const x = foo;' + os.EOL + '/**foo*/'; | ||
expect(docblock.extract(code)).toBe( | ||
'/**' + os.EOL + ' * @providesModule foo' + os.EOL + '*/' | ||
); | ||
}); | ||
it('returns nothing for no docblock', () => { | ||
const code = '/*'+os.EOL+' * @providesModule foo'+os.EOL+'*/'+os.EOL+'const x = foo;'+os.EOL+'/**foo*/'; | ||
const code = | ||
'/*' + os.EOL + ' * @providesModule foo' + os.EOL + '*/' + os.EOL + | ||
'const x = foo;' + os.EOL + '/**foo*/'; | ||
expect(docblock.extract(code)).toBe(''); | ||
@@ -43,5 +55,5 @@ }); | ||
const code = | ||
'/** @provides module-name */'+os.EOL+'' + | ||
''+os.EOL+'' + | ||
'.dummy {}'+os.EOL+''; | ||
'/** @provides module-name */' + os.EOL + '' + | ||
'' + os.EOL + '' + | ||
'.dummy {}' + os.EOL + ''; | ||
@@ -55,6 +67,6 @@ expect(docblock.parse(docblock.extract(code))).toEqual({ | ||
const code = | ||
'/**'+os.EOL+'' + | ||
' * @providesModule foo'+os.EOL+'' + | ||
' * @css a b'+os.EOL+'' + | ||
' * @preserve-whitespace'+os.EOL+'' + | ||
'/**' + os.EOL + '' + | ||
' * @providesModule foo' + os.EOL + '' + | ||
' * @css a b' + os.EOL + '' + | ||
' * @preserve-whitespace' + os.EOL + '' + | ||
' */'; | ||
@@ -70,9 +82,9 @@ expect(docblock.parse(code)).toEqual({ | ||
const code = | ||
'/**'+os.EOL+'' + | ||
' * Copyright 2004-present Facebook. All Rights Reserved.'+os.EOL+'' + | ||
' * @providesModule foo'+os.EOL+'' + | ||
' * @css a b'+os.EOL+'' + | ||
' *'+os.EOL+'' + | ||
' * And some license here'+os.EOL+'' + | ||
' * @preserve-whitespace'+os.EOL+'' + | ||
'/**' + os.EOL + '' + | ||
' * Copyright 2004-present Facebook. All Rights Reserved.' + os.EOL + '' + | ||
' * @providesModule foo' + os.EOL + '' + | ||
' * @css a b' + os.EOL + '' + | ||
' *' + os.EOL + '' + | ||
' * And some license here' + os.EOL + '' + | ||
' * @preserve-whitespace' + os.EOL + '' + | ||
' */'; | ||
@@ -88,9 +100,9 @@ expect(docblock.parse(code)).toEqual({ | ||
const code = | ||
'/**'+os.EOL+'' + | ||
' * Copyright 2004-present Facebook. All Rights Reserved.'+os.EOL+'' + | ||
' * @class A long declaration of a class'+os.EOL+'' + | ||
' * goes here, so we can read it and enjoy'+os.EOL+'' + | ||
' *'+os.EOL+'' + | ||
' * And some license here'+os.EOL+'' + | ||
' * @preserve-whitespace'+os.EOL+'' + | ||
'/**' + os.EOL + '' + | ||
' * Copyright 2004-present Facebook. All Rights Reserved.' + os.EOL + '' + | ||
' * @class A long declaration of a class' + os.EOL + '' + | ||
' * goes here, so we can read it and enjoy' + os.EOL + '' + | ||
' *' + os.EOL + '' + | ||
' * And some license here' + os.EOL + '' + | ||
' * @preserve-whitespace' + os.EOL + '' + | ||
' */'; | ||
@@ -97,0 +109,0 @@ expect(docblock.parse(code)).toEqual({ |
@@ -8,2 +8,4 @@ /** | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
* @emails oncall+jsinfra | ||
*/ | ||
@@ -10,0 +12,0 @@ 'use strict'; |
@@ -8,2 +8,4 @@ /** | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
* @emails oncall+jsinfra | ||
*/ | ||
@@ -10,0 +12,0 @@ 'use strict'; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
100229
19
2901