-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Auto detect and merge lockfile conflicts #3544
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,19 +11,19 @@ const objs = [{foo: 'bar'}, {foo: {}}, {foo: 'foo', bar: 'bar'}, {foo: 5}]; | |
let i = 0; | ||
for (const obj of objs) { | ||
test(`parse/stringify ${++i}`, () => { | ||
expect(parse(stringify(obj))).toEqual(nullify(obj)); | ||
expect(parse(stringify(obj)).object).toEqual(nullify(obj)); | ||
}); | ||
} | ||
|
||
test('parse', () => { | ||
expect(parse('foo "bar"')).toEqual(nullify({foo: 'bar'})); | ||
expect(parse('"foo" "bar"')).toEqual(nullify({foo: 'bar'})); | ||
expect(parse('foo "bar"')).toEqual(nullify({foo: 'bar'})); | ||
|
||
expect(parse(`foo:\n bar "bar"`)).toEqual(nullify({foo: {bar: 'bar'}})); | ||
expect(parse(`foo:\n bar:\n foo "bar"`)).toEqual(nullify({foo: {bar: {}, foo: 'bar'}})); | ||
expect(parse(`foo:\n bar:\n foo "bar"`)).toEqual(nullify({foo: {bar: {foo: 'bar'}}})); | ||
expect(parse('foo:\n bar:\n yes no\nbar:\n yes no')).toEqual( | ||
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'}}})); | ||
expect(parse('foo:\n bar:\n yes no\nbar:\n yes no').object).toEqual( | ||
nullify({ | ||
foo: { | ||
bar: { | ||
|
@@ -193,3 +193,106 @@ test('Lockfile.getLockfile (sorting)', () => { | |
|
||
expect(actual).toEqual(expected); | ||
}); | ||
|
||
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'}, | ||
}); | ||
}); | ||
|
||
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: | ||
foo: "bar" | ||
======= | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not try adding both, which is most probably what is needed when installing packages? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, it might not be obvious but in this example, the format is actually wrong because yarn lockfiles don't support colons |
||
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); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we not put these into a separate file? I can see both ways so just raising the question, not strong opinions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's much easier to manage it like this, and we care more about the text input than we care about where it is coming from for the purpose of this test.