[ 
https://issues.apache.org/jira/browse/COUCHDB-731?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul Joseph Davis updated COUCHDB-731:
--------------------------------------

    Skill Level: New Contributors Level (Easy)

> Improved Query Server tests
> ---------------------------
>
>                 Key: COUCHDB-731
>                 URL: https://issues.apache.org/jira/browse/COUCHDB-731
>             Project: CouchDB
>          Issue Type: Improvement
>          Components: Test Suite
>            Reporter: Matt Lyon
>            Priority: Trivial
>
> In the process of writing a ruby version of the query server, I wrote a few 
> more tests for the javascript and erlang ones to help determine the proper 
> behavior of certain cases. The ones pertaining to handling syntax errors will 
> fail for erlang, but pass on javascript; apparently this is by design. 
> Anyway, here they are, my hope is that other people attempting an 
> implementation of the query server find them useful.
> diff --git a/test/view_server/query_server_spec.rb 
> b/test/view_server/query_server_spec.rb
> index 1de8e5b..c427e35 100644
> --- a/test/view_server/query_server_spec.rb
> +++ b/test/view_server/query_server_spec.rb
> @@ -508,34 +623,70 @@ describe "query server normal case" do
>        [{:title => "Best ever", :body => "Doc body"}, {}]).should ==
>      ["resp", {"body" => "Best ever - Doc body"}] 
>    end
> -  
> -  it "should run map funs" do
> -    @qs.reset!
> -    @qs.run(["add_fun", functions["emit-twice"][LANGUAGE]]).should == true
> +  it "should clear map functions on reset" do
>      @qs.run(["add_fun", functions["emit-once"][LANGUAGE]]).should == true
> -    rows = @qs.run(["map_doc", {:a => "b"}])
> -    rows[0][0].should == ["foo", "b"]
> -    rows[0][1].should == ["bar", "b"]
> -    rows[1][0].should == ["baz", "b"]
> +    @qs.run(["map_doc", {:a => "b"}]).size.should be > 0
> +    @qs.run(["reset"])
> +    @qs.run(["map_doc", {:a => "b"}]).size.should == 0
>    end
> +  
> +  describe "map functions" do
> +    before do
> +      @qs.reset!
> +    end
> +    it "should run map funs" do
> +      @qs.run(["add_fun", functions["emit-twice"][LANGUAGE]]).should == true
> +      @qs.run(["add_fun", functions["emit-once"][LANGUAGE]]).should == true
> +      rows = @qs.run(["map_doc", {:a => "b"}])
> +      rows[0][0].should == ["foo", "b"]
> +      rows[0][1].should == ["bar", "b"]
> +      rows[1][0].should == ["baz", "b"]
> +    end
> +
> +    it "should return error on invalid expressions" do
> +      response = @qs.run(["add_fun", 
> functions["map-invalid-expression"][LANGUAGE]])
> +      response.should be_kind_of Array
> +      response[0].should == 'error'
> +      response[1].should == 'compilation_error'
> +    end
> +    
> +    it "should return error on non-function expressions" do
> +      response = @qs.run(["add_fun", 
> functions["map-non-function-expression"][LANGUAGE]])
> +      response.should be_kind_of Array
> +      response[0].should == 'error'
> +      response[1].should == 'compilation_error'
> +    end
> +
> +    it "has access to the logger" do
> +      @qs.run(["add_fun", functions["map-logging"][LANGUAGE]])
> +      @qs.rrun(["map_doc", {:a => "b"}])
> +      response = JSON.parse @qs.rgets
> +      response.should == ["log", "{\"a\":\"b\"}"]
> +      response = @qs.jsgets
> +      response.should == [[[ "logged", "b" ]]]
> +    end
> +  end
> +
>    describe "reduce" do
>      before(:all) do
>        @fun = functions["reduce-values-length"][LANGUAGE]
> +      @fun2 = functions["reduce-values-sum"][LANGUAGE]
>        @qs.reset!
>      end
>      it "should reduce" do
>        kvs = (0...10).collect{|i|[i,i*2]}
> -      @qs.run(["reduce", [...@fun], kvs]).should == [true, [10]]
> +      @qs.run(["reduce", [...@fun, @fun2], kvs]).should == [true, [10, 90]]
>      end
>    end
>    describe "rereduce" do
>      before(:all) do
>        @fun = functions["reduce-values-sum"][LANGUAGE]
> +      @fun2 = functions["reduce-values-length"][LANGUAGE]
>        @qs.reset!
>      end
>      it "should rereduce" do
>        vs = (0...10).collect{|i|i}
> -      @qs.run(["rereduce", [...@fun], vs]).should == [true, [45]]
> +      @qs.run(["rereduce", [...@fun, @fun2], vs]).should == [true, [45, 10]]
>      end
>    end
>  
> @@ -648,6 +799,15 @@ describe "query server normal case" do
>        doc.should == {"foo" => "gnarly", "world" => "hello"}
>        resp["body"].should == "hello doc"
>      end
> +    # TODO: fails in erlang, passes in javascript. does it matter or not?
> +    it "should reject GET requests" do
> +      err, name, msg = @qs.ddoc_run(@ddoc,
> +        ["updates","basic"],
> +        [{"foo" => "gnarly"}, {"method" => "GET"}]
> +      )
> +      err.should == "error"
> +      name.should == "method_not_allowed"
> +    end
>    end
>  
>  # end
> @@ -655,99 +815,100 @@ describe "query server normal case" do
>  # __END__
>  
>    describe "ddoc list" do
> -      before(:all) do
> -        @ddoc = {
> -          "_id" => "foo",
> -          "lists" => {
> -            "simple" => functions["list-simple"][LANGUAGE],
> -            "headers" => functions["show-sends"][LANGUAGE],
> -            "rows" => functions["show-while-get-rows"][LANGUAGE],
> -            "buffer-chunks" => 
> functions["show-while-get-rows-multi-send"][LANGUAGE],
> -            "chunky" => functions["list-chunky"][LANGUAGE]
> -          }
> +    before(:all) do
> +      @ddoc = {
> +        "_id" => "foo",
> +        "lists" => {
> +          "simple" => functions["list-simple"][LANGUAGE],
> +          "headers" => functions["show-sends"][LANGUAGE],
> +          "rows" => functions["show-while-get-rows"][LANGUAGE],
> +          "buffer-chunks" => 
> functions["show-while-get-rows-multi-send"][LANGUAGE],
> +          "chunky" => functions["list-chunky"][LANGUAGE]
>          }
> -        @qs.teach_ddoc(@ddoc)
> -      end
> -      
> -      describe "example list" do
> -        it "should run normal" do
> -          @qs.ddoc_run(@ddoc,
> -            ["lists","simple"],
> -            [{"foo"=>"bar"}, {"q" => "ok"}]
> -          ).should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
> -          @qs.run(["list_row", {"key"=>"baz"}]).should ==  ["chunks", 
> ["baz"]]
> -          @qs.run(["list_row", {"key"=>"bam"}]).should ==  ["chunks", 
> ["bam"]]
> -          @qs.run(["list_row", {"key"=>"foom"}]).should == ["chunks", 
> ["foom"]]
> -          @qs.run(["list_row", {"key"=>"fooz"}]).should == ["chunks", 
> ["fooz"]]
> -          @qs.run(["list_row", {"key"=>"foox"}]).should == ["chunks", 
> ["foox"]]
> -          @qs.run(["list_end"]).should == ["end" , ["early"]]
> -        end
> +      }
> +      @qs.teach_ddoc(@ddoc)
> +    end
> +    
> +    describe "example list" do
> +      it "should run normal" do
> +        @qs.ddoc_run(@ddoc,
> +          ["lists","simple"],
> +          [{"foo"=>"bar"}, {"q" => "ok"}]
> +        ).should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
> +        @qs.run(["list_row", {"key"=>"baz"}]).should ==  ["chunks", ["baz"]]
> +        @qs.run(["list_row", {"key"=>"bam"}]).should ==  ["chunks", ["bam"]]
> +        @qs.run(["list_row", {"key"=>"foom"}]).should == ["chunks", ["foom"]]
> +        @qs.run(["list_row", {"key"=>"fooz"}]).should == ["chunks", ["fooz"]]
> +        @qs.run(["list_row", {"key"=>"foox"}]).should == ["chunks", ["foox"]]
> +        @qs.run(["list_end"]).should == ["end" , ["early"]]
>        end
> -      
> -      describe "headers" do
> -        it "should do headers proper" do
> -          @qs.ddoc_run(@ddoc, ["lists","headers"], 
> -            [{"total_rows"=>1000}, {"q" => "ok"}]
> -          ).should == ["start", ["first chunk", 'second "chunk"'], 
> -            {"headers"=>{"Content-Type"=>"text/plain"}}]
> -          @qs.rrun(["list_end"])
> -          @qs.jsgets.should == ["end", ["tail"]]
> -        end
> +    end
> +    
> +    describe "headers" do
> +      it "should do headers proper" do
> +        @qs.ddoc_run(@ddoc, ["lists","headers"], 
> +          [{"total_rows"=>1000}, {"q" => "ok"}]
> +        ).should == ["start", ["first chunk", 'second "chunk"'], 
> +          {"headers"=>{"Content-Type"=>"text/plain"}}]
> +        @qs.rrun(["list_end"])
> +        @qs.jsgets.should == ["end", ["tail"]]
>        end
> +    end
>  
> -      describe "with rows" do
> -        it "should list em" do
> -          @qs.ddoc_run(@ddoc, ["lists","rows"], 
> -            [{"foo"=>"bar"}, {"q" => "ok"}]).
> -            should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
> -          @qs.rrun(["list_row", {"key"=>"baz"}])
> -          @qs.get_chunks.should == ["baz"]
> -          @qs.rrun(["list_row", {"key"=>"bam"}])
> -          @qs.get_chunks.should == ["bam"]
> -          @qs.rrun(["list_end"])
> -          @qs.jsgets.should == ["end", ["tail"]]
> -        end
> -        it "should work with zero rows" do
> -          @qs.ddoc_run(@ddoc, ["lists","rows"],
> -            [{"foo"=>"bar"}, {"q" => "ok"}]).
> -            should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
> -          @qs.rrun(["list_end"])
> -          @qs.jsgets.should == ["end", ["tail"]]
> -        end
> -      end
> -      
> -      describe "should buffer multiple chunks sent for a single row." do
> -        it "should should buffer em" do
> -          @qs.ddoc_run(@ddoc, ["lists","buffer-chunks"],
> -            [{"foo"=>"bar"}, {"q" => "ok"}]).
> -            should == ["start", ["bacon"], {"headers"=>{}}]
> -          @qs.rrun(["list_row", {"key"=>"baz"}])
> -          @qs.get_chunks.should == ["baz", "eggs"]
> -          @qs.rrun(["list_row", {"key"=>"bam"}])
> -          @qs.get_chunks.should == ["bam", "eggs"]
> -          @qs.rrun(["list_end"])
> -          @qs.jsgets.should == ["end", ["tail"]]
> -        end
> +    describe "with rows" do
> +      it "should list em" do
> +        @qs.ddoc_run(@ddoc, ["lists","rows"], 
> +          [{"foo"=>"bar"}, {"q" => "ok"}]).
> +          should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
> +        @qs.rrun(["list_row", {"key"=>"baz"}])
> +        @qs.get_chunks.should == ["baz"]
> +        @qs.rrun(["list_row", {"key"=>"bam"}])
> +        @qs.get_chunks.should == ["bam"]
> +        @qs.rrun(["list_end"])
> +        @qs.jsgets.should == ["end", ["tail"]]
>        end
> -      it "should end after 2" do
> -        @qs.ddoc_run(@ddoc, ["lists","chunky"],
> +      it "should work with zero rows" do
> +        @qs.ddoc_run(@ddoc, ["lists","rows"],
>            [{"foo"=>"bar"}, {"q" => "ok"}]).
>            should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
> -          
> -        @qs.run(["list_row", {"key"=>"baz"}]).
> -          should ==  ["chunks", ["baz"]]
> -
> -        @qs.run(["list_row", {"key"=>"bam"}]).
> -          should ==  ["chunks", ["bam"]]
> -
> -        @qs.run(["list_row", {"key"=>"foom"}]).
> -          should == ["end", ["foom", "early tail"]]
> -        # here's where js has to discard quit properly
> -        @qs.run(["reset"]).
> -          should == true
> +        @qs.rrun(["list_end"])
> +        @qs.jsgets.should == ["end", ["tail"]]
> +      end
> +    end
> +    
> +    describe "should buffer multiple chunks sent for a single row." do
> +      it "should should buffer em" do
> +        @qs.ddoc_run(@ddoc, ["lists","buffer-chunks"],
> +          [{"foo"=>"bar"}, {"q" => "ok"}]).
> +          should == ["start", ["bacon"], {"headers"=>{}}]
> +        @qs.rrun(["list_row", {"key"=>"baz"}])
> +        @qs.get_chunks.should == ["baz", "eggs"]
> +        @qs.rrun(["list_row", {"key"=>"bam"}])
> +        @qs.get_chunks.should == ["bam", "eggs"]
> +        @qs.rrun(["list_end"])
> +        @qs.jsgets.should == ["end", ["tail"]]
>        end
>      end
> +
> +    it "should end after 2" do
> +      @qs.ddoc_run(@ddoc, ["lists","chunky"],
> +        [{"foo"=>"bar"}, {"q" => "ok"}]).
> +        should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
> +        
> +      @qs.run(["list_row", {"key"=>"baz"}]).
> +        should ==  ["chunks", ["baz"]]
> +
> +      @qs.run(["list_row", {"key"=>"bam"}]).
> +        should ==  ["chunks", ["bam"]]
> +
> +      @qs.run(["list_row", {"key"=>"foom"}]).
> +        should == ["end", ["foom", "early tail"]]
> +      # here's where js has to discard quit properly
> +      @qs.run(["reset"]).
> +        should == true
> +    end
>    end
> +end
>  
>  
>  
> @@ -762,58 +923,60 @@ def should_have_exited qs
>    end
>  end
>  
> -describe "query server that exits" do
> -  before(:each) do
> -    @qs = QueryServerRunner.run
> -    @ddoc = {
> -      "_id" => "foo",
> -      "lists" => {
> -        "capped" => functions["list-capped"][LANGUAGE],
> -        "raw" => functions["list-raw"][LANGUAGE]
> -      },
> -      "shows" => {
> -        "fatal" => functions["fatal"][LANGUAGE]
> +if LANGUAGE=='js'
> +  describe "query server that exits" do
> +    before(:each) do
> +      @qs = QueryServerRunner.run
> +      @ddoc = {
> +        "_id" => "foo",
> +        "lists" => {
> +          "capped" => functions["list-capped"][LANGUAGE],
> +          "raw" => functions["list-raw"][LANGUAGE]
> +        },
> +        "shows" => {
> +          "fatal" => functions["fatal"][LANGUAGE]
> +        }
>        }
> -    }
> -    @qs.teach_ddoc(@ddoc)
> -  end
> -  after(:each) do
> -    @qs.close
> -  end
> +      @qs.teach_ddoc(@ddoc)
> +    end
> +    after(:each) do
> +      @qs.close
> +    end
>  
> -  describe "only goes to 2 list" do
> -    it "should exit if erlang sends too many rows" do
> -      @qs.ddoc_run(@ddoc, ["lists","capped"],
> -        [{"foo"=>"bar"}, {"q" => "ok"}]).
> -        should == ["start", ["bacon"], {"headers"=>{}}]
> -      @qs.run(["list_row", {"key"=>"baz"}]).should ==  ["chunks", ["baz"]]
> -      @qs.run(["list_row", {"key"=>"foom"}]).should == ["chunks", ["foom"]]
> -      @qs.run(["list_row", {"key"=>"fooz"}]).should == ["end", ["fooz", 
> "early"]]
> -      e = @qs.run(["list_row", {"key"=>"foox"}])
> -      e[0].should == "error"
> -      e[1].should == "unknown_command"
> -      should_have_exited @qs
> +    describe "only goes to 2 list" do
> +      it "should exit if erlang sends too many rows" do
> +        @qs.ddoc_run(@ddoc, ["lists","capped"],
> +          [{"foo"=>"bar"}, {"q" => "ok"}]).
> +          should == ["start", ["bacon"], {"headers"=>{}}]
> +        @qs.run(["list_row", {"key"=>"baz"}]).should ==  ["chunks", ["baz"]]
> +        @qs.run(["list_row", {"key"=>"foom"}]).should == ["chunks", ["foom"]]
> +        @qs.run(["list_row", {"key"=>"fooz"}]).should == ["end", ["fooz", 
> "early"]]
> +        e = @qs.run(["list_row", {"key"=>"foox"}])
> +        e[0].should == "error"
> +        e[1].should == "unknown_command"
> +        should_have_exited @qs
> +      end
>      end
> -  end
>  
> -  describe "raw list" do
> -    it "should exit if it gets a non-row in the middle" do
> -      @qs.ddoc_run(@ddoc, ["lists","raw"],
> -        [{"foo"=>"bar"}, {"q" => "ok"}]).
> -        should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
> -      e = @qs.run(["reset"])
> -      e[0].should == "error"
> -      e[1].should == "list_error"
> -      should_have_exited @qs
> +    describe "raw list" do
> +      it "should exit if it gets a non-row in the middle" do
> +        @qs.ddoc_run(@ddoc, ["lists","raw"],
> +          [{"foo"=>"bar"}, {"q" => "ok"}]).
> +          should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
> +        e = @qs.run(["reset"])
> +        e[0].should == "error"
> +        e[1].should == "list_error"
> +        should_have_exited @qs
> +      end
>      end
> -  end
> -  
> -  describe "fatal error" do
> -    it "should exit" do
> -      @qs.ddoc_run(@ddoc, ["shows","fatal"],
> -        [{"foo"=>"bar"}, {"q" => "ok"}]).
> -        should == ["error", "error_key", "testing"]
> -      should_have_exited @qs
> +    
> +    describe "fatal error" do
> +      it "should exit" do
> +        @qs.ddoc_run(@ddoc, ["shows","fatal"],
> +          [{"foo"=>"bar"}, {"q" => "ok"}]).
> +          should == ["error", "error_key", "testing"]
> +        should_have_exited @qs
> +      end
>      end
>    end
>  end
> @@ -821,4 +984,4 @@ end
>  describe "thank you for using the tests" do
>    it "for more info run with QS_TRACE=true or see query_server_spec.rb file 
> header" do
>    end
> -end
> \ No newline at end of file
> +end

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to