2016-09-16 20:27:37 +01:00
|
|
|
/* @flow */
|
2016-02-15 07:32:43 +00:00
|
|
|
/* eslint quotes: 0 */
|
2016-02-10 23:00:56 +00:00
|
|
|
|
2017-08-19 19:53:54 -04:00
|
|
|
import Lockfile from '../src/lockfile';
|
2017-05-16 20:12:03 +02:00
|
|
|
import stringify from '../src/lockfile/stringify.js';
|
|
|
|
|
import parse from '../src/lockfile/parse.js';
|
|
|
|
|
import nullify from '../src/util/map.js';
|
|
|
|
|
|
2018-08-01 17:26:34 +02:00
|
|
|
const ssri = require('ssri');
|
|
|
|
|
|
2017-05-16 20:12:03 +02:00
|
|
|
const objs = [{foo: 'bar'}, {foo: {}}, {foo: 'foo', bar: 'bar'}, {foo: 5}];
|
2016-02-10 20:20:49 +00:00
|
|
|
|
2016-03-07 12:17:37 -08:00
|
|
|
let i = 0;
|
2016-10-05 16:56:53 +01:00
|
|
|
for (const obj of objs) {
|
2016-07-29 18:57:22 +09:00
|
|
|
test(`parse/stringify ${++i}`, () => {
|
2017-07-07 14:06:39 +01:00
|
|
|
expect(parse(stringify(obj)).object).toEqual(nullify(obj));
|
2016-03-07 12:17:37 -08:00
|
|
|
});
|
|
|
|
|
}
|
2016-02-10 20:20:49 +00:00
|
|
|
|
2017-05-16 20:12:03 +02:00
|
|
|
test('parse', () => {
|
2019-05-24 08:58:47 +02:00
|
|
|
// Yaml
|
|
|
|
|
expect(parse('foo:\n bar\n').object).toEqual(nullify({foo: 'bar'}));
|
|
|
|
|
|
2017-07-07 14:06:39 +01:00
|
|
|
expect(parse('foo "bar"').object).toEqual(nullify({foo: 'bar'}));
|
|
|
|
|
expect(parse('"foo" "bar"').object).toEqual(nullify({foo: 'bar'}));
|
|
|
|
|
expect(parse('foo "bar"').object).toEqual(nullify({foo: 'bar'}));
|
|
|
|
|
|
|
|
|
|
expect(parse(`foo:\n bar "bar"`).object).toEqual(nullify({foo: {bar: 'bar'}}));
|
|
|
|
|
expect(parse(`foo:\n bar:\n foo "bar"`).object).toEqual(nullify({foo: {bar: {}, foo: 'bar'}}));
|
|
|
|
|
expect(parse(`foo:\n bar:\n foo "bar"`).object).toEqual(nullify({foo: {bar: {foo: 'bar'}}}));
|
2017-09-19 10:18:29 +01:00
|
|
|
expect(parse(`foo:\r\n bar:\r\n foo "bar"`).object).toEqual(nullify({foo: {bar: {foo: 'bar'}}}));
|
2017-07-07 14:06:39 +01:00
|
|
|
expect(parse('foo:\n bar:\n yes no\nbar:\n yes no').object).toEqual(
|
2017-05-16 20:12:03 +02:00
|
|
|
nullify({
|
|
|
|
|
foo: {
|
|
|
|
|
bar: {
|
|
|
|
|
yes: 'no',
|
|
|
|
|
},
|
|
|
|
|
},
|
2016-02-17 06:59:47 +00:00
|
|
|
bar: {
|
2017-05-16 20:12:03 +02:00
|
|
|
yes: 'no',
|
2016-08-16 23:05:13 +01:00
|
|
|
},
|
2017-05-16 20:12:03 +02:00
|
|
|
}),
|
|
|
|
|
);
|
2017-09-19 10:18:29 +01:00
|
|
|
expect(parse('foo:\r\n bar:\r\n yes no\r\nbar:\r\n yes no').object).toEqual(
|
|
|
|
|
nullify({
|
|
|
|
|
foo: {
|
|
|
|
|
bar: {
|
|
|
|
|
yes: 'no',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
bar: {
|
|
|
|
|
yes: 'no',
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
);
|
2016-01-31 22:58:39 +00:00
|
|
|
});
|
|
|
|
|
|
2017-05-16 20:12:03 +02:00
|
|
|
test('stringify', () => {
|
|
|
|
|
const obj = {foo: 'bar'};
|
|
|
|
|
expect(stringify({a: obj, b: obj}, true)).toEqual('a, b:\n foo bar\n');
|
2016-02-17 06:59:47 +00:00
|
|
|
});
|
|
|
|
|
|
2017-05-16 20:12:03 +02:00
|
|
|
test('Lockfile.fromDirectory', () => {});
|
2016-02-17 06:59:47 +00:00
|
|
|
|
2017-05-16 20:12:03 +02:00
|
|
|
test('Lockfile.getLocked', () => {
|
2016-10-05 21:05:44 +09:00
|
|
|
const lockfile = new Lockfile({
|
2017-08-18 16:10:15 +01:00
|
|
|
cache: {
|
|
|
|
|
foo: 'bar',
|
|
|
|
|
bar: {},
|
|
|
|
|
},
|
2016-02-17 06:59:47 +00:00
|
|
|
});
|
2017-05-16 20:12:03 +02:00
|
|
|
expect(!!lockfile.getLocked('foo')).toBeTruthy();
|
2016-02-17 06:59:47 +00:00
|
|
|
});
|
|
|
|
|
|
2017-05-16 20:12:03 +02:00
|
|
|
test('Lockfile.getLocked pointer', () => {
|
2016-10-05 21:05:44 +09:00
|
|
|
const lockfile = new Lockfile({
|
2017-08-18 16:10:15 +01:00
|
|
|
cache: {
|
|
|
|
|
foo: 'bar',
|
|
|
|
|
bar: {},
|
|
|
|
|
},
|
2016-02-17 06:59:47 +00:00
|
|
|
});
|
2017-05-16 20:12:03 +02:00
|
|
|
expect(!!lockfile.getLocked('foo')).toBeTruthy();
|
2016-02-17 06:59:47 +00:00
|
|
|
});
|
|
|
|
|
|
2017-05-16 20:12:03 +02:00
|
|
|
test('Lockfile.getLocked no cache', () => {
|
|
|
|
|
expect(!new Lockfile().getLocked('foobar')).toBeTruthy();
|
2016-02-17 06:59:47 +00:00
|
|
|
});
|
|
|
|
|
|
2017-05-16 20:12:03 +02:00
|
|
|
test('Lockfile.getLocked defaults', () => {
|
2016-10-05 21:05:44 +09:00
|
|
|
const pattern = new Lockfile({
|
2017-08-18 16:10:15 +01:00
|
|
|
cache: {
|
|
|
|
|
foobar: {
|
|
|
|
|
version: '0.0.0',
|
|
|
|
|
},
|
2016-08-16 23:05:13 +01:00
|
|
|
},
|
2017-05-16 20:12:03 +02:00
|
|
|
}).getLocked('foobar');
|
|
|
|
|
expect(pattern.registry).toBe('npm');
|
|
|
|
|
expect(pattern.uid).toBe('0.0.0');
|
|
|
|
|
expect(pattern.version).toBe('0.0.0');
|
2016-02-17 06:59:47 +00:00
|
|
|
});
|
|
|
|
|
|
2017-05-16 20:12:03 +02:00
|
|
|
test('Lockfile.getLocked unknown', () => {
|
2017-08-18 16:10:15 +01:00
|
|
|
new Lockfile({cache: {}}).getLocked('foobar');
|
2016-02-17 06:59:47 +00:00
|
|
|
});
|
|
|
|
|
|
2017-05-16 20:12:03 +02:00
|
|
|
test('Lockfile.getLockfile', () => {
|
2016-10-05 21:05:44 +09:00
|
|
|
const patterns = {
|
2016-02-17 06:59:47 +00:00
|
|
|
foobar: {
|
2017-05-16 20:12:03 +02:00
|
|
|
name: 'foobar',
|
|
|
|
|
version: '0.0.0',
|
|
|
|
|
_uid: '0.0.0',
|
2016-02-17 06:59:47 +00:00
|
|
|
dependencies: {},
|
|
|
|
|
optionalDependencies: {},
|
2016-08-22 16:37:11 +01:00
|
|
|
_reference: {
|
2016-08-16 23:05:13 +01:00
|
|
|
permissions: {},
|
2016-02-17 06:59:47 +00:00
|
|
|
},
|
2016-08-22 16:37:11 +01:00
|
|
|
_remote: {
|
2017-05-16 20:12:03 +02:00
|
|
|
resolved: 'http://example.com/foobar',
|
|
|
|
|
registry: 'npm',
|
2016-08-16 23:05:13 +01:00
|
|
|
},
|
2016-02-17 06:59:47 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
barfoo: {
|
2017-05-16 20:12:03 +02:00
|
|
|
name: 'barfoo',
|
|
|
|
|
version: '0.0.1',
|
|
|
|
|
_uid: '0.1.0',
|
2016-02-17 06:59:47 +00:00
|
|
|
dependencies: {
|
2017-05-16 20:12:03 +02:00
|
|
|
yes: 'no',
|
2016-02-17 06:59:47 +00:00
|
|
|
},
|
|
|
|
|
optionalDependencies: {
|
2017-05-16 20:12:03 +02:00
|
|
|
no: 'yes',
|
2016-02-17 06:59:47 +00:00
|
|
|
},
|
2016-08-22 16:37:11 +01:00
|
|
|
_reference: {
|
2016-02-17 06:59:47 +00:00
|
|
|
permissions: {
|
2017-05-16 20:12:03 +02:00
|
|
|
foo: 'bar',
|
2016-08-16 23:05:13 +01:00
|
|
|
},
|
2016-02-17 06:59:47 +00:00
|
|
|
},
|
2016-08-22 16:37:11 +01:00
|
|
|
_remote: {
|
2017-05-16 20:12:03 +02:00
|
|
|
resolved: 'http://example.com/barfoo',
|
|
|
|
|
registry: 'yarn',
|
2016-08-16 23:05:13 +01:00
|
|
|
},
|
2016-07-21 11:35:13 +01:00
|
|
|
},
|
|
|
|
|
|
2017-05-16 20:12:03 +02:00
|
|
|
'foobar@2': {},
|
2016-02-17 06:59:47 +00:00
|
|
|
};
|
|
|
|
|
|
2017-05-16 20:12:03 +02:00
|
|
|
patterns['foobar@2'] = patterns.foobar;
|
2016-02-17 06:59:47 +00:00
|
|
|
|
2016-10-05 21:05:44 +09:00
|
|
|
const actual = new Lockfile().getLockfile(patterns);
|
2016-02-17 06:59:47 +00:00
|
|
|
|
2016-10-05 21:05:44 +09:00
|
|
|
const expectedFoobar = {
|
2017-05-16 20:12:03 +02:00
|
|
|
version: '0.0.0',
|
2016-07-18 15:20:10 +01:00
|
|
|
uid: undefined,
|
2017-05-16 20:12:03 +02:00
|
|
|
resolved: 'http://example.com/foobar',
|
2016-07-18 15:20:10 +01:00
|
|
|
registry: undefined,
|
|
|
|
|
dependencies: undefined,
|
|
|
|
|
optionalDependencies: undefined,
|
2016-08-16 23:05:13 +01:00
|
|
|
permissions: undefined,
|
2016-07-18 15:20:10 +01:00
|
|
|
};
|
|
|
|
|
|
2016-10-05 21:05:44 +09:00
|
|
|
const expected = {
|
2016-02-17 06:59:47 +00:00
|
|
|
barfoo: {
|
2017-05-16 20:12:03 +02:00
|
|
|
version: '0.0.1',
|
|
|
|
|
uid: '0.1.0',
|
|
|
|
|
resolved: 'http://example.com/barfoo',
|
|
|
|
|
registry: 'yarn',
|
|
|
|
|
dependencies: {yes: 'no'},
|
|
|
|
|
optionalDependencies: {no: 'yes'},
|
|
|
|
|
permissions: {foo: 'bar'},
|
2016-02-17 06:59:47 +00:00
|
|
|
},
|
2016-08-24 04:12:53 +01:00
|
|
|
foobar: expectedFoobar,
|
2017-05-16 20:12:03 +02:00
|
|
|
'foobar@2': expectedFoobar,
|
2016-02-17 06:59:47 +00:00
|
|
|
};
|
|
|
|
|
|
2016-07-29 18:57:22 +09:00
|
|
|
expect(actual).toEqual(expected);
|
2016-02-17 06:59:47 +00:00
|
|
|
});
|
2016-07-13 17:59:04 +01:00
|
|
|
|
2017-05-16 20:12:03 +02:00
|
|
|
test('Lockfile.getLockfile (sorting)', () => {
|
2016-10-05 21:05:44 +09:00
|
|
|
const patterns = {
|
2016-07-13 17:59:04 +01:00
|
|
|
foobar2: {
|
2017-05-16 20:12:03 +02:00
|
|
|
name: 'foobar',
|
|
|
|
|
version: '0.0.0',
|
|
|
|
|
uid: '0.0.0',
|
2016-07-13 17:59:04 +01:00
|
|
|
dependencies: {},
|
|
|
|
|
optionalDependencies: {},
|
2016-08-22 16:37:11 +01:00
|
|
|
_reference: {
|
2016-08-16 23:05:13 +01:00
|
|
|
permissions: {},
|
2016-07-13 17:59:04 +01:00
|
|
|
},
|
2016-08-22 16:37:11 +01:00
|
|
|
_remote: {
|
2017-05-16 20:12:03 +02:00
|
|
|
resolved: 'http://example.com/foobar',
|
|
|
|
|
registry: 'npm',
|
2016-08-16 23:05:13 +01:00
|
|
|
},
|
2016-07-13 17:59:04 +01:00
|
|
|
},
|
2016-07-21 11:35:13 +01:00
|
|
|
|
2016-08-16 23:05:13 +01:00
|
|
|
foobar1: {},
|
2016-07-13 17:59:04 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
patterns.foobar1 = patterns.foobar2;
|
|
|
|
|
|
2016-10-05 21:05:44 +09:00
|
|
|
const actual = new Lockfile().getLockfile(patterns);
|
2016-07-13 17:59:04 +01:00
|
|
|
|
2016-10-05 21:05:44 +09:00
|
|
|
const expectedFoobar = {
|
2017-05-16 20:12:03 +02:00
|
|
|
name: 'foobar',
|
|
|
|
|
version: '0.0.0',
|
2016-07-18 15:20:10 +01:00
|
|
|
uid: undefined,
|
2017-05-16 20:12:03 +02:00
|
|
|
resolved: 'http://example.com/foobar',
|
2016-07-18 15:20:10 +01:00
|
|
|
registry: undefined,
|
|
|
|
|
dependencies: undefined,
|
|
|
|
|
optionalDependencies: undefined,
|
2016-08-16 23:05:13 +01:00
|
|
|
permissions: undefined,
|
2016-07-18 15:20:10 +01:00
|
|
|
};
|
2016-07-13 17:59:04 +01:00
|
|
|
|
2016-10-05 21:05:44 +09:00
|
|
|
const expected = {
|
2016-07-18 15:20:10 +01:00
|
|
|
foobar1: expectedFoobar,
|
2016-08-16 23:05:13 +01:00
|
|
|
foobar2: expectedFoobar,
|
2016-07-13 17:59:04 +01:00
|
|
|
};
|
|
|
|
|
|
2016-07-29 18:57:22 +09:00
|
|
|
expect(actual).toEqual(expected);
|
2016-07-13 17:59:04 +01:00
|
|
|
});
|
2017-07-07 14:06:39 +01:00
|
|
|
|
2018-08-01 17:26:34 +02:00
|
|
|
test('Lockfile.getLockfile handles integrity field', () => {
|
|
|
|
|
const integrity = ssri.parse('sha1-foo sha512-bar');
|
|
|
|
|
const patterns = {
|
|
|
|
|
foobar: {
|
|
|
|
|
name: 'foobar',
|
|
|
|
|
version: '0.0.0',
|
|
|
|
|
uid: '0.0.0',
|
|
|
|
|
dependencies: {},
|
|
|
|
|
optionalDependencies: {},
|
|
|
|
|
_reference: {
|
|
|
|
|
permissions: {},
|
|
|
|
|
},
|
|
|
|
|
_remote: {
|
|
|
|
|
resolved: 'http://example.com/foobar',
|
|
|
|
|
registry: 'npm',
|
|
|
|
|
integrity,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const actual = new Lockfile().getLockfile(patterns);
|
|
|
|
|
|
|
|
|
|
const expected = {
|
|
|
|
|
foobar: {
|
|
|
|
|
version: '0.0.0',
|
|
|
|
|
uid: undefined,
|
|
|
|
|
resolved: 'http://example.com/foobar',
|
|
|
|
|
registry: undefined,
|
|
|
|
|
dependencies: undefined,
|
|
|
|
|
optionalDependencies: undefined,
|
|
|
|
|
permissions: undefined,
|
|
|
|
|
integrity: integrity.toString().split(' ').sort().join(' '),
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
expect(actual).toEqual(expected);
|
|
|
|
|
});
|
|
|
|
|
|
2017-07-07 14:06:39 +01:00
|
|
|
test('parse single merge conflict', () => {
|
|
|
|
|
const file = `
|
|
|
|
|
a:
|
|
|
|
|
no "yes"
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
b:
|
|
|
|
|
foo "bar"
|
|
|
|
|
=======
|
|
|
|
|
c:
|
|
|
|
|
bar "foo"
|
|
|
|
|
>>>>>>> branch-a
|
|
|
|
|
|
|
|
|
|
d:
|
|
|
|
|
yes "no"
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const {type, object} = parse(file);
|
|
|
|
|
expect(type).toEqual('merge');
|
|
|
|
|
expect(object).toEqual({
|
|
|
|
|
a: {no: 'yes'},
|
|
|
|
|
b: {foo: 'bar'},
|
|
|
|
|
c: {bar: 'foo'},
|
|
|
|
|
d: {yes: 'no'},
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-09-19 10:18:29 +01:00
|
|
|
test('parse single merge conflict with CRLF', () => {
|
|
|
|
|
const file =
|
|
|
|
|
'a:\r\n no "yes"\r\n\r\n<<<<<<< HEAD\r\nb:\r\n foo "bar"' +
|
|
|
|
|
'\r\n=======\r\nc:\r\n bar "foo"\r\n>>>>>>> branch-a' +
|
|
|
|
|
'\r\n\r\nd:\r\n yes "no"\r\n';
|
|
|
|
|
|
|
|
|
|
const {type, object} = parse(file);
|
|
|
|
|
expect(type).toEqual('merge');
|
|
|
|
|
expect(object).toEqual({
|
|
|
|
|
a: {no: 'yes'},
|
|
|
|
|
b: {foo: 'bar'},
|
|
|
|
|
c: {bar: 'foo'},
|
|
|
|
|
d: {yes: 'no'},
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-07-07 14:06:39 +01:00
|
|
|
test('parse multiple merge conflicts', () => {
|
|
|
|
|
const file = `
|
|
|
|
|
a:
|
|
|
|
|
no "yes"
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
b:
|
|
|
|
|
foo "bar"
|
|
|
|
|
=======
|
|
|
|
|
c:
|
|
|
|
|
bar "foo"
|
|
|
|
|
>>>>>>> branch-a
|
|
|
|
|
|
|
|
|
|
d:
|
|
|
|
|
yes "no"
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
e:
|
|
|
|
|
foo "bar"
|
|
|
|
|
=======
|
|
|
|
|
f:
|
|
|
|
|
bar "foo"
|
|
|
|
|
>>>>>>> branch-b
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const {type, object} = parse(file);
|
|
|
|
|
expect(type).toEqual('merge');
|
|
|
|
|
expect(object).toEqual({
|
|
|
|
|
a: {no: 'yes'},
|
|
|
|
|
b: {foo: 'bar'},
|
|
|
|
|
c: {bar: 'foo'},
|
|
|
|
|
d: {yes: 'no'},
|
|
|
|
|
e: {foo: 'bar'},
|
|
|
|
|
f: {bar: 'foo'},
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('parse merge conflict fail', () => {
|
|
|
|
|
const file = `
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
b:
|
2019-05-24 08:58:47 +02:00
|
|
|
foo: "bar
|
2017-07-07 14:06:39 +01:00
|
|
|
=======
|
|
|
|
|
c:
|
|
|
|
|
bar "foo"
|
|
|
|
|
>>>>>>> branch-a
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const {type, object} = parse(file);
|
|
|
|
|
expect(type).toEqual('conflict');
|
|
|
|
|
expect(Object.keys(object).length).toEqual(0);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('discards common ancestors in merge conflicts', () => {
|
|
|
|
|
const file = `
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
b:
|
|
|
|
|
foo "bar"
|
|
|
|
|
||||||| common ancestor
|
|
|
|
|
d:
|
|
|
|
|
yes "no"
|
|
|
|
|
=======
|
|
|
|
|
c:
|
|
|
|
|
bar "foo"
|
|
|
|
|
>>>>>>> branch-a
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const {type, object} = parse(file);
|
|
|
|
|
expect(type).toEqual('merge');
|
|
|
|
|
expect(object).toEqual({
|
|
|
|
|
b: {foo: 'bar'},
|
|
|
|
|
c: {bar: 'foo'},
|
|
|
|
|
});
|
|
|
|
|
expect(object.d).toBe(undefined);
|
|
|
|
|
});
|