Skip to content

Commit

Permalink
Extracted expect extension to a separate file. Added a failing test f…
Browse files Browse the repository at this point in the history
…or gitWorkflow.

Use a .toEventuallyEqual() for git status checks
  • Loading branch information
okonet committed Oct 11, 2016
1 parent eb27ee2 commit 80ba161
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 96 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Expand Up @@ -12,7 +12,7 @@
"indent": [2, 4],
"strict": 0,
"import/no-extraneous-dependencies": [2, {
"devDependencies": ["**/*.spec.js"]
"devDependencies": ["**/*.spec.js", "**/utils.js"]
}]
}
}
3 changes: 1 addition & 2 deletions .lintstagedrc
Expand Up @@ -4,7 +4,6 @@
"eslint --fix",
"git add"
],
"*.md": "yaspeller",
".*rc": "jsonlint"
"*.md": "yaspeller"
}
}
133 changes: 52 additions & 81 deletions test/gitWorkflow.spec.js
Expand Up @@ -5,6 +5,7 @@ import expect from 'expect'
import rewire from 'rewire'
import fsp from 'fs-promise'
import tmp from 'tmp'
import { toEventuallyEqual } from './utils'

const gitflow = rewire('../src/gitWorkflow')

Expand All @@ -13,8 +14,10 @@ let wcDirPath
let gitOpts = { cwd: 'test/__fixtures__' }

tmp.setGracefulCleanup()
expect.extend(toEventuallyEqual)

const execaSpy = expect.createSpy().andReturn(new Promise(resolve => resolve()))
const gitStatus = opts => gitflow.execGit(['status', '--porcelain'], opts)

describe('gitWorkflow', () => {

Expand Down Expand Up @@ -143,122 +146,90 @@ describe('gitWorkflow', () => {
.then(() => fsp.writeFile(path.join(wcDirPath, 'test.js'), `module.exports = {
test: 'test2'
}`))
.then(() => gitflow.execGit(['status', '--porcelain'], gitOpts))
.then((res) => {
// Expect both are modified
expect(res.stdout).toEqual(' M test.css\n M test.js')
})
// Expect both are modified
.then(() => expect(gitStatus(gitOpts)).toEventuallyEqual(' M test.css\n M test.js'))
.then(() => gitflow.execGit(['add', 'test.js'], gitOpts))
.then(() => gitflow.execGit(['status', '--porcelain'], gitOpts))
.then((res) => {
// Expect one is in index
expect(res.stdout).toEqual(' M test.css\nM test.js')
})
// Expect one is in index
.then(() => expect(gitStatus(gitOpts)).toEventuallyEqual(' M test.css\nM test.js'))
.then(() => gitflow.gitStashSave(gitOpts))
.then(() => gitflow.execGit(['status', '--porcelain'], gitOpts))
.then((res) => {
// Expect only one file from indexed
expect(res.stdout).toEqual('M test.js')
})

// Expect only one file from indexed
.then(() => expect(gitStatus(gitOpts)).toEventuallyEqual('M test.js'))
// Restoring state
.then(() => gitflow.gitStashPop(gitOpts))
.then(() => gitflow.execGit(['status', '--porcelain'], gitOpts))
.then((res) => {
// Expect stashed files to be back. Indexed file remains indexed
expect(res.stdout).toEqual(' M test.css\nM test.js')
done()
})
// Expect stashed files to be back. Indexed file remains indexed
.then(() => expect(gitStatus(gitOpts)).toEventuallyEqual(' M test.css\nM test.js'))
.then(() => { done() })
})

it('should stash and restore WC state after commit', (done) => {
it('should stash and restore WC state with additional edits without a commit', (done) => {
// Update one of the files
fsp.writeFile(path.join(wcDirPath, 'test.css'), '.test { border: red; }')
// Update one of the files
.then(() => fsp.writeFile(path.join(wcDirPath, 'test.js'), `module.exports = {
test: 'test2'
}`))
.then(() => gitflow.execGit(['status', '--porcelain'], gitOpts))
.then((res) => {
// Expect both are modified
expect(res.stdout).toEqual(' M test.css\n M test.js')
})
// Expect both are modified
.then(() => expect(gitStatus(gitOpts)).toEventuallyEqual(' M test.css\n M test.js'))
.then(() => gitflow.execGit(['add', 'test.js'], gitOpts))
.then(() => gitflow.execGit(['status', '--porcelain'], gitOpts))
.then((res) => {
// Expect one is in index
expect(res.stdout).toEqual(' M test.css\nM test.js')
})
// Expect one is in index
.then(() => expect(gitStatus(gitOpts)).toEventuallyEqual(' M test.css\nM test.js'))
.then(() => gitflow.gitStashSave(gitOpts))
.then(() => gitflow.execGit(['status', '--porcelain'], gitOpts))
.then((res) => {
// Expect only one file from indexed
expect(res.stdout).toEqual('M test.js')
})

.then(() => gitflow.execGit(['commit', '-m', 'second commit'], gitOpts))
.then(() => gitflow.execGit(['status', '--porcelain'], gitOpts))
.then((res) => {
// Expect clean WC
expect(res.stdout).toEqual('')
})
// Expect only one file from indexed
.then(() => expect(gitStatus(gitOpts)).toEventuallyEqual('M test.js'))
// Do additional edits (imitate eslint --fix)
.then(() => fsp.writeFile(path.join(wcDirPath, 'test.js'), `module.exports = {
test: 'test2',
};`))

// Expect both indexed and modified state on one file
.then(() => expect(gitStatus(gitOpts)).toEventuallyEqual('MM test.js'))
// Restoring state
.then(() => gitflow.gitStashPop(gitOpts))
.then(() => gitflow.execGit(['status', '--porcelain'], gitOpts))
.then((res) => {
// Expect stashed files to be back. Commited file is gone.
expect(res.stdout).toEqual(' M test.css')
// Expect stashed files to be back. Commited file is gone.
.then(() => expect(gitStatus(gitOpts)).toEventuallyEqual(' M test.css\nM test.js'))
.then(() => {
const jsContent = fsp.readFileSync(path.join(wcDirPath, 'test.js'), { encoding: 'utf-8' })
expect(jsContent).toEqual(`module.exports = {
test: 'test2'
}`)
done()
})
})

it('should stash and restore WC state with additional edits without a commit', (done) => {
it('should stash and restore WC state with additional edits before a commit', (done) => {
// Update one of the files
fsp.writeFile(path.join(wcDirPath, 'test.css'), '.test { border: red; }')
// Update one of the files
.then(() => fsp.writeFile(path.join(wcDirPath, 'test.js'), `module.exports = {
test: 'test2'
}`))
.then(() => gitflow.execGit(['status', '--porcelain'], gitOpts))
.then((res) => {
// Expect both are modified
expect(res.stdout).toEqual(' M test.css\n M test.js')
})
.then(() => gitflow.execGit(['add', 'test.js'], gitOpts))
.then(() => gitflow.execGit(['status', '--porcelain'], gitOpts))
.then((res) => {
// Expect one is in index
expect(res.stdout).toEqual(' M test.css\nM test.js')
})
// Expect both are modified
.then(() => expect(gitStatus(gitOpts)).toEventuallyEqual(' M test.css\n M test.js'))
.then(() => gitflow.execGit(['add', '.'], gitOpts))
// Expect both are in index
.then(() => expect(gitStatus(gitOpts)).toEventuallyEqual('M test.css\nM test.js'))
.then(() => gitflow.gitStashSave(gitOpts))
.then(() => gitflow.execGit(['status', '--porcelain'], gitOpts))
.then((res) => {
// Expect only one file from indexed
expect(res.stdout).toEqual('M test.js')
})

// Do additional edits (imitate eslint --fix)
// Expect both are in index
.then(() => expect(gitStatus(gitOpts)).toEventuallyEqual('M test.css\nM test.js'))
// Do additional edits (simulate eslint --fix)
.then(() => fsp.writeFile(path.join(wcDirPath, 'test.js'), `module.exports = {
test: 'test2',
};`))

.then(() => gitflow.execGit(['status', '--porcelain'], gitOpts))
.then((res) => {
// Expect both indexed and modified state on one file
expect(res.stdout).toEqual('MM test.js')
})

// Expect both indexed and modified state on one file
.then(() => expect(gitStatus(gitOpts)).toEventuallyEqual('M test.css\nMM test.js'))
// Add additional changes to the commit
.then(() => gitflow.execGit(['add', 'test.js'], gitOpts))
// Expect both files are in the index
.then(() => expect(gitStatus(gitOpts)).toEventuallyEqual('M test.css\nM test.js'))
// Restoring state
.then(() => gitflow.gitStashPop(gitOpts))
.then(() => gitflow.execGit(['status', '--porcelain'], gitOpts))
.then((res) => {
// Expect stashed files to be back. Index changes are persisted.
.then(() => expect(gitStatus(gitOpts)).toEventuallyEqual('M test.css\nM test.js'))
.then(() => {
const jsContent = fsp.readFileSync(path.join(wcDirPath, 'test.js'), { encoding: 'utf-8' })
// Expect stashed files to be back. Commited file is gone.
expect(res.stdout).toEqual(' M test.css\nM test.js')
expect(jsContent).toEqual(`module.exports = {
test: 'test2'
}`)
test: 'test2',
};`)
done()
})
})
Expand Down
15 changes: 3 additions & 12 deletions test/runScript.spec.js
@@ -1,21 +1,12 @@
/* eslint no-underscore-dangle: 0 */

import expect from 'expect'
import isPromise from 'is-promise'
import rewire from 'rewire'
import testUtils from './utils'

const runScript = rewire('../src/runScript')
expect.extend(testUtils)

expect.extend({
toBeAPromise() {
expect.assert(
isPromise(this.actual),
'expected %s to be a Promise',
this.actual
)
return this
}
})
const runScript = rewire('../src/runScript')

const packageJSON = {
scripts: {
Expand Down
26 changes: 26 additions & 0 deletions test/utils.js
@@ -0,0 +1,26 @@
import expect, { assert } from 'expect'
import isPromise from 'is-promise'

export function toBeAPromise() {
assert(
isPromise(this.actual),
'expected %s to be a Promise',
this.actual
)
return this
}

export function toEventuallyEqual(value) {
if (!isPromise(this.actual)) {
assert(false, '%s is not a Promise', this.actual)
}
return this.actual
.then(res => expect(res.stdout).toEqual(value))
.catch(err => assert(false, 'Error in Promise %s', err))

}

export default {
toBeAPromise,
toEventuallyEqual
}
1 change: 1 addition & 0 deletions wallaby.js
Expand Up @@ -3,6 +3,7 @@ module.exports = function (wallaby) {
files: [
{ pattern: 'test/__fixtures__/*', instrument: false },
{ pattern: 'test/__fixtures__/**/*', instrument: false },
'test/utils.js',
'src/*.js'
],

Expand Down

0 comments on commit 80ba161

Please sign in to comment.