require "spec_helper" describe "Expressive" do before(:each) do @scope = TopLevel.new end describe "all_symbols" do it { Expressive.all_symbols.should =~ %w(+ - * / = set sum post >= > < <= and or if) } end describe "understands booleans" do it { Expressive.run("true").should eql true } it { Expressive.run("false").should eql false } end describe "understands numbers" do it { Expressive.run("5").should eql 5 } it { Expressive.run("5.5").should eql 5.5 } end describe "understands string literals" do it { Expressive.run('"hello world "').should eql "hello world " } it { Expressive.run('"hello world 2012"').should eql "hello world 2012" } it { Expressive.run('"hello world 2.5"').should eql "hello world 2.5" } it { Expressive.run('"hello world false"').should eql "hello world false" } end it "understands variables" do @scope["hello"] = "World" Expressive.run("hello", @scope).should eql "World" end describe "under stands arithmetic" do it { Expressive.run("(+ 4 2)").should eql 6.0 } it { Expressive.run("(- 4 2)").should eql 2.0 } it { Expressive.run("(* 4 2)").should eql 8.0 } it { Expressive.run("(/ 4 2)").should eql 2.0 } it { Expressive.run("(sum 1 2 3)").should eql 6.0 } end describe "understands comparisson" do it { Expressive.run("(= 4 2)").should eql false } it { Expressive.run("(= 4 4)").should eql true } it { Expressive.run("(> 4 2)").should eql true } it { Expressive.run("(> 2 4)").should eql false } it { Expressive.run("(< 4 2)").should eql false } it { Expressive.run("(< 2 4)").should eql true } it { Expressive.run("(>= 4 4)").should eql true } it { Expressive.run("(<= 4 4)").should eql true } end describe "understands compound statements" do it { Expressive.run("(= (+ 4 2) 6)").should eql true } it { Expressive.run("(if (and (< 3 9) (> 2 1)), true, false)").should eql true } it { Expressive.run("(if (and (< 10 9) (> 2 1)), true, false)").should eql false } end describe "understands conditional statements" do it { Expressive.run('(if (> 5 4) "greater" "not so greater")').should eql "greater" } context "it understands the need for commas (if you like that kind of thing" do it { Expressive.run('(if (< 5 4), "greater", "not so greater")').should eql "not so greater" } end context "nil values" do it { Expressive.run('(if (> nil_value 4) "greater" "not so greater")', @scope).should eql "not so greater" } it { Expressive.run('(if (> 4 nil_value) "greater" "not so greater")', @scope).should eql "greater" } it { Expressive.run('(if (> 4 nil_value) "greater" "not so greater")', @scope).should eql "greater" } it { Expressive.run('(if (<= nil_value 4) "greater" "not so greater")', @scope).should eql "greater" } it { Expressive.run('(if (>= 4 nil_value) "greater" "not so greater")', @scope).should eql "greater" } end end describe "understands logical statements" do it { Expressive.run('(and true true)').should eql true } it { Expressive.run('(and true false)').should eql false } it { Expressive.run('(or true true)').should eql true } it { Expressive.run('(or true false)').should eql true } it { Expressive.run('(or false false)').should eql false } context "nil values" do it { Expressive.run('(and true nil_value)', @scope).should eql false } it { Expressive.run('(and nil_value true)', @scope).should eql false } it { Expressive.run('(or nil_value true)', @scope).should eql true } it { Expressive.run('(or nil_value false)', @scope).should eql false } end end describe "understands web-hook statements" do context "with a valid response" do it "should post to the given uri" do request = stub_request(:post, "www.example.com") Expressive.run('(post "http://www.example.com")') assert_requested(request) end it "should post the cope parameters if given" do @scope['ohai'] = "world" request = stub_request(:post, "www.example.com").with(body: {'ohai' => 'world'}) Expressive.run('(post "http://www.example.com" ohai)', @scope) assert_requested(request) end it "should update the scope based on the response" do @scope['ohai'] = "world" request = stub_request(:post, "www.example.com").with(body: {'ohai' => 'world'}).to_return(body: {'goodbye' => 'srsly'}) Expressive.run('(post "http://www.example.com" ohai)', @scope) @scope['goodbye'].should eql 'srsly' end end context "when the response is invalid" do context "sets error custom message" do it "should add an entry in the errors element of the scope" do message = 'Something went Pete Tong' exception = RestClient::Exception.new exception.message = message stub_request(:post, 'www.example.com').to_raise(exception) Expressive.run('(post "http://www.example.com")', @scope) @scope['_errors'].should eql message end end context "bad uri" do it "should add an entry in the errors element of the scope" do stub_request(:post, "badexample.com").to_raise(RestClient::ResourceNotFound.new) Expressive.run('(post "badexample.com")', @scope) @scope['_errors'].should eql 'Resource Not Found' end end context "timeout" do it "should add an entry in the errors element of the scope" do stub_request(:post, 'www.example.com').to_timeout Expressive.run('(post "http://www.example.com")', @scope) @scope['_errors'].should eql 'Request Timeout' end end end end context "looking up an id based on a value" do it "should use the lookup method, find an id based on value" do #Expressive.run("lookup_case_state 'not_started'", @scope) #@payload[:_].should eql 1 end end context "when setting simple properties" do it "should set order_no to 1234" do Expressive.run("(set order_no 1234)", @scope).should eql 1234 @scope["order_no"].should eql 1234 end it "should reuse set properties" do Expressive.run("(set order_no 1234)(+ order_no 11)", @scope).should eql 1245.0 end it "should sum scoped arrays" do @scope["sub_totals"] = [100, 200, 300] Expressive.run("(sum sub_totals)", @scope).should eql 600.0 end end context "when setting complex properties" do context "e.g. current_state" do before(:each) { Expressive.run("(set current_state (lookup_case_state, 'not started'))", @scope) } it "should set current_state to 'started'" it "should set current_state_id to 2" end context "e.g. owned_by" do it "should set owned_by_id to 1" it "should set owned_by_type to 'CaseBlocks::User'" end end context "when setting multiple properties" do # it { # Expressive.apply_to @scope do |scope| # apply "set order_no 1234" # apply "set current_state (lookup case_state 'not started')" # apply "set owned_by (lookup_user_by_email 'ijonas@ijonas.com')" # end # @scope["order_no"].should eql "1234" # } end context "register external lookup functions" do end end