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