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