couchdb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Matt Lyon (JIRA)" <j...@apache.org>
Subject [jira] Created: (COUCHDB-731) Improved Query Server tests
Date Mon, 12 Apr 2010 05:51:42 GMT
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.
-
If you think it was sent incorrectly contact one of the administrators: https://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Mime
View raw message