spec/calculator_spec.rb in dentaku-3.3.2 vs spec/calculator_spec.rb in dentaku-3.3.3

- old
+ new

@@ -72,10 +72,15 @@ expect(calculator.evaluate('AND(a,b)', a: nil, b: nil)).to be_falsy expect(calculator.evaluate('IF(a,1,0)', a: nil, b: nil)).to eq(0) expect(calculator.evaluate('NOT(a)', a: nil, b: nil)).to be_truthy expect(calculator.evaluate('OR(a,b)', a: nil, b: nil)).to be_falsy end + + it 'supports lazy evaluation of variables' do + expect(calculator.evaluate('x + 1', x: -> { 1 })).to eq(2) + expect { calculator.evaluate('2', x: -> { raise 'boom' }) }.not_to raise_error + end end describe 'evaluate!' do it 'raises exception when formula has error' do expect { calculator.evaluate!('1 + + 1') }.to raise_error(Dentaku::ParseError) @@ -103,11 +108,11 @@ expect { calculator.evaluate!('ROUNDUP(a)', a: nil) }.to raise_error(Dentaku::ArgumentError) expect { calculator.evaluate!('SUM(a,b)', a: nil, b: nil) }.to raise_error(Dentaku::ArgumentError) end it 'raises argument error if a function is called with incorrect arity' do - expect { calculator.evaluate!('IF(a,b)', a: 1, b: 1) }.to raise_error(Dentaku::ArgumentError) + expect { calculator.evaluate!('IF(a,b)', a: 1, b: 1) }.to raise_error(Dentaku::ParseError) end end it 'supports unicode characters in identifiers' do expect(calculator.evaluate("ρ * 2", ρ: 2)).to eq (4) @@ -367,21 +372,35 @@ expect(calculator.evaluate('some_boolean OR 7 > 5', some_boolean: true)).to be_truthy expect(calculator.evaluate('some_boolean OR 7 < 5', some_boolean: true)).to be_truthy expect(calculator.evaluate('some_boolean OR 7 < 5', some_boolean: false)).to be_falsey end - it 'compares Time variables' do + it 'compares time variables' do expect(calculator.evaluate('t1 < t2', t1: Time.local(2017, 1, 1).to_datetime, t2: Time.local(2017, 1, 2).to_datetime)).to be_truthy expect(calculator.evaluate('t1 < t2', t1: Time.local(2017, 1, 2).to_datetime, t2: Time.local(2017, 1, 1).to_datetime)).to be_falsy expect(calculator.evaluate('t1 > t2', t1: Time.local(2017, 1, 1).to_datetime, t2: Time.local(2017, 1, 2).to_datetime)).to be_falsy expect(calculator.evaluate('t1 > t2', t1: Time.local(2017, 1, 2).to_datetime, t2: Time.local(2017, 1, 1).to_datetime)).to be_truthy end - it 'compares Time literals with Time variables' do + it 'compares time literals with time variables' do expect(calculator.evaluate('t1 < 2017-01-02', t1: Time.local(2017, 1, 1).to_datetime)).to be_truthy expect(calculator.evaluate('t1 < 2017-01-02', t1: Time.local(2017, 1, 3).to_datetime)).to be_falsy expect(calculator.evaluate('t1 > 2017-01-02', t1: Time.local(2017, 1, 1).to_datetime)).to be_falsy expect(calculator.evaluate('t1 > 2017-01-02', t1: Time.local(2017, 1, 3).to_datetime)).to be_truthy + end + + it 'supports date arithmetic' do + expect(calculator.evaluate!('2020-01-01 + 30').to_date).to eq(Time.local(2020, 1, 31).to_date) + expect(calculator.evaluate!('2020-01-01 - 1').to_date).to eq(Time.local(2019, 12, 31).to_date) + expect(calculator.evaluate!('2020-01-01 + duration(1, day)').to_date).to eq(Time.local(2020, 1, 2).to_date) + expect(calculator.evaluate!('2020-01-01 - duration(1, day)').to_date).to eq(Time.local(2019, 12, 31).to_date) + expect(calculator.evaluate!('2020-01-01 + duration(30, days)').to_date).to eq(Time.local(2020, 1, 31).to_date) + expect(calculator.evaluate!('2020-01-01 + duration(1, month)').to_date).to eq(Time.local(2020, 2, 1).to_date) + expect(calculator.evaluate!('2020-01-01 - duration(1, month)').to_date).to eq(Time.local(2019, 12, 1).to_date) + expect(calculator.evaluate!('2020-01-01 + duration(30, months)').to_date).to eq(Time.local(2022, 7, 1).to_date) + expect(calculator.evaluate!('2020-01-01 + duration(1, year)').to_date).to eq(Time.local(2021, 1, 1).to_date) + expect(calculator.evaluate!('2020-01-01 - duration(1, year)').to_date).to eq(Time.local(2019, 1, 1).to_date) + expect(calculator.evaluate!('2020-01-01 + duration(30, years)').to_date).to eq(Time.local(2050, 1, 1).to_date) end describe 'functions' do it 'include IF' do expect(calculator.evaluate('if(foo < 8, 10, 20)', foo: 2)).to eq(10)