First Initial
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
describe 'Morris.Area', ->
|
||||
|
||||
describe 'svg structure', ->
|
||||
defaults =
|
||||
element: 'graph'
|
||||
data: [{x: '2012 Q1', y: 1}, {x: '2012 Q2', y: 1}]
|
||||
lineColors: [ '#0b62a4', '#7a92a3']
|
||||
gridLineColor: '#aaa'
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['Y']
|
||||
|
||||
it 'should contain a line path for each line', ->
|
||||
chart = Morris.Area $.extend {}, defaults
|
||||
$('#graph').find("path[stroke='#0b62a4']").size().should.equal 1
|
||||
|
||||
it 'should contain a path with stroke-width 0 for each line', ->
|
||||
chart = Morris.Area $.extend {}, defaults
|
||||
$('#graph').find("path[stroke='#0b62a4']").size().should.equal 1
|
||||
|
||||
it 'should contain 5 grid lines', ->
|
||||
chart = Morris.Area $.extend {}, defaults
|
||||
$('#graph').find("path[stroke='#aaaaaa']").size().should.equal 5
|
||||
|
||||
it 'should contain 9 text elements', ->
|
||||
chart = Morris.Area $.extend {}, defaults
|
||||
$('#graph').find("text").size().should.equal 9
|
||||
|
||||
describe 'svg attributes', ->
|
||||
defaults =
|
||||
element: 'graph'
|
||||
data: [{x: '2012 Q1', y: 1}, {x: '2012 Q2', y: 1}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['Y']
|
||||
lineColors: [ '#0b62a4', '#7a92a3']
|
||||
lineWidth: 3
|
||||
pointWidths: [5]
|
||||
pointStrokeColors: ['#ffffff']
|
||||
gridLineColor: '#aaa'
|
||||
gridStrokeWidth: 0.5
|
||||
gridTextColor: '#888'
|
||||
gridTextSize: 12
|
||||
|
||||
it 'should not be cumulative if behaveLikeLine', ->
|
||||
chart = Morris.Area $.extend {}, defaults, behaveLikeLine: true
|
||||
chart.cumulative.should.equal false
|
||||
|
||||
it 'should have a line with transparent fill if behaveLikeLine', ->
|
||||
chart = Morris.Area $.extend {}, defaults, behaveLikeLine: true
|
||||
$('#graph').find("path[fill-opacity='0.8']").size().should.equal 1
|
||||
|
||||
it 'should not have a line with transparent fill', ->
|
||||
chart = Morris.Area $.extend {}, defaults
|
||||
$('#graph').find("path[fill-opacity='0.8']").size().should.equal 0
|
||||
|
||||
it 'should have a line with the fill of a modified line color', ->
|
||||
chart = Morris.Area $.extend {}, defaults
|
||||
$('#graph').find("path[fill='#0b62a4']").size().should.equal 0
|
||||
$('#graph').find("path[fill='#7a92a3']").size().should.equal 0
|
||||
@@ -0,0 +1,50 @@
|
||||
describe 'Morris.Bar', ->
|
||||
|
||||
describe 'svg structure', ->
|
||||
defaults =
|
||||
element: 'graph'
|
||||
data: [{x: 'foo', y: 2, z: 3}, {x: 'bar', y: 4, z: 6}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y', 'z']
|
||||
labels: ['Y', 'Z']
|
||||
|
||||
it 'should contain a rect for each bar', ->
|
||||
chart = Morris.Bar $.extend {}, defaults
|
||||
$('#graph').find("rect").size().should.equal 4
|
||||
|
||||
it 'should contain 5 grid lines', ->
|
||||
chart = Morris.Bar $.extend {}, defaults
|
||||
$('#graph').find("path").size().should.equal 5
|
||||
|
||||
it 'should contain 7 text elements', ->
|
||||
chart = Morris.Bar $.extend {}, defaults
|
||||
$('#graph').find("text").size().should.equal 7
|
||||
|
||||
describe 'svg attributes', ->
|
||||
defaults =
|
||||
element: 'graph'
|
||||
data: [{x: 'foo', y: 2, z: 3}, {x: 'bar', y: 4, z: 6}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y', 'z']
|
||||
labels: ['Y', 'Z']
|
||||
barColors: [ '#0b62a4', '#7a92a3']
|
||||
gridLineColor: '#aaa'
|
||||
gridStrokeWidth: 0.5
|
||||
gridTextColor: '#888'
|
||||
gridTextSize: 12
|
||||
|
||||
it 'should have a bar with the first default color', ->
|
||||
chart = Morris.Bar $.extend {}, defaults
|
||||
$('#graph').find("rect[fill='#0b62a4']").size().should.equal 2
|
||||
|
||||
it 'should have a bar with stroke width 0', ->
|
||||
chart = Morris.Bar $.extend {}, defaults
|
||||
$('#graph').find("rect[stroke-width='0']").size().should.equal 4
|
||||
|
||||
it 'should have text with configured fill color', ->
|
||||
chart = Morris.Bar $.extend {}, defaults
|
||||
$('#graph').find("text[fill='#888888']").size().should.equal 7
|
||||
|
||||
it 'should have text with configured font size', ->
|
||||
chart = Morris.Bar $.extend {}, defaults
|
||||
$('#graph').find("text[font-size='12px']").size().should.equal 7
|
||||
@@ -0,0 +1,36 @@
|
||||
describe 'Morris.Bar#colorFor', ->
|
||||
|
||||
defaults =
|
||||
element: 'graph'
|
||||
data: [{x: 'foo', y: 2, z: 3}, {x: 'bar', y: 4, z: 6}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y', 'z']
|
||||
labels: ['Y', 'Z']
|
||||
|
||||
it 'should fetch colours from an array', ->
|
||||
chart = Morris.Bar $.extend {}, defaults, barColors: ['#f00', '#0f0', '#00f']
|
||||
chart.colorFor(chart.data[0], 0, 'bar').should.equal '#f00'
|
||||
chart.colorFor(chart.data[0], 0, 'hover').should.equal '#f00'
|
||||
chart.colorFor(chart.data[0], 1, 'bar').should.equal '#0f0'
|
||||
chart.colorFor(chart.data[0], 1, 'hover').should.equal '#0f0'
|
||||
chart.colorFor(chart.data[0], 2, 'bar').should.equal '#00f'
|
||||
chart.colorFor(chart.data[0], 2, 'hover').should.equal '#00f'
|
||||
chart.colorFor(chart.data[0], 3, 'bar').should.equal '#f00'
|
||||
chart.colorFor(chart.data[0], 4, 'hover').should.equal '#0f0'
|
||||
|
||||
it 'should defer to a callback', ->
|
||||
stub = sinon.stub().returns '#f00'
|
||||
chart = Morris.Bar $.extend {}, defaults, barColors: stub
|
||||
stub.reset()
|
||||
|
||||
chart.colorFor(chart.data[0], 0, 'bar')
|
||||
stub.should.have.been.calledWith(
|
||||
{x:0, y:2, label:'foo'},
|
||||
{index:0, key:'y', label:'Y'},
|
||||
'bar')
|
||||
|
||||
chart.colorFor(chart.data[0], 1, 'hover')
|
||||
stub.should.have.been.calledWith(
|
||||
{x:0, y:3, label:'foo'},
|
||||
{index:1, key:'z', label:'Z'},
|
||||
'hover')
|
||||
@@ -0,0 +1,38 @@
|
||||
describe '#commas', ->
|
||||
|
||||
it 'should insert commas into long numbers', ->
|
||||
# zero
|
||||
Morris.commas(0).should.equal("0")
|
||||
|
||||
# positive integers
|
||||
Morris.commas(1).should.equal("1")
|
||||
Morris.commas(12).should.equal("12")
|
||||
Morris.commas(123).should.equal("123")
|
||||
Morris.commas(1234).should.equal("1,234")
|
||||
Morris.commas(12345).should.equal("12,345")
|
||||
Morris.commas(123456).should.equal("123,456")
|
||||
Morris.commas(1234567).should.equal("1,234,567")
|
||||
|
||||
# negative integers
|
||||
Morris.commas(-1).should.equal("-1")
|
||||
Morris.commas(-12).should.equal("-12")
|
||||
Morris.commas(-123).should.equal("-123")
|
||||
Morris.commas(-1234).should.equal("-1,234")
|
||||
Morris.commas(-12345).should.equal("-12,345")
|
||||
Morris.commas(-123456).should.equal("-123,456")
|
||||
Morris.commas(-1234567).should.equal("-1,234,567")
|
||||
|
||||
# positive decimals
|
||||
Morris.commas(1.2).should.equal("1.2")
|
||||
Morris.commas(12.34).should.equal("12.34")
|
||||
Morris.commas(123.456).should.equal("123.456")
|
||||
Morris.commas(1234.56).should.equal("1,234.56")
|
||||
|
||||
# negative decimals
|
||||
Morris.commas(-1.2).should.equal("-1.2")
|
||||
Morris.commas(-12.34).should.equal("-12.34")
|
||||
Morris.commas(-123.456).should.equal("-123.456")
|
||||
Morris.commas(-1234.56).should.equal("-1,234.56")
|
||||
|
||||
# null
|
||||
Morris.commas(null).should.equal('-')
|
||||
@@ -0,0 +1,61 @@
|
||||
describe 'Morris.Donut', ->
|
||||
|
||||
describe 'svg structure', ->
|
||||
defaults =
|
||||
element: 'graph'
|
||||
data: [ {label: 'Jam', value: 25 },
|
||||
{label: 'Frosted', value: 40 },
|
||||
{label: 'Custard', value: 25 },
|
||||
{label: 'Sugar', value: 10 } ]
|
||||
formatter: (y) -> "#{y}%"
|
||||
|
||||
it 'should contain 2 paths for each segment', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("path").size().should.equal 8
|
||||
|
||||
it 'should contain 2 text elements for the label', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("text").size().should.equal 2
|
||||
|
||||
describe 'svg attributes', ->
|
||||
defaults =
|
||||
defaults =
|
||||
element: 'graph'
|
||||
data: [ {label: 'Jam', value: 25 },
|
||||
{label: 'Frosted', value: 40 },
|
||||
{label: 'Custard', value: 25 },
|
||||
{label: 'Sugar', value: 10 } ]
|
||||
formatter: (y) -> "#{y}%"
|
||||
colors: [ '#0B62A4', '#3980B5', '#679DC6', '#95BBD7']
|
||||
|
||||
it 'should have a label with font size 15', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("text[font-size='15px']").size().should.equal 1
|
||||
|
||||
it 'should have a label with font size 14', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("text[font-size='14px']").size().should.equal 1
|
||||
|
||||
it 'should have a label with font-weight 800', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("text[font-weight='800']").size().should.equal 1
|
||||
|
||||
it 'should have 1 paths with fill of first color', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("path[fill='#0b62a4']").size().should.equal 1
|
||||
|
||||
it 'should have 1 paths with stroke of first color', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("path[stroke='#0b62a4']").size().should.equal 1
|
||||
|
||||
it 'should have a path with white stroke', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("path[stroke='#ffffff']").size().should.equal 4
|
||||
|
||||
it 'should have a path with stroke-width 3', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("path[stroke-width='3']").size().should.equal 4
|
||||
|
||||
it 'should have a path with stroke-width 2', ->
|
||||
chart = Morris.Donut $.extend {}, defaults
|
||||
$('#graph').find("path[stroke-width='2']").size().should.equal 4
|
||||
@@ -0,0 +1,25 @@
|
||||
describe 'Morris.Grid#autoGridLines', ->
|
||||
|
||||
beforeEach ->
|
||||
@subject = Morris.Grid.prototype.autoGridLines
|
||||
|
||||
it 'should draw at fixed intervals', ->
|
||||
@subject(0, 4, 5).should.deep.equal [0, 1, 2, 3, 4]
|
||||
@subject(0, 400, 5).should.deep.equal [0, 100, 200, 300, 400]
|
||||
|
||||
it 'should pick intervals that show significant numbers', ->
|
||||
@subject(102, 499, 5).should.deep.equal [100, 200, 300, 400, 500]
|
||||
|
||||
it 'should draw zero when it falls within [ymin..ymax]', ->
|
||||
@subject(-100, 300, 5).should.deep.equal [-100, 0, 100, 200, 300]
|
||||
@subject(-50, 350, 5).should.deep.equal [-125, 0, 125, 250, 375]
|
||||
@subject(-400, 400, 5).should.deep.equal [-400, -200, 0, 200, 400]
|
||||
@subject(100, 500, 5).should.deep.equal [100, 200, 300, 400, 500]
|
||||
@subject(-500, -100, 5).should.deep.equal [-500, -400, -300, -200, -100]
|
||||
|
||||
it 'should generate decimal labels to 2 significant figures', ->
|
||||
@subject(0, 1, 5).should.deep.equal [0, 0.25, 0.5, 0.75, 1]
|
||||
@subject(0.1, 0.5, 5).should.deep.equal [0.1, 0.2, 0.3, 0.4, 0.5]
|
||||
|
||||
it 'should use integer intervals for intervals larger than 1', ->
|
||||
@subject(0, 9, 5).should.deep.equal [0, 3, 6, 9, 12]
|
||||
@@ -0,0 +1,208 @@
|
||||
describe 'Morris.Grid#setData', ->
|
||||
|
||||
it 'should not alter user-supplied data', ->
|
||||
my_data = [{x: 1, y: 1}, {x: 2, y: 2}]
|
||||
expected_data = [{x: 1, y: 1}, {x: 2, y: 2}]
|
||||
Morris.Line
|
||||
element: 'graph'
|
||||
data: my_data
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['dontcare']
|
||||
my_data.should.deep.equal expected_data
|
||||
|
||||
describe 'ymin/ymax', ->
|
||||
beforeEach ->
|
||||
@defaults =
|
||||
element: 'graph'
|
||||
xkey: 'x'
|
||||
ykeys: ['y', 'z']
|
||||
labels: ['y', 'z']
|
||||
|
||||
it 'should use a user-specified minimum and maximum value', ->
|
||||
line = Morris.Line $.extend @defaults,
|
||||
data: [{x: 1, y: 1}]
|
||||
ymin: 10
|
||||
ymax: 20
|
||||
line.ymin.should.equal 10
|
||||
line.ymax.should.equal 20
|
||||
|
||||
describe 'auto', ->
|
||||
|
||||
it 'should automatically calculate the minimum and maximum value', ->
|
||||
line = Morris.Line $.extend @defaults,
|
||||
data: [{x: 1, y: 10}, {x: 2, y: 15}, {x: 3, y: null}, {x: 4}]
|
||||
ymin: 'auto'
|
||||
ymax: 'auto'
|
||||
line.ymin.should.equal 10
|
||||
line.ymax.should.equal 15
|
||||
|
||||
it 'should automatically calculate the minimum and maximum value given no y data', ->
|
||||
line = Morris.Line $.extend @defaults,
|
||||
data: [{x: 1}, {x: 2}, {x: 3}, {x: 4}]
|
||||
ymin: 'auto'
|
||||
ymax: 'auto'
|
||||
line.ymin.should.equal 0
|
||||
line.ymax.should.equal 1
|
||||
|
||||
describe 'auto [n]', ->
|
||||
|
||||
it 'should automatically calculate the minimum and maximum value', ->
|
||||
line = Morris.Line $.extend @defaults,
|
||||
data: [{x: 1, y: 10}, {x: 2, y: 15}, {x: 3, y: null}, {x: 4}]
|
||||
ymin: 'auto 11'
|
||||
ymax: 'auto 13'
|
||||
line.ymin.should.equal 10
|
||||
line.ymax.should.equal 15
|
||||
|
||||
it 'should automatically calculate the minimum and maximum value given no data', ->
|
||||
line = Morris.Line $.extend @defaults,
|
||||
data: [{x: 1}, {x: 2}, {x: 3}, {x: 4}]
|
||||
ymin: 'auto 11'
|
||||
ymax: 'auto 13'
|
||||
line.ymin.should.equal 11
|
||||
line.ymax.should.equal 13
|
||||
|
||||
it 'should use a user-specified minimum and maximum value', ->
|
||||
line = Morris.Line $.extend @defaults,
|
||||
data: [{x: 1, y: 10}, {x: 2, y: 15}, {x: 3, y: null}, {x: 4}]
|
||||
ymin: 'auto 5'
|
||||
ymax: 'auto 20'
|
||||
line.ymin.should.equal 5
|
||||
line.ymax.should.equal 20
|
||||
|
||||
it 'should use a user-specified minimum and maximum value given no data', ->
|
||||
line = Morris.Line $.extend @defaults,
|
||||
data: [{x: 1}, {x: 2}, {x: 3}, {x: 4}]
|
||||
ymin: 'auto 5'
|
||||
ymax: 'auto 20'
|
||||
line.ymin.should.equal 5
|
||||
line.ymax.should.equal 20
|
||||
|
||||
describe 'xmin/xmax', ->
|
||||
|
||||
it 'should calculate the horizontal range', ->
|
||||
line = Morris.Line
|
||||
element: 'graph'
|
||||
data: [{x: 2, y: 2}, {x: 1, y: 1}, {x: 4, y: 4}, {x: 3, y: 3}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['y']
|
||||
line.xmin.should == 1
|
||||
line.xmax.should == 4
|
||||
|
||||
it "should pad the range if there's only one data point", ->
|
||||
line = Morris.Line
|
||||
element: 'graph'
|
||||
data: [{x: 2, y: 2}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['y']
|
||||
line.xmin.should == 1
|
||||
line.xmax.should == 3
|
||||
|
||||
describe 'sorting', ->
|
||||
|
||||
it 'should sort data when parseTime is true', ->
|
||||
line = Morris.Line
|
||||
element: 'graph'
|
||||
data: [
|
||||
{x: '2012 Q1', y: 2},
|
||||
{x: '2012 Q3', y: 1},
|
||||
{x: '2012 Q4', y: 4},
|
||||
{x: '2012 Q2', y: 3}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['y']
|
||||
line.data.map((row) -> row.label).should.deep.equal ['2012 Q1', '2012 Q2', '2012 Q3', '2012 Q4']
|
||||
|
||||
it 'should not sort data when parseTime is false', ->
|
||||
line = Morris.Line
|
||||
element: 'graph'
|
||||
data: [{x: 1, y: 2}, {x: 4, y: 1}, {x: 3, y: 4}, {x: 2, y: 3}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['y']
|
||||
parseTime: false
|
||||
line.data.map((row) -> row.label).should.deep.equal [1, 4, 3, 2]
|
||||
|
||||
describe 'timestamp data', ->
|
||||
|
||||
it 'should generate default labels for timestamp x-values', ->
|
||||
d = [
|
||||
new Date 2012, 0, 1
|
||||
new Date 2012, 0, 2
|
||||
new Date 2012, 0, 3
|
||||
new Date 2012, 0, 4
|
||||
]
|
||||
line = Morris.Line
|
||||
element: 'graph'
|
||||
data: [
|
||||
{x: d[0].getTime(), y: 2},
|
||||
{x: d[1].getTime(), y: 1},
|
||||
{x: d[2].getTime(), y: 4},
|
||||
{x: d[3].getTime(), y: 3}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['y']
|
||||
line.data.map((row) -> row.label).should.deep.equal d.map((t) -> t.toString())
|
||||
|
||||
it 'should use a user-supplied formatter for labels', ->
|
||||
line = Morris.Line
|
||||
element: 'graph'
|
||||
data: [
|
||||
{x: new Date(2012, 0, 1).getTime(), y: 2},
|
||||
{x: new Date(2012, 0, 2).getTime(), y: 1},
|
||||
{x: new Date(2012, 0, 3).getTime(), y: 4},
|
||||
{x: new Date(2012, 0, 4).getTime(), y: 3}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['y']
|
||||
dateFormat: (ts) ->
|
||||
date = new Date(ts)
|
||||
"#{date.getFullYear()}-#{date.getMonth()+1}-#{date.getDate()}"
|
||||
line.data.map((row) -> row.label).should.deep.equal ['2012-1-1', '2012-1-2', '2012-1-3', '2012-1-4']
|
||||
|
||||
it 'should parse y-values in strings', ->
|
||||
line = Morris.Line
|
||||
element: 'graph'
|
||||
data: [{x: 2, y: '12'}, {x: 1, y: '13.5'}, {x: 4, y: '14'}, {x: 3, y: '16'}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['y']
|
||||
line.ymin.should == 12
|
||||
line.ymax.should == 16
|
||||
line.data.map((row) -> row.y).should.deep.equal [[13.5], [12], [16], [14]]
|
||||
|
||||
it 'should clear the chart when empty data is supplied', ->
|
||||
line = Morris.Line
|
||||
element: 'graph',
|
||||
data: [{x: 2, y: '12'}, {x: 1, y: '13.5'}, {x: 4, y: '14'}, {x: 3, y: '16'}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['y']
|
||||
line.data.length.should.equal 4
|
||||
line.setData([])
|
||||
line.data.length.should.equal 0
|
||||
line.setData([{x: 2, y: '12'}, {x: 1, y: '13.5'}, {x: 4, y: '14'}, {x: 3, y: '16'}])
|
||||
line.data.length.should.equal 4
|
||||
|
||||
it 'should be able to add data if the chart is initialised with empty data', ->
|
||||
line = Morris.Line
|
||||
element: 'graph',
|
||||
data: []
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['y']
|
||||
line.data.length.should.equal 0
|
||||
line.setData([{x: 2, y: '12'}, {x: 1, y: '13.5'}, {x: 4, y: '14'}, {x: 3, y: '16'}])
|
||||
line.data.length.should.equal 4
|
||||
|
||||
it 'should automatically choose significant numbers for y-labels', ->
|
||||
line = Morris.Line
|
||||
element: 'graph',
|
||||
data: [{x: 1, y: 0}, {x: 2, y: 3600}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['y']
|
||||
line.grid.should == [0, 1000, 2000, 3000, 4000]
|
||||
@@ -0,0 +1,15 @@
|
||||
describe 'Morris.Grid#yLabelFormat', ->
|
||||
|
||||
it 'should use custom formatter for y labels', ->
|
||||
formatter = (label) ->
|
||||
flabel = parseFloat(label) / 1000
|
||||
"#{flabel.toFixed(1)}k"
|
||||
line = Morris.Line
|
||||
element: 'graph'
|
||||
data: [{x: 1, y: 1500}, {x: 2, y: 2500}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['dontcare']
|
||||
preUnits: "$"
|
||||
yLabelFormat: formatter
|
||||
line.yLabelFormat(1500).should.equal "1.5k"
|
||||
@@ -0,0 +1,64 @@
|
||||
describe "Morris.Hover", ->
|
||||
|
||||
describe "with dummy content", ->
|
||||
|
||||
beforeEach ->
|
||||
parent = $('<div style="width:200px;height:180px"></div>')
|
||||
.appendTo($('#test'))
|
||||
@hover = new Morris.Hover(parent: parent)
|
||||
@element = $('#test .morris-hover')
|
||||
|
||||
it "should initialise a hidden, empty popup", ->
|
||||
@element.should.exist
|
||||
@element.should.be.hidden
|
||||
@element.should.be.empty
|
||||
|
||||
describe "#show", ->
|
||||
it "should show the popup", ->
|
||||
@hover.show()
|
||||
@element.should.be.visible
|
||||
|
||||
describe "#hide", ->
|
||||
it "should hide the popup", ->
|
||||
@hover.show()
|
||||
@hover.hide()
|
||||
@element.should.be.hidden
|
||||
|
||||
describe "#html", ->
|
||||
it "should replace the contents of the element", ->
|
||||
@hover.html('<div>Foobarbaz</div>')
|
||||
@element.should.have.html('<div>Foobarbaz</div>')
|
||||
|
||||
describe "#moveTo", ->
|
||||
beforeEach ->
|
||||
@hover.html('<div style="width:84px;height:84px"></div>')
|
||||
|
||||
it "should place the popup directly above the given point", ->
|
||||
@hover.moveTo(100, 150)
|
||||
@element.should.have.css('left', '50px')
|
||||
@element.should.have.css('top', '40px')
|
||||
|
||||
it "should place the popup below the given point if it does not fit above", ->
|
||||
@hover.moveTo(100, 50)
|
||||
@element.should.have.css('left', '50px')
|
||||
@element.should.have.css('top', '60px')
|
||||
|
||||
it "should center the popup vertically if it will not fit above or below", ->
|
||||
@hover.moveTo(100, 100)
|
||||
@element.should.have.css('left', '50px')
|
||||
@element.should.have.css('top', '40px')
|
||||
|
||||
it "should center the popup vertically if no y value is supplied", ->
|
||||
@hover.moveTo(100)
|
||||
@element.should.have.css('left', '50px')
|
||||
@element.should.have.css('top', '40px')
|
||||
|
||||
describe "#update", ->
|
||||
it "should update content, show and reposition the popup", ->
|
||||
hover = new Morris.Hover(parent: $('#test'))
|
||||
html = "<div style='width:84px;height:84px'>Hello, Everyone!</div>"
|
||||
hover.update(html, 150, 200)
|
||||
el = $('#test .morris-hover')
|
||||
el.should.have.css('left', '100px')
|
||||
el.should.have.css('top', '90px')
|
||||
el.should.have.text('Hello, Everyone!')
|
||||
@@ -0,0 +1,172 @@
|
||||
describe '#labelSeries', ->
|
||||
|
||||
it 'should generate decade intervals', ->
|
||||
Morris.labelSeries(
|
||||
new Date(1952, 0, 1).getTime(),
|
||||
new Date(2012, 0, 1).getTime(),
|
||||
1000
|
||||
).should.deep.equal([
|
||||
["1960", new Date(1960, 0, 1).getTime()],
|
||||
["1970", new Date(1970, 0, 1).getTime()],
|
||||
["1980", new Date(1980, 0, 1).getTime()],
|
||||
["1990", new Date(1990, 0, 1).getTime()],
|
||||
["2000", new Date(2000, 0, 1).getTime()],
|
||||
["2010", new Date(2010, 0, 1).getTime()]
|
||||
])
|
||||
Morris.labelSeries(
|
||||
new Date(1952, 3, 1).getTime(),
|
||||
new Date(2012, 3, 1).getTime(),
|
||||
1000
|
||||
).should.deep.equal([
|
||||
["1960", new Date(1960, 0, 1).getTime()],
|
||||
["1970", new Date(1970, 0, 1).getTime()],
|
||||
["1980", new Date(1980, 0, 1).getTime()],
|
||||
["1990", new Date(1990, 0, 1).getTime()],
|
||||
["2000", new Date(2000, 0, 1).getTime()],
|
||||
["2010", new Date(2010, 0, 1).getTime()]
|
||||
])
|
||||
|
||||
it 'should generate year intervals', ->
|
||||
Morris.labelSeries(
|
||||
new Date(2007, 0, 1).getTime(),
|
||||
new Date(2012, 0, 1).getTime(),
|
||||
1000
|
||||
).should.deep.equal([
|
||||
["2007", new Date(2007, 0, 1).getTime()],
|
||||
["2008", new Date(2008, 0, 1).getTime()],
|
||||
["2009", new Date(2009, 0, 1).getTime()],
|
||||
["2010", new Date(2010, 0, 1).getTime()],
|
||||
["2011", new Date(2011, 0, 1).getTime()],
|
||||
["2012", new Date(2012, 0, 1).getTime()]
|
||||
])
|
||||
Morris.labelSeries(
|
||||
new Date(2007, 3, 1).getTime(),
|
||||
new Date(2012, 3, 1).getTime(),
|
||||
1000
|
||||
).should.deep.equal([
|
||||
["2008", new Date(2008, 0, 1).getTime()],
|
||||
["2009", new Date(2009, 0, 1).getTime()],
|
||||
["2010", new Date(2010, 0, 1).getTime()],
|
||||
["2011", new Date(2011, 0, 1).getTime()],
|
||||
["2012", new Date(2012, 0, 1).getTime()]
|
||||
])
|
||||
|
||||
it 'should generate month intervals', ->
|
||||
Morris.labelSeries(
|
||||
new Date(2012, 0, 1).getTime(),
|
||||
new Date(2012, 5, 1).getTime(),
|
||||
1000
|
||||
).should.deep.equal([
|
||||
["2012-01", new Date(2012, 0, 1).getTime()],
|
||||
["2012-02", new Date(2012, 1, 1).getTime()],
|
||||
["2012-03", new Date(2012, 2, 1).getTime()],
|
||||
["2012-04", new Date(2012, 3, 1).getTime()],
|
||||
["2012-05", new Date(2012, 4, 1).getTime()],
|
||||
["2012-06", new Date(2012, 5, 1).getTime()]
|
||||
])
|
||||
|
||||
it 'should generate day intervals', ->
|
||||
Morris.labelSeries(
|
||||
new Date(2012, 0, 1).getTime(),
|
||||
new Date(2012, 0, 6).getTime(),
|
||||
1000
|
||||
).should.deep.equal([
|
||||
["2012-01-01", new Date(2012, 0, 1).getTime()],
|
||||
["2012-01-02", new Date(2012, 0, 2).getTime()],
|
||||
["2012-01-03", new Date(2012, 0, 3).getTime()],
|
||||
["2012-01-04", new Date(2012, 0, 4).getTime()],
|
||||
["2012-01-05", new Date(2012, 0, 5).getTime()],
|
||||
["2012-01-06", new Date(2012, 0, 6).getTime()]
|
||||
])
|
||||
|
||||
it 'should generate hour intervals', ->
|
||||
Morris.labelSeries(
|
||||
new Date(2012, 0, 1, 0).getTime(),
|
||||
new Date(2012, 0, 1, 5).getTime(),
|
||||
1000
|
||||
).should.deep.equal([
|
||||
["00:00", new Date(2012, 0, 1, 0).getTime()],
|
||||
["01:00", new Date(2012, 0, 1, 1).getTime()],
|
||||
["02:00", new Date(2012, 0, 1, 2).getTime()],
|
||||
["03:00", new Date(2012, 0, 1, 3).getTime()],
|
||||
["04:00", new Date(2012, 0, 1, 4).getTime()],
|
||||
["05:00", new Date(2012, 0, 1, 5).getTime()]
|
||||
])
|
||||
|
||||
it 'should generate half-hour intervals', ->
|
||||
Morris.labelSeries(
|
||||
new Date(2012, 0, 1, 0, 0).getTime(),
|
||||
new Date(2012, 0, 1, 2, 30).getTime(),
|
||||
1000
|
||||
).should.deep.equal([
|
||||
["00:00", new Date(2012, 0, 1, 0, 0).getTime()],
|
||||
["00:30", new Date(2012, 0, 1, 0, 30).getTime()],
|
||||
["01:00", new Date(2012, 0, 1, 1, 0).getTime()],
|
||||
["01:30", new Date(2012, 0, 1, 1, 30).getTime()],
|
||||
["02:00", new Date(2012, 0, 1, 2, 0).getTime()],
|
||||
["02:30", new Date(2012, 0, 1, 2, 30).getTime()]
|
||||
])
|
||||
Morris.labelSeries(
|
||||
new Date(2012, 4, 12, 0, 0).getTime(),
|
||||
new Date(2012, 4, 12, 2, 30).getTime(),
|
||||
1000
|
||||
).should.deep.equal([
|
||||
["00:00", new Date(2012, 4, 12, 0, 0).getTime()],
|
||||
["00:30", new Date(2012, 4, 12, 0, 30).getTime()],
|
||||
["01:00", new Date(2012, 4, 12, 1, 0).getTime()],
|
||||
["01:30", new Date(2012, 4, 12, 1, 30).getTime()],
|
||||
["02:00", new Date(2012, 4, 12, 2, 0).getTime()],
|
||||
["02:30", new Date(2012, 4, 12, 2, 30).getTime()]
|
||||
])
|
||||
|
||||
it 'should generate fifteen-minute intervals', ->
|
||||
Morris.labelSeries(
|
||||
new Date(2012, 0, 1, 0, 0).getTime(),
|
||||
new Date(2012, 0, 1, 1, 15).getTime(),
|
||||
1000
|
||||
).should.deep.equal([
|
||||
["00:00", new Date(2012, 0, 1, 0, 0).getTime()],
|
||||
["00:15", new Date(2012, 0, 1, 0, 15).getTime()],
|
||||
["00:30", new Date(2012, 0, 1, 0, 30).getTime()],
|
||||
["00:45", new Date(2012, 0, 1, 0, 45).getTime()],
|
||||
["01:00", new Date(2012, 0, 1, 1, 0).getTime()],
|
||||
["01:15", new Date(2012, 0, 1, 1, 15).getTime()]
|
||||
])
|
||||
Morris.labelSeries(
|
||||
new Date(2012, 4, 12, 0, 0).getTime(),
|
||||
new Date(2012, 4, 12, 1, 15).getTime(),
|
||||
1000
|
||||
).should.deep.equal([
|
||||
["00:00", new Date(2012, 4, 12, 0, 0).getTime()],
|
||||
["00:15", new Date(2012, 4, 12, 0, 15).getTime()],
|
||||
["00:30", new Date(2012, 4, 12, 0, 30).getTime()],
|
||||
["00:45", new Date(2012, 4, 12, 0, 45).getTime()],
|
||||
["01:00", new Date(2012, 4, 12, 1, 0).getTime()],
|
||||
["01:15", new Date(2012, 4, 12, 1, 15).getTime()]
|
||||
])
|
||||
|
||||
it 'should override automatic intervals', ->
|
||||
Morris.labelSeries(
|
||||
new Date(2011, 11, 12).getTime(),
|
||||
new Date(2012, 0, 12).getTime(),
|
||||
1000,
|
||||
"year"
|
||||
).should.deep.equal([
|
||||
["2012", new Date(2012, 0, 1).getTime()]
|
||||
])
|
||||
|
||||
it 'should apply custom formatters', ->
|
||||
Morris.labelSeries(
|
||||
new Date(2012, 0, 1).getTime(),
|
||||
new Date(2012, 0, 6).getTime(),
|
||||
1000,
|
||||
"day",
|
||||
(d) -> "#{d.getMonth()+1}/#{d.getDate()}/#{d.getFullYear()}"
|
||||
).should.deep.equal([
|
||||
["1/1/2012", new Date(2012, 0, 1).getTime()],
|
||||
["1/2/2012", new Date(2012, 0, 2).getTime()],
|
||||
["1/3/2012", new Date(2012, 0, 3).getTime()],
|
||||
["1/4/2012", new Date(2012, 0, 4).getTime()],
|
||||
["1/5/2012", new Date(2012, 0, 5).getTime()],
|
||||
["1/6/2012", new Date(2012, 0, 6).getTime()]
|
||||
])
|
||||
@@ -0,0 +1,207 @@
|
||||
describe 'Morris.Line', ->
|
||||
|
||||
it 'should raise an error when the placeholder element is not found', ->
|
||||
my_data = [{x: 1, y: 1}, {x: 2, y: 2}]
|
||||
fn = ->
|
||||
Morris.Line(
|
||||
element: "thisplacedoesnotexist"
|
||||
data: my_data
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['dontcare']
|
||||
)
|
||||
fn.should.throw(/Graph container element not found/)
|
||||
|
||||
it 'should make point styles customizable', ->
|
||||
my_data = [{x: 1, y: 1}, {x: 2, y: 2}]
|
||||
red = '#ff0000'
|
||||
blue = '#0000ff'
|
||||
chart = Morris.Line
|
||||
element: 'graph'
|
||||
data: my_data
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['dontcare']
|
||||
pointStrokeColors: [red, blue]
|
||||
pointWidths: [1, 2]
|
||||
pointFillColors: [null, red]
|
||||
chart.strokeWidthForSeries(0).should.equal 1
|
||||
chart.strokeForSeries(0).should.equal red
|
||||
chart.strokeWidthForSeries(1).should.equal 2
|
||||
chart.strokeForSeries(1).should.equal blue
|
||||
chart.colorFor(chart.data[0], 0, 'point').should.equal chart.colorFor(chart.data[0], 0, 'line')
|
||||
chart.colorFor(chart.data[1], 1, 'point').should.equal red
|
||||
|
||||
describe 'generating column labels', ->
|
||||
|
||||
it 'should use user-supplied x value strings by default', ->
|
||||
chart = Morris.Line
|
||||
element: 'graph'
|
||||
data: [{x: '2012 Q1', y: 1}, {x: '2012 Q2', y: 1}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['dontcare']
|
||||
chart.data.map((x) -> x.label).should == ['2012 Q1', '2012 Q2']
|
||||
|
||||
it 'should use a default format for timestamp x-values', ->
|
||||
d1 = new Date(2012, 0, 1)
|
||||
d2 = new Date(2012, 0, 2)
|
||||
chart = Morris.Line
|
||||
element: 'graph'
|
||||
data: [{x: d1.getTime(), y: 1}, {x: d2.getTime(), y: 1}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['dontcare']
|
||||
chart.data.map((x) -> x.label).should == [d2.toString(), d1.toString()]
|
||||
|
||||
it 'should use user-defined formatters', ->
|
||||
d = new Date(2012, 0, 1)
|
||||
chart = Morris.Line
|
||||
element: 'graph'
|
||||
data: [{x: d.getTime(), y: 1}, {x: '2012-01-02', y: 1}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['dontcare']
|
||||
dateFormat: (d) ->
|
||||
x = new Date(d)
|
||||
"#{x.getYear()}/#{x.getMonth()+1}/#{x.getDay()}"
|
||||
chart.data.map((x) -> x.label).should == ['2012/1/1', '2012/1/2']
|
||||
|
||||
describe 'rendering lines', ->
|
||||
beforeEach ->
|
||||
@defaults =
|
||||
element: 'graph'
|
||||
data: [{x:0, y:1, z:0}, {x:1, y:0, z:1}, {x:2, y:1, z:0}, {x:3, y:0, z:1}, {x:4, y:1, z:0}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y', 'z']
|
||||
labels: ['y', 'z']
|
||||
lineColors: ['#abcdef', '#fedcba']
|
||||
smooth: true
|
||||
continuousLine: false
|
||||
|
||||
shouldHavePath = (regex, color = '#abcdef') ->
|
||||
# Matches an SVG path element within the rendered chart.
|
||||
#
|
||||
# Sneakily uses line colors to differentiate between paths within
|
||||
# the chart.
|
||||
$('#graph').find("path[stroke='#{color}']").attr('d').should.match regex
|
||||
|
||||
it 'should generate smooth lines when options.smooth is true', ->
|
||||
Morris.Line @defaults
|
||||
shouldHavePath /M[\d\.]+,[\d\.]+(C[\d\.]+(,[\d\.]+){5}){4}/
|
||||
|
||||
it 'should generate jagged lines when options.smooth is false', ->
|
||||
Morris.Line $.extend(@defaults, smooth: false)
|
||||
shouldHavePath /M[\d\.]+,[\d\.]+(L[\d\.]+,[\d\.]+){4}/
|
||||
|
||||
it 'should generate smooth/jagged lines according to the value for each series when options.smooth is an array', ->
|
||||
Morris.Line $.extend(@defaults, smooth: ['y'])
|
||||
shouldHavePath /M[\d\.]+,[\d\.]+(C[\d\.]+(,[\d\.]+){5}){4}/, '#abcdef'
|
||||
shouldHavePath /M[\d\.]+,[\d\.]+(L[\d\.]+,[\d\.]+){4}/, '#fedcba'
|
||||
|
||||
it 'should ignore undefined values', ->
|
||||
@defaults.data[2].y = undefined
|
||||
Morris.Line @defaults
|
||||
shouldHavePath /M[\d\.]+,[\d\.]+(C[\d\.]+(,[\d\.]+){5}){3}/
|
||||
|
||||
it 'should ignore null values when options.continuousLine is true', ->
|
||||
@defaults.data[2].y = null
|
||||
Morris.Line $.extend(@defaults, continuousLine: true)
|
||||
shouldHavePath /M[\d\.]+,[\d\.]+(C[\d\.]+(,[\d\.]+){5}){3}/
|
||||
|
||||
it 'should break the line at null values when options.continuousLine is false', ->
|
||||
@defaults.data[2].y = null
|
||||
Morris.Line @defaults
|
||||
shouldHavePath /(M[\d\.]+,[\d\.]+C[\d\.]+(,[\d\.]+){5}){2}/
|
||||
|
||||
describe '#createPath', ->
|
||||
|
||||
it 'should generate a smooth line', ->
|
||||
testData = [{x: 0, y: 10}, {x: 10, y: 0}, {x: 20, y: 10}]
|
||||
path = Morris.Line.createPath(testData, true, 20)
|
||||
path.should.equal 'M0,10C2.5,7.5,7.5,0,10,0C12.5,0,17.5,7.5,20,10'
|
||||
|
||||
it 'should generate a jagged line', ->
|
||||
testData = [{x: 0, y: 10}, {x: 10, y: 0}, {x: 20, y: 10}]
|
||||
path = Morris.Line.createPath(testData, false, 20)
|
||||
path.should.equal 'M0,10L10,0L20,10'
|
||||
|
||||
it 'should prevent paths from descending below the bottom of the chart', ->
|
||||
testData = [{x: 0, y: 20}, {x: 10, y: 30}, {x: 20, y: 10}]
|
||||
path = Morris.Line.createPath(testData, true, 30)
|
||||
path.should.equal 'M0,20C2.5,22.5,7.5,30,10,30C12.5,28.75,17.5,15,20,10'
|
||||
|
||||
it 'should break the line at null values', ->
|
||||
testData = [{x: 0, y: 10}, {x: 10, y: 0}, {x: 20, y: null}, {x: 30, y: 10}, {x: 40, y: 0}]
|
||||
path = Morris.Line.createPath(testData, true, 20)
|
||||
path.should.equal 'M0,10C2.5,7.5,7.5,2.5,10,0M30,10C32.5,7.5,37.5,2.5,40,0'
|
||||
|
||||
it 'should ignore leading and trailing null values', ->
|
||||
testData = [{x: 0, y: null}, {x: 10, y: 10}, {x: 20, y: 0}, {x: 30, y: 10}, {x: 40, y: null}]
|
||||
path = Morris.Line.createPath(testData, true, 20)
|
||||
path.should.equal 'M10,10C12.5,7.5,17.5,0,20,0C22.5,0,27.5,7.5,30,10'
|
||||
|
||||
describe 'svg structure', ->
|
||||
defaults =
|
||||
element: 'graph'
|
||||
data: [{x: '2012 Q1', y: 1}, {x: '2012 Q2', y: 1}]
|
||||
lineColors: [ '#0b62a4', '#7a92a3']
|
||||
xkey: 'x'
|
||||
ykeys: ['y']
|
||||
labels: ['dontcare']
|
||||
|
||||
it 'should contain a path that represents the line', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("path[stroke='#0b62a4']").size().should.equal 1
|
||||
|
||||
it 'should contain a circle for each data point', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("circle").size().should.equal 2
|
||||
|
||||
it 'should contain 5 grid lines', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("path[stroke='#aaaaaa']").size().should.equal 5
|
||||
|
||||
it 'should contain 9 text elements', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("text").size().should.equal 9
|
||||
|
||||
describe 'svg attributes', ->
|
||||
defaults =
|
||||
element: 'graph'
|
||||
data: [{x: '2012 Q1', y: 1}, {x: '2012 Q2', y: 1}]
|
||||
xkey: 'x'
|
||||
ykeys: ['y', 'z']
|
||||
labels: ['Y', 'Z']
|
||||
lineColors: [ '#0b62a4', '#7a92a3']
|
||||
lineWidth: 3
|
||||
pointWidths: [5]
|
||||
pointStrokeColors: ['#ffffff']
|
||||
gridLineColor: '#aaa'
|
||||
gridStrokeWidth: 0.5
|
||||
gridTextColor: '#888'
|
||||
gridTextSize: 12
|
||||
|
||||
it 'should have circles with configured fill color', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("circle[fill='#0b62a4']").size().should.equal 2
|
||||
|
||||
it 'should have circles with configured stroke width', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("circle[stroke-width='5']").size().should.equal 2
|
||||
|
||||
it 'should have circles with configured stroke color', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("circle[stroke='#ffffff']").size().should.equal 2
|
||||
|
||||
it 'should have line with configured line width', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("path[stroke-width='3']").size().should.equal 1
|
||||
|
||||
it 'should have text with configured font size', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("text[font-size='12px']").size().should.equal 9
|
||||
|
||||
it 'should have text with configured font size', ->
|
||||
chart = Morris.Line $.extend {}, defaults
|
||||
$('#graph').find("text[fill='#888888']").size().should.equal 9
|
||||
@@ -0,0 +1,17 @@
|
||||
describe '#pad', ->
|
||||
|
||||
it 'should pad numbers', ->
|
||||
Morris.pad2(0).should.equal("00")
|
||||
Morris.pad2(1).should.equal("01")
|
||||
Morris.pad2(2).should.equal("02")
|
||||
Morris.pad2(3).should.equal("03")
|
||||
Morris.pad2(4).should.equal("04")
|
||||
Morris.pad2(5).should.equal("05")
|
||||
Morris.pad2(6).should.equal("06")
|
||||
Morris.pad2(7).should.equal("07")
|
||||
Morris.pad2(8).should.equal("08")
|
||||
Morris.pad2(9).should.equal("09")
|
||||
Morris.pad2(10).should.equal("10")
|
||||
Morris.pad2(12).should.equal("12")
|
||||
Morris.pad2(34).should.equal("34")
|
||||
Morris.pad2(123).should.equal("123")
|
||||
@@ -0,0 +1,35 @@
|
||||
describe '#parseTime', ->
|
||||
|
||||
it 'should parse years', ->
|
||||
Morris.parseDate('2012').should.equal(new Date(2012, 0, 1).getTime())
|
||||
|
||||
it 'should parse quarters', ->
|
||||
Morris.parseDate('2012 Q1').should.equal(new Date(2012, 2, 1).getTime())
|
||||
|
||||
it 'should parse months', ->
|
||||
Morris.parseDate('2012-09').should.equal(new Date(2012, 8, 1).getTime())
|
||||
Morris.parseDate('2012-10').should.equal(new Date(2012, 9, 1).getTime())
|
||||
|
||||
it 'should parse dates', ->
|
||||
Morris.parseDate('2012-09-15').should.equal(new Date(2012, 8, 15).getTime())
|
||||
Morris.parseDate('2012-10-15').should.equal(new Date(2012, 9, 15).getTime())
|
||||
|
||||
it 'should parse times', ->
|
||||
Morris.parseDate("2012-10-15 12:34").should.equal(new Date(2012, 9, 15, 12, 34).getTime())
|
||||
Morris.parseDate("2012-10-15T12:34").should.equal(new Date(2012, 9, 15, 12, 34).getTime())
|
||||
Morris.parseDate("2012-10-15 12:34:55").should.equal(new Date(2012, 9, 15, 12, 34, 55).getTime())
|
||||
Morris.parseDate("2012-10-15T12:34:55").should.equal(new Date(2012, 9, 15, 12, 34, 55).getTime())
|
||||
|
||||
it 'should parse times with timezones', ->
|
||||
Morris.parseDate("2012-10-15T12:34+0100").should.equal(Date.UTC(2012, 9, 15, 11, 34))
|
||||
Morris.parseDate("2012-10-15T12:34+02:00").should.equal(Date.UTC(2012, 9, 15, 10, 34))
|
||||
Morris.parseDate("2012-10-15T12:34-0100").should.equal(Date.UTC(2012, 9, 15, 13, 34))
|
||||
Morris.parseDate("2012-10-15T12:34-02:00").should.equal(Date.UTC(2012, 9, 15, 14, 34))
|
||||
Morris.parseDate("2012-10-15T12:34:55Z").should.equal(Date.UTC(2012, 9, 15, 12, 34, 55))
|
||||
Morris.parseDate("2012-10-15T12:34:55+0600").should.equal(Date.UTC(2012, 9, 15, 6, 34, 55))
|
||||
Morris.parseDate("2012-10-15T12:34:55+04:00").should.equal(Date.UTC(2012, 9, 15, 8, 34, 55))
|
||||
Morris.parseDate("2012-10-15T12:34:55-0600").should.equal(Date.UTC(2012, 9, 15, 18, 34, 55))
|
||||
|
||||
it 'should pass-through timestamps', ->
|
||||
Morris.parseDate(new Date(2012, 9, 15, 12, 34, 55, 123).getTime())
|
||||
.should.equal(new Date(2012, 9, 15, 12, 34, 55, 123).getTime())
|
||||
35
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/specs.html
Normal file
35
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/specs.html
Normal file
@@ -0,0 +1,35 @@
|
||||
<!doctype html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>morris.js tests</title>
|
||||
<link rel="stylesheet" href="vendor/mocha-1.6.0.css" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="../morris.css" type="text/css" media="screen" />
|
||||
<script src="vendor/jquery-1.8.2.min.js"></script>
|
||||
<script type="text/javascript" src="vendor/raphael-2.1.0.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
|
||||
<script type="text/javascript" src="vendor/mocha-1.6.0.js"></script>
|
||||
<script>
|
||||
mocha.setup('bdd');
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="vendor/chai-1.3.0.js"></script>
|
||||
<script type="text/javascript" src="vendor/chai-jquery-1.1.0.js"></script>
|
||||
<script type="text/javascript" src="vendor/sinon-1.5.0.js"></script>
|
||||
<script type="text/javascript" src="vendor/sinon-chai-2.1.2.js"></script>
|
||||
<script>
|
||||
should = chai.should();
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="../morris.js"></script>
|
||||
<script type="text/javascript" src="../build/spec.js"></script>
|
||||
<div id="test" style="width: 400px; height: 200px;"></div>
|
||||
<script>
|
||||
if (navigator.userAgent.indexOf('PhantomJS') < 0) {
|
||||
mocha.run();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,6 @@
|
||||
beforeEach ->
|
||||
placeholder = $('<div id="graph" style="width: 600px; height: 400px"></div>')
|
||||
$('#test').append(placeholder)
|
||||
|
||||
afterEach ->
|
||||
$('#test').empty()
|
||||
3649
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/vendor/chai-1.3.0.js
vendored
Normal file
3649
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/vendor/chai-1.3.0.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
232
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/vendor/chai-jquery-1.1.0.js
vendored
Normal file
232
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/vendor/chai-jquery-1.1.0.js
vendored
Normal file
@@ -0,0 +1,232 @@
|
||||
(function (chaiJquery) {
|
||||
// Module systems magic dance.
|
||||
if (typeof require === "function" && typeof exports === "object" && typeof module === "object") {
|
||||
// NodeJS
|
||||
module.exports = chaiJquery;
|
||||
} else if (typeof define === "function" && define.amd) {
|
||||
// AMD
|
||||
define(function () {
|
||||
return chaiJquery;
|
||||
});
|
||||
} else {
|
||||
// Other environment (usually <script> tag): plug in to global chai instance directly.
|
||||
chai.use(chaiJquery);
|
||||
}
|
||||
}(function (chai, utils) {
|
||||
var inspect = utils.inspect,
|
||||
flag = utils.flag;
|
||||
|
||||
jQuery.fn.inspect = function (depth) {
|
||||
var el = jQuery('<div />').append(this.clone());
|
||||
if (depth) {
|
||||
var children = el.children();
|
||||
while (depth-- > 0)
|
||||
children = children.children();
|
||||
children.html('...');
|
||||
}
|
||||
return el.html();
|
||||
};
|
||||
|
||||
var props = {attr: 'attribute', css: 'CSS property'};
|
||||
for (var prop in props) {
|
||||
(function (prop, description) {
|
||||
chai.Assertion.addMethod(prop, function (name, val) {
|
||||
var actual = flag(this, 'object')[prop](name);
|
||||
|
||||
if (!flag(this, 'negate') || undefined === val) {
|
||||
this.assert(
|
||||
undefined !== actual
|
||||
, 'expected #{this} to have a #{exp} ' + description
|
||||
, 'expected #{this} not to have a #{exp} ' + description
|
||||
, name
|
||||
);
|
||||
}
|
||||
|
||||
if (undefined !== val) {
|
||||
this.assert(
|
||||
val === actual
|
||||
, 'expected #{this} to have a ' + inspect(name) + ' ' + description + ' with the value #{exp}, but the value was #{act}'
|
||||
, 'expected #{this} not to have a ' + inspect(name) + ' ' + description + ' with the value #{act}'
|
||||
, val
|
||||
, actual
|
||||
);
|
||||
}
|
||||
|
||||
flag(this, 'object', actual);
|
||||
});
|
||||
})(prop, props[prop]);
|
||||
}
|
||||
|
||||
chai.Assertion.addMethod('data', function (name, val) {
|
||||
// Work around a chai bug (https://github.com/logicalparadox/chai/issues/16)
|
||||
if (flag(this, 'negate') && undefined !== val && undefined === flag(this, 'object').data(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var assertion = new chai.Assertion(flag(this, 'object').data());
|
||||
if (flag(this, 'negate'))
|
||||
assertion = assertion.not;
|
||||
return assertion.property(name, val);
|
||||
});
|
||||
|
||||
chai.Assertion.addMethod('class', function (className) {
|
||||
this.assert(
|
||||
flag(this, 'object').hasClass(className)
|
||||
, 'expected #{this} to have class #{exp}'
|
||||
, 'expected #{this} not to have class #{exp}'
|
||||
, className
|
||||
);
|
||||
});
|
||||
|
||||
chai.Assertion.addMethod('id', function (id) {
|
||||
this.assert(
|
||||
flag(this, 'object').attr('id') === id
|
||||
, 'expected #{this} to have id #{exp}'
|
||||
, 'expected #{this} not to have id #{exp}'
|
||||
, id
|
||||
);
|
||||
});
|
||||
|
||||
chai.Assertion.addMethod('html', function (html) {
|
||||
this.assert(
|
||||
flag(this, 'object').html() === html
|
||||
, 'expected #{this} to have HTML #{exp}'
|
||||
, 'expected #{this} not to have HTML #{exp}'
|
||||
, html
|
||||
);
|
||||
});
|
||||
|
||||
chai.Assertion.addMethod('text', function (text) {
|
||||
this.assert(
|
||||
flag(this, 'object').text() === text
|
||||
, 'expected #{this} to have text #{exp}'
|
||||
, 'expected #{this} not to have text #{exp}'
|
||||
, text
|
||||
);
|
||||
});
|
||||
|
||||
chai.Assertion.addMethod('value', function (value) {
|
||||
this.assert(
|
||||
flag(this, 'object').val() === value
|
||||
, 'expected #{this} to have value #{exp}'
|
||||
, 'expected #{this} not to have value #{exp}'
|
||||
, value
|
||||
);
|
||||
});
|
||||
|
||||
jQuery.each(['visible', 'hidden', 'selected', 'checked', 'disabled'], function (i, attr) {
|
||||
chai.Assertion.addProperty(attr, function () {
|
||||
this.assert(
|
||||
flag(this, 'object').is(':' + attr)
|
||||
, 'expected #{this} to be ' + attr
|
||||
, 'expected #{this} not to be ' + attr);
|
||||
});
|
||||
});
|
||||
|
||||
chai.Assertion.overwriteProperty('exist', function (_super) {
|
||||
return function () {
|
||||
var obj = flag(this, 'object');
|
||||
if (obj instanceof jQuery) {
|
||||
this.assert(
|
||||
obj.length > 0
|
||||
, 'expected ' + inspect(obj.selector) + ' to exist'
|
||||
, 'expected ' + inspect(obj.selector) + ' not to exist');
|
||||
} else {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
chai.Assertion.overwriteProperty('empty', function (_super) {
|
||||
return function () {
|
||||
var obj = flag(this, 'object');
|
||||
if (obj instanceof jQuery) {
|
||||
this.assert(
|
||||
obj.is(':empty')
|
||||
, 'expected #{this} to be empty'
|
||||
, 'expected #{this} not to be empty');
|
||||
} else {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
chai.Assertion.overwriteProperty('be', function (_super) {
|
||||
return function () {
|
||||
var be = function (selector) {
|
||||
var obj = flag(this, 'object');
|
||||
if (obj instanceof jQuery) {
|
||||
this.assert(
|
||||
obj.is(selector)
|
||||
, 'expected #{this} to be #{exp}'
|
||||
, 'expected #{this} not to be #{exp}'
|
||||
, selector
|
||||
);
|
||||
} else {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
be.__proto__ = this;
|
||||
return be;
|
||||
}
|
||||
});
|
||||
|
||||
chai.Assertion.overwriteMethod('match', function (_super) {
|
||||
return function (selector) {
|
||||
var obj = flag(this, 'object');
|
||||
if (obj instanceof jQuery) {
|
||||
this.assert(
|
||||
obj.is(selector)
|
||||
, 'expected #{this} to match #{exp}'
|
||||
, 'expected #{this} not to match #{exp}'
|
||||
, selector
|
||||
);
|
||||
} else {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
chai.Assertion.overwriteProperty('contain', function (_super) {
|
||||
return function () {
|
||||
_super.call(this);
|
||||
var contain = function (text) {
|
||||
var obj = flag(this, 'object');
|
||||
if (obj instanceof jQuery) {
|
||||
this.assert(
|
||||
obj.is(':contains(\'' + text + '\')')
|
||||
, 'expected #{this} to contain #{exp}'
|
||||
, 'expected #{this} not to contain #{exp}'
|
||||
, text
|
||||
);
|
||||
} else {
|
||||
Function.prototype.apply.call(_super.call(this), this, arguments);
|
||||
}
|
||||
};
|
||||
contain.__proto__ = this;
|
||||
return contain;
|
||||
}
|
||||
});
|
||||
|
||||
chai.Assertion.overwriteProperty('have', function (_super) {
|
||||
return function () {
|
||||
var obj = flag(this, 'object');
|
||||
if (obj instanceof jQuery) {
|
||||
var have = function (selector) {
|
||||
this.assert(
|
||||
// Using find() rather than has() to work around a jQuery bug:
|
||||
// http://bugs.jquery.com/ticket/11706
|
||||
obj.find(selector).length > 0
|
||||
, 'expected #{this} to have #{exp}'
|
||||
, 'expected #{this} not to have #{exp}'
|
||||
, selector
|
||||
);
|
||||
};
|
||||
have.__proto__ = this;
|
||||
return have;
|
||||
} else {
|
||||
_super.call(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
2
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/vendor/jquery-1.8.2.min.js
vendored
Normal file
2
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/vendor/jquery-1.8.2.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
203
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/vendor/mocha-1.6.0.css
vendored
Normal file
203
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/vendor/mocha-1.6.0.css
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
@charset "UTF-8";
|
||||
body {
|
||||
font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
padding: 60px 50px;
|
||||
}
|
||||
|
||||
#mocha ul, #mocha li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#mocha ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#mocha h1, #mocha h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#mocha h1 {
|
||||
margin-top: 15px;
|
||||
font-size: 1em;
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
#mocha h1 a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
#mocha h1 a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#mocha .suite .suite h1 {
|
||||
margin-top: 0;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha h2 {
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#mocha .suite {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
#mocha .test {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
#mocha .test:hover h2::after {
|
||||
position: relative;
|
||||
top: 0;
|
||||
right: -10px;
|
||||
content: '(view source)';
|
||||
font-size: 12px;
|
||||
font-family: arial;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
#mocha .test.pending:hover h2::after {
|
||||
content: '(pending)';
|
||||
font-family: arial;
|
||||
}
|
||||
|
||||
#mocha .test.pass.medium .duration {
|
||||
background: #C09853;
|
||||
}
|
||||
|
||||
#mocha .test.pass.slow .duration {
|
||||
background: #B94A48;
|
||||
}
|
||||
|
||||
#mocha .test.pass::before {
|
||||
content: '✓';
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
color: #00d6b2;
|
||||
}
|
||||
|
||||
#mocha .test.pass .duration {
|
||||
font-size: 9px;
|
||||
margin-left: 5px;
|
||||
padding: 2px 5px;
|
||||
color: white;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
||||
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
||||
box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-ms-border-radius: 5px;
|
||||
-o-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#mocha .test.pass.fast .duration {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha .test.pending {
|
||||
color: #0b97c4;
|
||||
}
|
||||
|
||||
#mocha .test.pending::before {
|
||||
content: '◦';
|
||||
color: #0b97c4;
|
||||
}
|
||||
|
||||
#mocha .test.fail {
|
||||
color: #c00;
|
||||
}
|
||||
|
||||
#mocha .test.fail pre {
|
||||
color: black;
|
||||
}
|
||||
|
||||
#mocha .test.fail::before {
|
||||
content: '✖';
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
color: #c00;
|
||||
}
|
||||
|
||||
#mocha .test pre.error {
|
||||
color: #c00;
|
||||
}
|
||||
|
||||
#mocha .test pre {
|
||||
display: inline-block;
|
||||
font: 12px/1.5 monaco, monospace;
|
||||
margin: 5px;
|
||||
padding: 15px;
|
||||
border: 1px solid #eee;
|
||||
border-bottom-color: #ddd;
|
||||
-webkit-border-radius: 3px;
|
||||
-webkit-box-shadow: 0 1px 3px #eee;
|
||||
}
|
||||
|
||||
#report.pass .test.fail {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#report.fail .test.pass {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#error {
|
||||
color: #c00;
|
||||
font-size: 1.5 em;
|
||||
font-weight: 100;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
#stats {
|
||||
position: fixed;
|
||||
top: 15px;
|
||||
right: 10px;
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
#stats .progress {
|
||||
float: right;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
#stats em {
|
||||
color: black;
|
||||
}
|
||||
|
||||
#stats a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
#stats a:hover {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
#stats li {
|
||||
display: inline-block;
|
||||
margin: 0 5px;
|
||||
list-style: none;
|
||||
padding-top: 11px;
|
||||
}
|
||||
|
||||
code .comment { color: #ddd }
|
||||
code .init { color: #2F6FAD }
|
||||
code .string { color: #5890AD }
|
||||
code .keyword { color: #8A6343 }
|
||||
code .number { color: #2F6FAD }
|
||||
4906
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/vendor/mocha-1.6.0.js
vendored
Normal file
4906
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/vendor/mocha-1.6.0.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
10
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/vendor/raphael-2.1.0.min.js
vendored
Normal file
10
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/vendor/raphael-2.1.0.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4142
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/vendor/sinon-1.5.0.js
vendored
Normal file
4142
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/vendor/sinon-1.5.0.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
95
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/vendor/sinon-chai-2.1.2.js
vendored
Normal file
95
wwwroot/BackendScript/assets/morris.js-0.4.3/spec/vendor/sinon-chai-2.1.2.js
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
(function (sinonChai) {
|
||||
"use strict";
|
||||
|
||||
// Module systems magic dance.
|
||||
|
||||
if (typeof require === "function" && typeof exports === "object" && typeof module === "object") {
|
||||
// NodeJS
|
||||
module.exports = sinonChai;
|
||||
} else if (typeof define === "function" && define.amd) {
|
||||
// AMD
|
||||
define(function () {
|
||||
return sinonChai;
|
||||
});
|
||||
} else {
|
||||
// Other environment (usually <script> tag): plug in to global chai instance directly.
|
||||
chai.use(sinonChai);
|
||||
}
|
||||
}(function sinonChai(chai, utils) {
|
||||
"use strict";
|
||||
|
||||
var slice = Array.prototype.slice;
|
||||
|
||||
function isSpy(putativeSpy) {
|
||||
return typeof putativeSpy === "function" &&
|
||||
typeof putativeSpy.getCall === "function" &&
|
||||
typeof putativeSpy.calledWithExactly === "function";
|
||||
}
|
||||
|
||||
function isCall(putativeCall) {
|
||||
return putativeCall && isSpy(putativeCall.proxy);
|
||||
}
|
||||
|
||||
function assertCanWorkWith(assertion) {
|
||||
if (!isSpy(assertion._obj) && !isCall(assertion._obj)) {
|
||||
throw new TypeError(utils.inspect(assertion._obj) + " is not a spy or a call to a spy!");
|
||||
}
|
||||
}
|
||||
|
||||
function getMessages(spy, action, nonNegatedSuffix, always, args) {
|
||||
var verbPhrase = always ? "always have " : "have ";
|
||||
nonNegatedSuffix = nonNegatedSuffix || "";
|
||||
spy = spy.proxy || spy;
|
||||
|
||||
function printfArray(array) {
|
||||
return spy.printf.apply(spy, array);
|
||||
}
|
||||
|
||||
return {
|
||||
affirmative: printfArray(["expected %n to " + verbPhrase + action + nonNegatedSuffix].concat(args)),
|
||||
negative: printfArray(["expected %n to not " + verbPhrase + action].concat(args))
|
||||
};
|
||||
}
|
||||
|
||||
function sinonProperty(name, action, nonNegatedSuffix) {
|
||||
utils.addProperty(chai.Assertion.prototype, name, function () {
|
||||
assertCanWorkWith(this);
|
||||
|
||||
var messages = getMessages(this._obj, action, nonNegatedSuffix, false);
|
||||
this.assert(this._obj[name], messages.affirmative, messages.negative);
|
||||
});
|
||||
}
|
||||
|
||||
function exceptionalSinonMethod(chaiName, sinonName, action, nonNegatedSuffix) {
|
||||
utils.addMethod(chai.Assertion.prototype, chaiName, function () {
|
||||
assertCanWorkWith(this);
|
||||
|
||||
var alwaysSinonMethod = "always" + sinonName[0].toUpperCase() + sinonName.substring(1);
|
||||
var shouldBeAlways = utils.flag(this, "always") && typeof this._obj[alwaysSinonMethod] === "function";
|
||||
var sinonMethod = shouldBeAlways ? alwaysSinonMethod : sinonName;
|
||||
|
||||
var messages = getMessages(this._obj, action, nonNegatedSuffix, shouldBeAlways, slice.call(arguments));
|
||||
this.assert(this._obj[sinonMethod].apply(this._obj, arguments), messages.affirmative, messages.negative);
|
||||
});
|
||||
}
|
||||
|
||||
function sinonMethod(name, action, nonNegatedSuffix) {
|
||||
exceptionalSinonMethod(name, name, action, nonNegatedSuffix);
|
||||
}
|
||||
|
||||
utils.addProperty(chai.Assertion.prototype, "always", function () {
|
||||
utils.flag(this, "always", true);
|
||||
});
|
||||
|
||||
sinonProperty("called", "been called", " at least once, but it was never called");
|
||||
sinonProperty("calledOnce", "been called exactly once", ", but it was called %c%C");
|
||||
sinonProperty("calledTwice", "been called exactly twice", ", but it was called %c%C");
|
||||
sinonProperty("calledThrice", "been called exactly thrice", ", but it was called %c%C");
|
||||
sinonMethod("calledBefore", "been called before %1");
|
||||
sinonMethod("calledAfter", "been called after %1");
|
||||
sinonMethod("calledOn", "been called with %1 as this", ", but it was called with %t instead");
|
||||
sinonMethod("calledWith", "been called with arguments %*", "%C");
|
||||
sinonMethod("calledWithExactly", "been called with exact arguments %*", "%C");
|
||||
sinonMethod("returned", "returned %1");
|
||||
exceptionalSinonMethod("thrown", "threw", "thrown %1");
|
||||
}));
|
||||
Reference in New Issue
Block a user