RSpec.describe AST::Index do it 'evaluates array index' do expect( AST::Index.new( AST::Array.new( [AST::Number.new(1.0), AST::Number.new(2.0), AST::Number.new(3.0)] ), AST::Number.new(2.0) ) .execute(Environment.new) ).to eq(3.0) end it 'evaluates hash index' do expect( AST::Index.new( AST::Hash.new( a: AST::Number.new(1.0), b: AST::Number.new(2.0), c: AST::Number.new(3.0) ), AST::Atom.new(:b) ) .execute(Environment.new) ).to eq(2.0) end it 'raises for out of bounds array index' do expect { AST::Index.new( AST::Array.new( [AST::Number.new(1.0), AST::Number.new(2.0), AST::Number.new(3.0)] ), AST::Number.new(3.0) ) .execute(Environment.new) }.to raise_error('Array index out of bounds') end it 'raises for non-integral key on array' do expect { AST::Index.new( AST::Array.new( [AST::Number.new(1.0), AST::Number.new(2.0), AST::Number.new(3.0)] ), AST::Number.new(1.5) ) .execute(Environment.new) }.to raise_error('Array index requires integer key') expect { AST::Index.new( AST::Array.new( [AST::Number.new(1.0), AST::Number.new(2.0), AST::Number.new(3.0)] ), AST::String.new('5') ) .execute(Environment.new) }.to raise_error('Array index requires integer key') expect { AST::Index.new( AST::Array.new( [AST::Number.new(1.0), AST::Number.new(2.0), AST::Number.new(3.0)] ), AST::Atom.new(:atom) ) .execute(Environment.new) }.to raise_error('Array index requires integer key') end it 'raises for missing hash key' do expect { AST::Index.new( AST::Hash.new( { a: AST::Number.new(1.0), b: AST::Number.new(2.0), c: AST::Number.new(3.0) } ), AST::Atom.new(:d) ) .execute(Environment.new) }.to raise_error('Key d does not exist on object') end end