require_relative '../dsl/applied_filter_query_spec' require_relative '../dsl/field_accessors_spec' module CloudSesame module Query module Domain describe Block do # Module Specs # ======================================= it_behaves_like DSL::AppliedFilterQuery do let(:scope) { AST::Root.new({}, {}) } subject { Block.new(self, {}) } before { subject.instance_variable_set(:@_scopes, [scope]) } end it_behaves_like 'FieldAccessors' do let(:scope) { AST::Root.new(context, {}) } subject { Block.new(self, context) } before do Block.send(:include, DSL::FieldAccessors) subject.instance_variable_set(:@_scopes, [scope]) end end # Class Specs # ======================================= class Caller def initialize @test = "hello" end def test_method return "test method!!!" end end subject { Block.new(Caller.new, {}) } [ DSL::BlockStyledOperators, DSL::ScopeAccessors, DSL::Operators, DSL::BindCaller ].each do |included_module| it "should include #{ included_module }" do expect(Block.included_modules).to include included_module end end context 'given a caller' do it 'should have access to caller\'s instance variables' do expect(subject.instance_variable_get(:@test)).to eq "hello" end it 'should have access to caller\'s methods' do expect(subject.test_method).to eq "test method!!!" end end describe '#_scopes' do it 'should be default to an empty array' do expect(subject._scopes).to eq [] end it 'should not be able to get overrided' do expect{ subject._scopes = [] }.to raise_error(NoMethodError) end end describe '#_scope' do context 'when scopes is not empty' do before { subject._scopes << 1 << 2 } it 'should return the last item from _scopes' do expect(subject._scope).to eq 2 end end context 'when scopes is empty' do it 'should return nil' do expect(subject._scope).to eq nil end end end describe '#_eval' do let(:node) { AST::And.new({}, {}) } let(:scope) { AST::And.new({}, {}) } context 'when block is not given' do it 'should raise an error ' do expect{ subject._eval(node, scope) }.to raise_error(ArgumentError) end end context 'when a block is given' do subject { Block.new(self, {}) } it 'should use itself to evalute the block' do subject._eval(node, scope) { expect(self).to eq subject } end it 'should change the _scope in the block to the node passed in' do subject._eval(node, scope) { expect(_scope).to eq node } end it 'should set the _scope back to previous scope after _eval' do subject._scopes << :first_scope subject._eval(node, scope) {} expect(subject._scope).to eq :first_scope end context 'when _scope is not a root node' do it 'should return the node it self' do expect(subject._eval(node, scope) {}).to eq node end end context 'when _scope is a root node' do it 'should return the _return' do scope = AST::Root.new({}, {}) expect(subject._eval(node, scope, :return_object) { }).to eq :return_object end end end end end end end end