Skip to content

Commit

Permalink
Increasing test coverage.
Browse files Browse the repository at this point in the history
1.  Added a fake block to insert a missing value in the testing utils.
2.  Added tests that rely on it.
  • Loading branch information
gvwilson committed Sep 18, 2019
1 parent cfbf564 commit 663e9cc
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 56 deletions.
7 changes: 7 additions & 0 deletions data/updown.csv
@@ -0,0 +1,7 @@
value
25
35
45
20
30
40
4 changes: 3 additions & 1 deletion test/test_js_codegen.js
Expand Up @@ -15,14 +15,16 @@ const {
loadBlockFiles,
makeBlock,
generateCode,
evalCode
evalCode,
createTestingBlocks
} = require('./utils')

//
// Load blocks before running tests.
//
before(() => {
loadBlockFiles()
createTestingBlocks()
})

describe('generate code for single blocks', () => {
Expand Down
4 changes: 3 additions & 1 deletion test/test_js_error.js
Expand Up @@ -15,14 +15,16 @@ const {
loadBlockFiles,
makeBlock,
generateCode,
evalCode
evalCode,
createTestingBlocks
} = require('./utils')

//
// Load blocks before running tests.
//
before(() => {
loadBlockFiles()
createTestingBlocks()
})

describe('raises errors at the right times', () => {
Expand Down
115 changes: 99 additions & 16 deletions test/test_js_exec.js
Expand Up @@ -15,14 +15,16 @@ const {
loadBlockFiles,
makeBlock,
generateCode,
evalCode
evalCode,
createTestingBlocks
} = require('./utils')

//
// Load blocks before running tests.
// Load blocks and define testing blocks before running tests.
//
before(() => {
loadBlockFiles()
createTestingBlocks()
})

describe('execute blocks for entire pipelines', () => {
Expand Down Expand Up @@ -928,41 +930,45 @@ describe('check that grouping and summarization work', () => {
})

it('calculates multiple summary values correctly', (done) => {
const filePath = 'https://raw.githubusercontent.com/tidyblocks/tidyblocks/master/data/updown.csv'
const pipeline = [
makeBlock(
'data_double',
{}),
'data_urlCSV',
{URL: filePath}),
makeBlock(
'transform_summarize',
{COLUMN_FUNC_PAIR: [
makeBlock('transform_summarize_item',
{FUNC: 'tbMin',
COLUMN: 'first'}),
COLUMN: 'value'}),
makeBlock('transform_summarize_item',
{FUNC: 'tbMean',
COLUMN: 'second'}),
COLUMN: 'value'}),
makeBlock('transform_summarize_item',
{FUNC: 'tbMax',
COLUMN: 'second'})
COLUMN: 'value'})
]})
]
const env = evalCode(pipeline)
assert(env.table.length == 1,
`Expect a single row of output`)
assert(env.table[0].first_min == 1,
`Expected a min of 1, not ${env.table[0].first}`)
assert(env.table[0].second_mean == 150,
`Expected a mean of 150, not ${env.table[0].second}`)
assert(env.table[0].second_max == 200,
`Expected a max of 200, not ${env.table[0].second}`)
assert.equal(env.error, '',
`Expected no error from pipeline`)
assert.equal(env.table.length, 1,
`Expect a single row of output`)
assert.equal(env.table[0].value_min, 20,
`Expected a mean of 20, not ${env.table[0].value_min}`)
assert.equal(env.table[0].value_mean, 32.5,
`Expected a mean of 32.5, not ${env.table[0].value_mean}`)
assert.equal(env.table[0].value_max, 45,
`Expected a max of 45, not ${env.table[0].value_max}`)
done()
})

it('handles empty tables correctly when calculating maxima', (done) => {
it('handles empty tables correctly', (done) => {
const pipeline = [
makeBlock(
'data_colors',
{}),
// remove all rows
makeBlock(
'transform_filter',
{TEST: makeBlock(
Expand All @@ -974,9 +980,16 @@ describe('check that grouping and summarization work', () => {
RIGHT: makeBlock(
'value_number',
{VALUE: 0})})}),
// calculate various summaries
makeBlock(
'transform_summarize',
{COLUMN_FUNC_PAIR: [
makeBlock('transform_summarize_item',
{FUNC: 'tbMin',
COLUMN: 'red'}),
makeBlock('transform_summarize_item',
{FUNC: 'tbMedian',
COLUMN: 'red'}),
makeBlock('transform_summarize_item',
{FUNC: 'tbMax',
COLUMN: 'red'})
Expand Down Expand Up @@ -1057,6 +1070,76 @@ describe('check that grouping and summarization work', () => {
`Expect a standard deviation of ${expected_std}, not ${env.table[0].green_std}`)
done()
})

it('handles missing values for unary operators correctly', (done) => {
const pipeline = [
makeBlock(
'data_single',
{}),
makeBlock(
'transform_mutate',
{COLUMN: 'negated',
VALUE: makeBlock(
'value_negate',
{VALUE: makeBlock(
'value_missing',
{})}
)}),
makeBlock(
'transform_mutate',
{COLUMN: 'notted',
VALUE: makeBlock(
'value_not',
{VALUE: makeBlock(
'value_missing',
{})}
)})
]
const env = evalCode(pipeline)
assert.equal(env.error, '',
`Expectd no error message`)
assert.equal(env.table[0].negated, MISSING,
`Expected MISSING from negation, not ${env.table[0].negated}`)
assert.equal(env.table[0].notted, MISSING,
`Expected MISSING from logical negation, not ${env.table[0].notted}`)
done()
})

it('handles missing values in binary arithmetic correctly', (done) => {
const allTests = [
['addition', 'tbAdd'],
['division', 'tbDiv'],
['exponentiation', 'tbExp'],
['modulus', 'tbMod'],
['multiplication', 'tbMul'],
['subtraction', 'tbSub']
]
for (let [opName, funcName] of allTests) {
const pipeline = [
makeBlock(
'data_single',
{}),
makeBlock(
'transform_mutate',
{COLUMN: 'result',
VALUE: makeBlock(
'value_arithmetic',
{OP: funcName,
LEFT: makeBlock(
'value_column',
{COLUMN: 'first'}),
RIGHT: makeBlock(
'value_missing',
{})})})
]
const env = evalCode(pipeline)
assert.equal(env.error, '',
`Expected no error message`)
assert.equal(env.table[0].result, MISSING,
`Expected missing value for ${opName}`)
}
done()
})

})

Expand Down
34 changes: 30 additions & 4 deletions test/test_js_utils.js
Expand Up @@ -16,14 +16,16 @@ const {
loadBlockFiles,
makeBlock,
generateCode,
evalCode
evalCode,
createTestingBlocks
} = require('./utils')

//
// Load blocks before running tests.
//
before(() => {
loadBlockFiles()
createTestingBlocks()
})

describe('CSV headers are sanitized correctly', () => {
Expand Down Expand Up @@ -220,8 +222,9 @@ describe('blocks return proper columns', () => {

it('adds new column when mutating', (done) => {
const pipeline = [
makeBlock('data_single',
{}),
makeBlock(
'data_single',
{}),
makeBlock(
'transform_mutate',
{COLUMN: 'newColumnName',
Expand All @@ -230,7 +233,30 @@ describe('blocks return proper columns', () => {
{VALUE: 0})})
]
const env = evalCode(pipeline)
assert('newColumnName' in env.table[0])
assert_hasKey(env.table[0], 'newColumnName',
`Table does not have expected column after mutate`)
done()
})

it('creates a missing value', (done) => {
const pipeline = [
makeBlock(
'data_single',
{}),
makeBlock(
'transform_mutate',
{COLUMN: 'na',
VALUE: makeBlock(
'value_missing',
{})})
]
const env = evalCode(pipeline)
assert.equal(env.error, '',
`Expected no error when creating missing value`)
assert.equal(env.table.length, 1,
`Expected one row of output`)
assert.equal(env.table[0].na, MISSING,
`Expected missing value in new column`)
done()
})

Expand Down
25 changes: 24 additions & 1 deletion test/utils.js
Expand Up @@ -337,6 +337,28 @@ const evalCode = (code) => {
return environment
}

/**
* Create special-purpose blocks for testing.
*/
const createTestingBlocks = () => {

// "Missing value" block.
Blockly.defineBlocksWithJsonArray([
{
type: 'value_missing',
message0: 'missing',
args0: [],
inputsInline: true,
style: 'value_blocks'
}
])
Blockly.JavaScript['value_missing'] = (block) => {
const order = Blockly.JavaScript.ORDER_NONE
const code = `(row) => MISSING`
return [code, order]
}
}

//
// Exports.
//
Expand All @@ -355,5 +377,6 @@ module.exports = {
loadBlockFiles,
makeBlock,
generateCode,
evalCode
evalCode,
createTestingBlocks
}

0 comments on commit 663e9cc

Please sign in to comment.