Skip to content

Commit

Permalink
feat: allow shared named snapshot close #443
Browse files Browse the repository at this point in the history
  • Loading branch information
bahmutov committed Oct 14, 2019
1 parent fe35dd6 commit cad8ad6
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 5 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,16 @@ exports['my name'] = 42

**Note** you should make sure that the name is unique per spec file.

### Shared snapshot name

If you **do want** to share a named snapshot value from several places or tests in the same spec file, you need to pass an option when calling `snapshot`. The the first snapshot is saved, and the next ones will just compare against the value.

```js
snapshot('my shared snapshot', value, { allowSharedSnapshot : true })
// some time later
snapshot('my shared snapshot', value, { allowSharedSnapshot : true })
```

## Pruning

If the test run is successful and executed _all_ tests (there was no `.only`) then snapshots without a test are pruned. You can skip pruning by running with environment variable
Expand Down
2 changes: 2 additions & 0 deletions __snapshots__/named-snapshots-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ exports['my snap name'] = 41
exports['second snapshot'] = 2

exports['third snapshot'] = 3

exports['shared snapshot'] = 42
2 changes: 2 additions & 0 deletions src/duplicate-key-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ describe('duplicate key', () => {
}
)
)
// it is fine to use the same snapshot name if passed an option
snapshot('diff values', 1, { allowSharedSnapshot: true })
})
})
})
17 changes: 13 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,26 @@ const isPruneInfo = is.schema({
specFile: is.unemptyString,
key: is.unemptyString,
testTitle: is.unemptyString,
titleParts: is.strings
titleParts: is.strings,
allowDuplicate: is.bool
})

function addToPrune (info) {
la(isPruneInfo(info), 'wrong info for pruning snapshot', info)

const prevInfo = findExistingSnapshotKey(info)
if (prevInfo) {
debug('found duplicate snapshot name: %s', prevInfo.key)
if (prevInfo && !info.allowDuplicate) {
debug('add to prune: found duplicate snapshot name: %s', prevInfo.key)
debug('%o', info)

throwDuplicateSnapshotKeyError(info, prevInfo)
}

seenSpecs.push(info)
}

const findExistingSnapshotKey = info => {
la(isPruneInfo(info), 'wrong snapshot info', info)
la(isPruneInfo(info), 'wrong snapshot prune info', info)
return R.find(R.propEq('key', info.key))(seenSpecs)
}

Expand Down Expand Up @@ -183,6 +186,7 @@ function snapshot (value) {

// eslint-disable-next-line immutable/no-let
let savedTestTitle = fullTitle
let snapshotOptions = {}

if (isDataDriven(arguments)) {
// value is a function
Expand All @@ -194,6 +198,8 @@ function snapshot (value) {
} else if (isNamedSnapshotArguments(arguments)) {
savedTestTitle = arguments[0]
value = arguments[1]
// and there could be additional arguments for named snapshots
snapshotOptions = arguments[2] || {}
debug('named snapshots "%s"', savedTestTitle)
} else {
debug('snapshot value %j', value)
Expand Down Expand Up @@ -290,6 +296,7 @@ function snapshot (value) {
la('key' in coreResult, 'core result should have key', coreResult)

const pruneInfo = R.assoc('key', coreResult.key, snapshotInfo)
pruneInfo.allowDuplicate = Boolean(snapshotOptions.allowSharedSnapshot)
debug('prune info %o', pruneInfo)

addToPrune(pruneInfo)
Expand All @@ -307,7 +314,9 @@ function snapshot (value) {
// })
//
// check if we have a collision
// the code is duplicate from above to get just the key collision error
const info = R.assoc('key', e.key, snapshotInfo)
info.allowDuplicate = Boolean(snapshotOptions.allowSharedSnapshot)
debug('current snapshot info %o', info)

const prevInfo = findExistingSnapshotKey(info)
Expand Down
18 changes: 18 additions & 0 deletions src/named-snapshots-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,22 @@ describe('named snapshots', () => {
la(e.message.includes(mySnapshotName), e.message)
}
})

context('allows several tests to use same name', () => {
const snapshotName = 'shared snapshot'

// as long as the value is the same, these two tests
// should be allowed to use same snapshot name
const snapshotOptions = {
allowSharedSnapshot: true
}

it('test a', () => {
snapshot(snapshotName, 42, snapshotOptions)
})

it('test b', () => {
snapshot(snapshotName, 42, snapshotOptions)
})
})
})
7 changes: 6 additions & 1 deletion src/named-snapshots.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
const is = require('check-more-types')

/**
* If we called snapshot like `snapshot('name', value)`
* or like `snapshot('name', value, options)` then this is
* a named snapshot.
*/
function isNamedSnapshotArguments (args) {
return args.length === 2 && is.string(args[0])
return (args.length === 2 || args.length === 3) && is.string(args[0])
}

// eslint-disable-next-line immutable/no-mutation
Expand Down

0 comments on commit cad8ad6

Please sign in to comment.