diff --git a/packages/jest-snapshot/src/__tests__/__snapshots__/printSnapshot.test.ts.snap b/packages/jest-snapshot/src/__tests__/__snapshots__/printSnapshot.test.ts.snap index 1b1aea2e1561..a74871623f55 100644 --- a/packages/jest-snapshot/src/__tests__/__snapshots__/printSnapshot.test.ts.snap +++ b/packages/jest-snapshot/src/__tests__/__snapshots__/printSnapshot.test.ts.snap @@ -1,5 +1,21 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`change text value 1`] = ` +expect(received).toMatchSnapshot(properties, hint) + +Snapshot name: \`with properties: change text value 1\` + +- Snapshot - 1 ++ Received + 1 + + Object { + "id": "abcdef", +- "text": "snapshot", ++ "text": "received", + "type": "ADD_ITEM", + } +`; + exports[`matcher error toMatchInlineSnapshot Expected properties must be an object (non-null) without snapshot 1`] = ` expect(received).toMatchInlineSnapshot(properties) @@ -32,6 +48,67 @@ exports[`matcher error toMatchInlineSnapshot Snapshot matchers cannot be used wi Matcher error: Snapshot matchers cannot be used with not `; +exports[`matcher error toMatchNamedSnapshot Expected properties must be an object (non-null) 1`] = ` +expect(received).toMatchNamedSnapshot(properties) + +Matcher error: Expected properties must be an object + +Expected properties has type: function +Expected properties has value: [Function] +`; + +exports[`matcher error toMatchNamedSnapshot Expected properties must be an object (null) with snapshot name 1`] = ` +expect(received).toMatchNamedSnapshot(properties, snapshotName) + +Matcher error: Expected properties must be an object + +Expected properties has value: null + +To provide a snapshot name without properties: toMatchNamedSnapshot('snapshotName') +`; + +exports[`matcher error toMatchNamedSnapshot Expected properties must be an object (null) without snapshot name 1`] = ` +expect(received).toMatchNamedSnapshot(properties) + +Matcher error: Expected properties must be an object + +Expected properties has value: null +`; + +exports[`matcher error toMatchNamedSnapshot Snapshot state must be initialized 1`] = ` +expect(received).resolves.toMatchNamedSnapshot() + +Snapshot state must be initialized + +Snapshot state has value: undefined +`; + +exports[`matcher error toMatchNamedSnapshot received value must be an object (non-null) 1`] = ` +expect(received).toMatchNamedSnapshot(properties) + +Matcher error: received value must be an object when the matcher has properties + +Received has type: string +Received has value: "string" +`; + +exports[`matcher error toMatchNamedSnapshot received value must be an object (null) 1`] = ` +expect(received).toMatchNamedSnapshot(properties) + +Matcher error: received value must be an object when the matcher has properties + +Received has value: null +`; + +exports[`matcher error toMatchSnapshot Expected properties must be an object (array) 1`] = ` +expect(received).toMatchSnapshot(properties) + +Matcher error: Expected properties must be an object + +Expected properties has type: array +Expected properties has value: [] +`; + exports[`matcher error toMatchSnapshot Expected properties must be an object (non-null) 1`] = ` expect(received).toMatchSnapshot(properties) @@ -166,6 +243,32 @@ Snapshot name: \`with properties 1\` } `; +exports[`pass false toMatchNamedSnapshot empty snapshot name New snapshot was not written (multi line) 1`] = ` +expect(received).toMatchNamedSnapshot() + +Snapshot name: \`New snapshot was not written 1\` + +New snapshot was not written. The update flag must be explicitly passed to write a new snapshot. + +This is likely because this test is run in a continuous integration (CI) environment in which snapshots are not written by default. + +Received: +"To write or not to write, +that is the question." +`; + +exports[`pass false toMatchNamedSnapshot empty snapshot name New snapshot was not written (single line) 1`] = ` +expect(received).toMatchNamedSnapshot() + +Snapshot name: \`New snapshot was not written 2\` + +New snapshot was not written. The update flag must be explicitly passed to write a new snapshot. + +This is likely because this test is run in a continuous integration (CI) environment in which snapshots are not written by default. + +Received: "Write me if you can!" +`; + exports[`pass false toMatchSnapshot New snapshot was not written (multi line) 1`] = ` expect(received).toMatchSnapshot(hint) @@ -638,3 +741,52 @@ exports[`printSnapshotAndReceived without serialize prettier/pull/5590 1`] = ` ================================================================================ `; + +exports[`specific-line-diff-false 1`] = ` +expect(received).toMatchNamedSnapshot(properties) + +Snapshot name: \`with properties 1\` + +Expected properties: {"name": "Error"} +Received value: [RangeError: Invalid array length] +`; + +exports[`specific-line-diff-true 1`] = ` +expect(received).toMatchNamedSnapshot(properties) + +Snapshot name: \`with properties 1\` + +- Expected properties - 1 ++ Received value + 1 + + Object { +- "id": "abcdef", ++ "id": "abcdefg", + } +`; + +exports[`specific-not-written-multi-line 1`] = ` +expect(received).toMatchNamedSnapshot() + +Snapshot name: \`New snapshot was not written 1\` + +New snapshot was not written. The update flag must be explicitly passed to write a new snapshot. + +This is likely because this test is run in a continuous integration (CI) environment in which snapshots are not written by default. + +Received: +"To write or not to write, +that is the question." +`; + +exports[`specific-not-written-single-line 1`] = ` +expect(received).toMatchNamedSnapshot() + +Snapshot name: \`New snapshot was not written 2\` + +New snapshot was not written. The update flag must be explicitly passed to write a new snapshot. + +This is likely because this test is run in a continuous integration (CI) environment in which snapshots are not written by default. + +Received: "Write me if you can!" +`; diff --git a/packages/jest-snapshot/src/__tests__/printSnapshot.test.ts b/packages/jest-snapshot/src/__tests__/printSnapshot.test.ts index 43edcd13029b..f1e27227fe3b 100644 --- a/packages/jest-snapshot/src/__tests__/printSnapshot.test.ts +++ b/packages/jest-snapshot/src/__tests__/printSnapshot.test.ts @@ -13,6 +13,7 @@ import format from 'pretty-format'; import { Context, toMatchInlineSnapshot, + toMatchNamedSnapshot, toMatchSnapshot, toThrowErrorMatchingInlineSnapshot, toThrowErrorMatchingSnapshot, @@ -274,6 +275,99 @@ describe('matcher error', () => { }); }); + describe('toMatchNamedSnapshot', () => { + const received = { + id: 'abcdef', + text: 'Throw matcher error', + type: 'ADD_ITEM', + }; + + test('Expected properties must be an object (non-null)', () => { + const context = { + isNot: false, + promise: '', + } as Context; + const properties = () => {}; + + expect(() => { + toMatchNamedSnapshot.call(context, received, properties); + }).toThrowErrorMatchingSnapshot(); + }); + + test('Expected properties must be an object (null) with snapshot name', () => { + const context = { + isNot: false, + promise: '', + } as Context; + const properties = null; + const snapshotName = 'obj-snapshot'; + + expect(() => { + // @ts-expect-error: Testing runtime error + toMatchNamedSnapshot.call(context, received, properties, snapshotName); + }).toThrowErrorMatchingSnapshot(); + }); + + test('Expected properties must be an object (null) without snapshot name', () => { + const context = { + isNot: false, + promise: '', + } as Context; + const properties = null; + + expect(() => { + // @ts-expect-error: Testing runtime error + toMatchNamedSnapshot.call(context, received, properties); + }).toThrowErrorMatchingSnapshot(); + }); + + test('Expected properties must be an object (array)', () => { + const context = { + isNot: false, + promise: '', + } as Context; + const properties: Array = []; + + expect(() => { + toMatchNamedSnapshot.call(context, received, properties); + }).toThrowErrorMatchingSnapshot(); + }); + + describe('received value must be an object', () => { + const context = { + currentTestName: '', + isNot: false, + promise: '', + snapshotState: {}, + } as Context; + const properties = {}; + + test('(non-null)', () => { + expect(() => { + toMatchNamedSnapshot.call(context, 'string', properties); + }).toThrowErrorMatchingSnapshot(); + }); + + test('(null)', () => { + expect(() => { + toMatchNamedSnapshot.call(context, null, properties); + }).toThrowErrorMatchingSnapshot(); + }); + }); + + test('Snapshot state must be initialized', () => { + const context = { + isNot: false, + promise: 'resolves', + } as Context; + const snapshotName = 'initialize me'; + + expect(() => { + toMatchNamedSnapshot.call(context, received, snapshotName); + }).toThrowErrorMatchingSnapshot(); + }); + }); + describe('toMatchSnapshot', () => { const received = { id: 'abcdef', @@ -554,6 +648,220 @@ describe('pass false', () => { }); }); + describe('toMatchNamedSnapshot', () => { + describe('empty snapshot name', () => { + test('New snapshot was not written (multi line)', () => { + const context = { + currentTestName: 'New snapshot was not written', + isNot: false, + promise: '', + snapshotState: { + match({received}) { + return { + actual: format(received), + count: 1, + expected: undefined, + pass: false, + }; + }, + }, + } as Context; + const received = 'To write or not to write,\nthat is the question.'; + const snapshotName = ''; + + const {message, pass} = toMatchNamedSnapshot.call( + context, + received, + snapshotName, + ) as SyncExpectationResult; + expect(pass).toBe(false); + expect(message()).toMatchNamedSnapshot(snapshotName); + }); + + test('New snapshot was not written (single line)', () => { + const context = { + currentTestName: 'New snapshot was not written', + isNot: false, + promise: '', + snapshotState: { + match({received}) { + return { + actual: format(received), + count: 2, + expected: undefined, + pass: false, + }; + }, + }, + } as Context; + const received = 'Write me if you can!'; + const snapshotName = ''; + + const {message, pass} = toMatchNamedSnapshot.call( + context, + received, + snapshotName, + ) as SyncExpectationResult; + expect(pass).toBe(false); + expect(message()).toMatchNamedSnapshot(snapshotName); + }); + }); + + describe('specific snapshot name', () => { + test('New snapshot was not written (multi line)', () => { + const context = { + currentTestName: 'New snapshot was not written', + isNot: false, + promise: '', + snapshotState: { + match({received}) { + return { + actual: format(received), + count: 1, + expected: undefined, + pass: false, + }; + }, + }, + } as Context; + const received = 'To write or not to write,\nthat is the question.'; + const snapshotName = 'specific-not-written-multi-line'; + + const {message, pass} = toMatchNamedSnapshot.call( + context, + received, + snapshotName, + ) as SyncExpectationResult; + expect(pass).toBe(false); + expect(message()).toMatchNamedSnapshot(snapshotName); + }); + + test('New snapshot was not written (single line)', () => { + const context = { + currentTestName: 'New snapshot was not written', + isNot: false, + promise: '', + snapshotState: { + match({received}) { + return { + actual: format(received), + count: 2, + expected: undefined, + pass: false, + }; + }, + }, + } as Context; + const received = 'Write me if you can!'; + const snapshotName = 'specific-not-written-single-line'; + + const {message, pass} = toMatchNamedSnapshot.call( + context, + received, + snapshotName, + ) as SyncExpectationResult; + expect(pass).toBe(false); + expect(message()).toMatchNamedSnapshot(snapshotName); + }); + }); + + describe('with properties', () => { + const id = 'abcdef'; + const properties = {id}; + const type = 'ADD_ITEM'; + + describe('equals false', () => { + const context = { + currentTestName: 'with properties', + equals: () => false, + isNot: false, + promise: '', + snapshotState: { + fail: (fullTestName: string) => `${fullTestName} 1`, + }, + utils: { + iterableEquality: () => {}, + subsetEquality: () => {}, + }, + } as unknown as Context; + + test('isLineDiffable false', () => { + const snapshotName = 'specific-line-diff-false'; + + const {message, pass} = toMatchNamedSnapshot.call( + context, + new RangeError('Invalid array length'), + {name: 'Error'}, + snapshotName, + ) as SyncExpectationResult; + expect(pass).toBe(false); + expect(message()).toMatchNamedSnapshot(snapshotName); + }); + + test('isLineDiffable true', () => { + const snapshotName = 'specific-line-diff-true'; + const received = { + id: 'abcdefg', + text: 'Increase code coverage', + type, + }; + + const {message, pass} = toMatchNamedSnapshot.call( + context, + received, + properties, + snapshotName, + ) as SyncExpectationResult; + expect(pass).toBe(false); + expect(message()).toMatchNamedSnapshot(snapshotName); + }); + }); + + test('equals true', () => { + const context = { + currentTestName: 'with properties', + equals: () => true, + isNot: false, + promise: '', + snapshotState: { + expand: false, + match({received}) { + return { + actual: format(received), + count: 1, + expected: format({ + id, + text: 'snapshot', + type, + }), + pass: false, + }; + }, + } as SnapshotState, + utils: { + iterableEquality: () => {}, + subsetEquality: () => {}, + }, + } as unknown as Context; + const received = { + id, + text: 'received', + type, + }; + const snapshotName = 'change text value'; + + const {message, pass} = toMatchSnapshot.call( + context, + received, + properties, + snapshotName, + ) as SyncExpectationResult; + expect(pass).toBe(false); + expect(message()).toMatchNamedSnapshot(snapshotName); + }); + }); + }); + describe('toMatchSnapshot', () => { test('New snapshot was not written (multi line)', () => { const context = {