Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .meteor/versions
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ blaze@2.1.2
blaze-tools@1.0.3
boilerplate-generator@1.0.3
callback-hook@1.0.3
canotto90:latte@0.6.4
canotto90:latte@0.7.4
canotto90:pretty-errors@0.0.1
cfs:http-methods@0.0.29
check@1.0.5
coffeescript@1.0.6
ddp@1.1.0
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"describe", "ddescribe", "context", "ccontext", "it", "iit",
"beforeAll", "beforeEach", "T", "afterAll", "afterEach",
"expect", "should", "_",
"figures", "Npm"
"figures", "Npm", "HTTP"
]
}
}
9 changes: 9 additions & 0 deletions packages/latte/http_api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
HTTP.methods({
'/test': {
get: function () {
T.needToBoot = false
T.run(this.query.suite)
}
}
})

101 changes: 55 additions & 46 deletions packages/latte/latte.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,46 @@
var figures = Npm.require('figures')
var readFile = Meteor.wrapAsync(Npm.require('fs').readFile)

T = { // eslint-disable-line
analize: function () { // this lets us analyze suite's structure to act accordingly later (allowing, for example, iit blocks to work)
T.analyzing = true
T.suites.forEach(exec)
T.analyzing = false
},
run: function () {
run: function (input) {
if (!process.env.RUN_TESTS) { return }
console.log('T.onlySuites', T.onlySuites)
console.log('T.analyzing', T.analyzing)

T.preProcess = false
T.describeBlocks.forEach(exec)
getOnlySuitesFromInput(input)
console.log('T.onlySuites', T.onlySuites)
T.analyzing = false
T.needToBoot = false

var testingDB = new global.MongoInternals.RemoteCollectionDriver(T.testingDbUrl) // create a driver pointing to testing's DB
getCollections().forEach(pointToTestingDB) // point collections to testing's DB
getCollections().forEach(removeAll) // erase date on testing DB (though there should be none)
console.log('0')

console.log('T.onlyRootDescribeBlocksForIit', T.onlyRootDescribeBlocksForIit)
T.onlyRootDescribeBlocksForIit.length ? T.onlyRootDescribeBlocksForIit.forEach(exec) : T.suites.forEach(exec) // if there's `iit` blocks, only run those

// output number of successful over total tests
log('\n' + (T.itCount + ' tests: ').yellow + (T.successfulItCount + ' passing, ').green + (T.itCount - T.successfulItCount + ' failing.').red)
console.log('1')

getCollections().forEach(pointBackToDevelopDB) // point collections back to development's DB
_(T.postRunCallbacks).reject(preventsSuiteFromRunning).map(fns).forEach(exec) // allow to run a callback when testing has finished (before possibly ending the process)

console.log('A')
process.env.RUN_TESTS !== 'cont' && process.exit(T.exceptions.length) // end the process unless option is specified

console.log('B')
T.itCount = 0
T.successfulItCount = 0
T.analyzing = true
T.needToBoot = true
T.suites = []
T.onlyRootDescribeBlocksForIit = []
console.log('C')

function pointToTestingDB (collection) {
collection.latte_original_driver = collection._driver // keep track of original driver, to point back to development's DB once tests have finished
collection._driver = testingDB
Expand Down Expand Up @@ -78,21 +96,11 @@ T = { // eslint-disable-line
T.exceptions.push(e) // if `T.exceptions` has any item at the en of the test run, exit code will be != 0
}
},
beforeAll: function (fn) {
if (T.analyzing) { return }
T.beforeAllBlocks.push({ fn: fn, deepLevel: T.deepLevel }) // keep track of beforeAll blocks, to run them later
},
beforeEach: function (fn) {
if (T.analyzing) { return }
T.beforeEachBlocks.push({ fn: fn, deepLevel: T.deepLevel })
},
afterAll: function (fn) {
if (T.analyzing) { return }
T.afterAllBlocks.push({ fn: fn, deepLevel: T.deepLevel })
},
afterEach: function (fn) {
if (T.analyzing) { return }
T.afterEachBlocks.push({ fn: fn, deepLevel: T.deepLevel })
defineHook: function (type) {
return function (fn) {
if (T.analyzing) { return }
T[type + 'Blocks'].push({ fn: fn, deepLevel: T.deepLevel })
}
},
message: function (type, label, deepLevel) { // pretty print messages for console report
var prefix = ''
Expand All @@ -116,8 +124,9 @@ T = { // eslint-disable-line
onlyRootDescribeBlocksForIit: [],
describeMessages: [],
itBlockRunLevel: 0,
isFirstAddedSuite: true,
needToBoot: true,
analyzing: true,
preProcess: true,
onlySuites: [],
testingDbUrl: 'mongodb://127.0.0.1:3001/meteor_latte'
}
Expand All @@ -139,32 +148,18 @@ function descriptionBlock (type, options) {
if (!process.env.RUN_TESTS) { return function () {} } // don't run any test related stuff unless explicitly told so
options = options || {}

return function analyzeOrExec (label, fn) {
return function describeBlock (label, fn) {
T.needToBoot && Meteor.startup(T.run)
T.needToBoot = false
if (T.preProcess) { return T.describeBlocks.push(describeBlock.bind(this, label, fn)) }
if (T.deepLevel === 0 && options.runOnly && !excludedSuite(T.onlySuites, label) && !T.onlySuitesAsUserParams) { T.onlySuites.push(label) }
if (T.deepLevel === 0 && preventsSuiteFromRunning(label)) { return }

return (T.analyzing ? analizeBlock(label, fn) : describeBlock(label, fn))
}

function analizeBlock (label, fn) {
if (T.deepLevel === 0) {
if (T.analyzing && T.deepLevel === 0) {
var testSuite = describeBlock.bind(this, label, fn)
T.currentRootDescribeBlock = testSuite
T.suites.push(testSuite)
T.isFirstAddedSuite && Meteor.startup(function () { // upon first suite addition, add a callback to startup to run tests
T.analize() // look at suites structure and prepare the test run (this allows, for example, iit behavior)
T.run() // run code defined inside suites (describe blocks)
})
T.isFirstAddedSuite = false
}
T.deepLevel++
fn()
T.deepLevel--
}

function describeBlock (label, fn) {
if (T.deepLevel === 0 && preventsSuiteFromRunning(label)) { return }
T.describeMessages.push(T.message(type, label, T.deepLevel))
!T.analyzing && T.describeMessages.push(T.message(type, label, T.deepLevel))
T.deepLevel++
fn()
if (T.itBlockRunLevel >= T.deepLevel) {
Expand Down Expand Up @@ -237,6 +232,20 @@ function getCollections () {
}
}

// input can be either the file or the describe label to run
function getOnlySuitesFromInput (input) {
if (!input) { return }
var onlySuites = null
var file = null
try { file = input && readFile(input.toString()).toString() } catch(e) {}
if (file) {
var start = file.indexOf('describe(') + 'describe('.length + 1
var end = file.indexOf(', function') - 1
onlySuites = [file.substring(start, end)]
}
T.onlySuites = onlySuites || input
}

// Global variables are not attached to the `global` object in Meteor packages, so we ignore style checker for this section.
// Details: http://stackoverflow.com/questions/31526454/global-variables-not-being-attached-to-the-global-object-on-meteorjs-packages

Expand All @@ -245,10 +254,10 @@ describe = T.describe.bind(T)
context = T.context.bind(T)
it = T.it.bind(T)
iit = T.iit.bind(T)
beforeAll = T.beforeAll.bind(T)
beforeEach = T.beforeEach.bind(T)
afterAll = T.afterAll.bind(T)
afterEach = T.afterEach.bind(T)
beforeAll = T.defineHook('beforeAll').bind(T)
beforeEach = T.defineHook('beforeEach').bind(T)
afterAll = T.defineHook('afterAll').bind(T)
afterEach = T.defineHook('afterEach').bind(T)
ddescribe = T.ddescribe.bind(T)
ccontext = T.ccontext.bind(T)
/*eslint-enable */
Expand Down
4 changes: 3 additions & 1 deletion packages/latte/package.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package.describe({
name: 'canotto90:latte',
version: '0.6.4',
version: '0.7.4',
summary: 'Run mocha-like specs in Meteor, without Velocity\'s overhead.',
git: 'https://github.com/taromero/latte.git',
documentation: '../../README.md'
Expand All @@ -13,7 +13,9 @@ Npm.depends({
Package.onUse(function (api) {
api.use('mongo@1.1.0', 'server')
api.use('nooitaf:colors@0.0.2')
api.use('cfs:http-methods@0.0.29')
api.addFiles('latte.js', 'server')
api.addFiles('http_api.js', 'server')
api.export('T', 'server')
api.export('describe', 'server')
api.export('context', 'server')
Expand Down
4 changes: 3 additions & 1 deletion specs/ddescribe_iit_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ describe('describe block containing an iit block, in presence of a ddescribe blo
T.postRunCallbacks.push({
label: 'ddescribe should take precedence over iit blocks',
fn: function () {
if (ddescribeCounter !== 1) { throw new Error('some assertion failed to exec. ddescribeCounter = ' + ddescribeCounter) }
console.log('prca')
if (ddescribeCounter !== 1) { console.log('prca1'); throw new Error('some assertion failed to exec. ddescribeCounter = ' + ddescribeCounter) }
console.log('prca2')
}
})

1 change: 1 addition & 0 deletions specs/ddescribe_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ describe('unnested describe blocks in presence of a ddescribe block', function (
T.postRunCallbacks.push({
label: 'if there is a ddescribe block',
fn: function () {
console.log('prcb')
if (ddescribeCounter !== 2) { throw new Error('ddescribe_spec: some assertion failed to exec. ddescribeCounter == ' + ddescribeCounter) }
}
})
Expand Down
1 change: 1 addition & 0 deletions specs/iit_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ describe('iit behaviour', function () {
T.postRunCallbacks.push({
label: 'iit behaviour',
fn: function () {
console.log('prcd')
if (iitCounter !== 3) { throw new Error('some assertion failed to exec. iitCounter == ' + iitCounter) }
if (allCounter !== 4) { throw new Error('some before/afterAll block failed to exec. allCounter == ' + allCounter) }
if (eachCounter !== 6) { throw new Error('some before/afterEach block failed to exec. eachCounter == ' + eachCounter) }
Expand Down
2 changes: 2 additions & 0 deletions specs/multiple_ddescribe_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ ddescribe('second ddescribe', function () {
T.postRunCallbacks.push({
label: 'first ddescribe',
fn: function () {
console.log('prcc')
if (ddescribeCounter1 !== 1) { throw new Error('some assertion failed to exec. ddescribeCounter = ' + ddescribeCounter1) }
}
})

T.postRunCallbacks.push({
label: 'second ddescribe',
fn: function () {
console.log('prcd')
if (ddescribeCounter2 !== 1) { throw new Error('some assertion failed to exec. ddescribeCounter = ' + ddescribeCounter2) }
}
})
Expand Down
2 changes: 1 addition & 1 deletion specs/sample_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('Subject seeding', function () {
})

it('should not create new subjects', function () {
Subjects.find().count().should.eq(1)
Subjects.find().count().should.eq(2)
})

})
Expand Down