81 lines
2.9 KiB
Ruby
81 lines
2.9 KiB
Ruby
require 'spec_helper'
|
|
require 'dentaku/ast/operation'
|
|
require 'dentaku/ast/logical'
|
|
require 'dentaku/ast/identifier'
|
|
require 'dentaku/ast/arithmetic'
|
|
require 'dentaku/ast/case'
|
|
|
|
require 'dentaku/token'
|
|
|
|
describe Dentaku::AST::Case do
|
|
let!(:one) { Dentaku::AST::Logical.new Dentaku::Token.new(:numeric, 1) }
|
|
let!(:two) { Dentaku::AST::Logical.new Dentaku::Token.new(:numeric, 2) }
|
|
let!(:apple) do
|
|
Dentaku::AST::Logical.new Dentaku::Token.new(:string, 'apple')
|
|
end
|
|
let!(:banana) do
|
|
Dentaku::AST::Logical.new Dentaku::Token.new(:string, 'banana')
|
|
end
|
|
let!(:identifier) do
|
|
Dentaku::AST::Identifier.new(Dentaku::Token.new(:identifier, :fruit))
|
|
end
|
|
let!(:switch) { Dentaku::AST::CaseSwitchVariable.new(identifier) }
|
|
|
|
let!(:when1) { Dentaku::AST::CaseWhen.new(apple) }
|
|
let!(:then1) { Dentaku::AST::CaseThen.new(one) }
|
|
let!(:conditional1) { Dentaku::AST::CaseConditional.new(when1, then1) }
|
|
|
|
let!(:when2) { Dentaku::AST::CaseWhen.new(banana) }
|
|
let!(:then2) { Dentaku::AST::CaseThen.new(two) }
|
|
let!(:conditional2) { Dentaku::AST::CaseConditional.new(when2, then2) }
|
|
|
|
describe '#value' do
|
|
it 'raises an exception if there is no switch variable' do
|
|
expect { described_class.new(conditional1, conditional2) }
|
|
.to raise_error('Case missing switch variable')
|
|
end
|
|
|
|
it 'raises an exception if a non-conditional is passed' do
|
|
expect { described_class.new(switch, conditional1, when2) }
|
|
.to raise_error(/is not a CaseConditional/)
|
|
end
|
|
|
|
it 'tests each conditional against the switch variable' do
|
|
node = described_class.new(switch, conditional1, conditional2)
|
|
expect(node.value(fruit: 'banana')).to eq(2)
|
|
end
|
|
|
|
it 'raises an exception if the conditional is not matched' do
|
|
node = described_class.new(switch, conditional1, conditional2)
|
|
expect { node.value(fruit: 'orange') }
|
|
.to raise_error("No block matched the switch value 'orange'")
|
|
end
|
|
|
|
it 'uses the else value if provided and conditional is not matched' do
|
|
three = Dentaku::AST::Logical.new Dentaku::Token.new(:numeric, 3)
|
|
else_statement = Dentaku::AST::CaseElse.new(three)
|
|
node = described_class.new(
|
|
switch,
|
|
conditional1,
|
|
conditional2,
|
|
else_statement)
|
|
expect(node.value(fruit: 'orange')).to eq(3)
|
|
end
|
|
end
|
|
|
|
describe '#dependencies' do
|
|
let!(:tax) do
|
|
Dentaku::AST::Identifier.new(Dentaku::Token.new(:identifier, :tax))
|
|
end
|
|
let!(:addition) { Dentaku::AST::Addition.new(two, tax) }
|
|
let!(:when2) { Dentaku::AST::CaseWhen.new(banana) }
|
|
let!(:then2) { Dentaku::AST::CaseThen.new(addition) }
|
|
let!(:conditional2) { Dentaku::AST::CaseConditional.new(when2, then2) }
|
|
|
|
it 'gathers dependencies from switch and conditionals' do
|
|
node = described_class.new(switch, conditional1, conditional2)
|
|
expect(node.dependencies).to eq([:fruit, :tax])
|
|
end
|
|
end
|
|
end
|