spec/calculator_spec.rb in dentaku-2.0.11 vs spec/calculator_spec.rb in dentaku-3.0.0
- old
+ new
@@ -1,7 +1,7 @@
require 'spec_helper'
-require 'dentaku/calculator'
+require 'dentaku'
describe Dentaku::Calculator do
let(:calculator) { described_class.new }
let(:with_memory) { described_class.new.store(apples: 3) }
@@ -30,10 +30,11 @@
expect(calculator.evaluate('15 % 8')).to eq(7)
expect(calculator.evaluate('(((695759/735000)^(1/(1981-1991)))-1)*1000').round(4)).to eq(5.5018)
expect(calculator.evaluate('0.253/0.253')).to eq(1)
expect(calculator.evaluate('0.253/d', d: 0.253)).to eq(1)
expect(calculator.evaluate('10 + x', x: 'abc')).to be_nil
+ expect(calculator.evaluate('a/b', a: '10', b: '2')).to eq(5)
expect(calculator.evaluate('t + 1*24*60*60', t: Time.local(2017, 1, 1))).to eq(Time.local(2017, 1, 2))
expect(calculator.evaluate("2 | 3 * 9")).to eq (27)
expect(calculator.evaluate("2 & 3 * 9")).to eq (2)
end
@@ -66,10 +67,17 @@
it 'stores nested hashes' do
calculator.store({a: {basket: {of: 'apples'}}, b: 2})
expect(calculator.evaluate!('a.basket.of')).to eq 'apples'
expect(calculator.evaluate!('b')).to eq 2
end
+
+ it 'stores arrays' do
+ calculator.store({a: [1, 2, 3]})
+ expect(calculator.evaluate!('a[0]')).to eq 1
+ expect(calculator.evaluate!('a[x]', x: 1)).to eq 2
+ expect(calculator.evaluate!('a[x+1]', x: 1)).to eq 3
+ end
end
describe 'dependencies' do
it "finds dependencies in a generic statement" do
expect(calculator.dependencies("bob + dole / 3")).to eq(['bob', 'dole'])
@@ -190,18 +198,24 @@
unbound = 'foo * 1.5'
expect { calculator.evaluate!(unbound) }.to raise_error(Dentaku::UnboundVariableError)
expect { calculator.evaluate!(unbound) }.to raise_error do |error|
expect(error.unbound_variables).to eq ['foo']
end
+ expect { calculator.evaluate!('a + b') }.to raise_error do |error|
+ expect(error.unbound_variables).to eq ['a', 'b']
+ end
expect(calculator.evaluate(unbound)).to be_nil
expect(calculator.evaluate(unbound) { :bar }).to eq :bar
expect(calculator.evaluate(unbound) { |e| e }).to eq unbound
end
it 'fails to evaluate incomplete statements' do
- incomplete = 'true AND'
- expect { calculator.evaluate!(incomplete) }.to raise_error(Dentaku::ParseError)
+ ['true AND', 'a a ^&'].each do |statement|
+ expect {
+ calculator.evaluate!(statement)
+ }.to raise_error(Dentaku::ParseError)
+ end
end
it 'evaluates unbound statements given a binding in memory' do
expect(calculator.evaluate('foo * 1.5', foo: 2)).to eq(3)
expect(calculator.bind(monkeys: 3).evaluate('monkeys < 7')).to be_truthy
@@ -453,11 +467,11 @@
describe 'math functions' do
Math.methods(false).each do |method|
it method do
if Math.method(method).arity == 2
- expect(calculator.evaluate("#{method}(1,2)")).to eq Math.send(method, 1, 2)
+ expect(calculator.evaluate("#{method}(x,y)", x: 1, y: '2')).to eq Math.send(method, 1, 2)
else
expect(calculator.evaluate("#{method}(1)")).to eq Math.send(method, 1)
end
end
end
@@ -513,8 +527,16 @@
describe 'string functions' do
it 'concatenates strings' do
expect(
calculator.evaluate('CONCAT(s1, s2, s3)', 's1' => 'ab', 's2' => 'cd', 's3' => 'ef')
).to eq 'abcdef'
+ end
+ end
+
+ describe 'zero-arity functions' do
+ it 'can be used in formulas' do
+ calculator.add_function(:two, :numeric, -> { 2 })
+ expect(calculator.evaluate("max(two(), 1)")).to eq 2
+ expect(calculator.evaluate("max(1, two())")).to eq 2
end
end
end