#50 - advanced tests (some hacks test)
authorFedor Yudanov <fedwiz@academ.org>
Mon, 8 Apr 2013 11:50:57 +0000 (18:50 +0700)
committerFedor Yudanov <fedwiz@academ.org>
Mon, 8 Apr 2013 11:50:57 +0000 (18:50 +0700)
rbejdb/src/rbbson.c
rbejdb/src/rbejdb.c
rbejdb/test/t2.rb

index b30967f..79de787 100644 (file)
@@ -114,6 +114,11 @@ int iterate_key_values_callback(VALUE key, VALUE val, VALUE bsonWrap) {
                 bson_append_oid(b, attrName, &oid);
             }
             break;
+        case T_SYMBOL: {
+                VALUE sname = rb_funcall(val, rb_intern("inspect"), 0);
+                bson_append_symbol(b, attrName, StringValuePtr(sname));
+            }
+            break;
         case T_FIXNUM:
             bson_append_int(b, attrName, FIX2INT(val));
             break;
@@ -205,8 +210,10 @@ void ruby_to_bson_internal(VALUE rbobj, bson** bsonresp, VALUE traverse, int fla
         case T_HASH:
             ruby_hash_to_bson_internal(rbobj, bsonWrap);
             break;
-        default:
-            rb_raise(rb_eRuntimeError, "Cannot convert object to bson: %d", TYPE(rbobj));
+        default: {
+            VALUE objStr = rb_funcall(rbobj, rb_intern("inspect"), 0);
+            rb_raise(rb_eRuntimeError, "Cannot convert object to bson: %s: %s", rb_obj_classname(rbobj), StringValuePtr(objStr));
+        }
     }
 
     bson_finish(rbbson->bsonval);
@@ -229,6 +236,9 @@ VALUE bson_iterator_to_ruby(bson_iterator* it, bson_type t) {
         case BSON_STRING:
             val = rb_str_new2(bson_iterator_string(it));
             break;
+        case BSON_SYMBOL:
+            val = ID2SYM(rb_intern(bson_iterator_string(it)));
+            break;
         case BSON_BOOL:
             val = bson_iterator_bool(it) ? Qtrue : Qfalse;
             break;
index 16f27f1..ed6651a 100644 (file)
@@ -56,13 +56,22 @@ VALUE get_hash_option(VALUE hash, const char* opt) {
     return !NIL_P(res) ? res : rb_hash_aref(hash, rb_str_new2(opt));
 }
 
-
 static int raise_ejdb_error(EJDB *ejdb) {
     int ecode = ejdbecode(ejdb);
     const char *emsg = ejdberrmsg(ecode);
     rb_raise(rb_eRuntimeError, "%s", emsg);
 }
 
+static int nil_or_raise_ejdb_error(EJDB *ejdb) {
+    int ecode = ejdbecode(ejdb);
+    if (ecode != TCESUCCESS && ecode != TCENOREC) {
+        raise_ejdb_error(ejdb);
+    } else {
+        return Qnil;
+    }
+}
+
+
 
 EJDB* getEJDB(VALUE self) {
     RBEJDB* rejdb;
@@ -162,7 +171,7 @@ void EJDB_ensure_collection(int argc, VALUE* argv, VALUE self) {
 
 VALUE EJDB_save(int argc, VALUE *argv, VALUE self) {
     if (argc < 1) {
-        rb_raise(rb_eRuntimeError, "Error calling EJDB.save(): need to specify collection name");
+        rb_raise(rb_eArgError, "Error calling EJDB.save(): need to specify collection name");
     }
 
     VALUE collName = argv[0];
@@ -226,36 +235,30 @@ VALUE EJDB_load(VALUE self, VALUE collName, VALUE rboid) {
 
     EJCOLL *coll = ejdbgetcoll(ejdb, StringValuePtr(collName));
     if (!coll) {
-        raise_ejdb_error(ejdb);
+        return nil_or_raise_ejdb_error(ejdb);
     }
 
     bson_oid_t oid = ruby_to_bson_oid(rboid);
-
     bson *bs = ejdbloadbson(coll, &oid);
-    if (!bs) {
-        int ecode = ejdbecode(ejdb);
-        if (ecode != TCESUCCESS && ecode != TCENOREC) {
-            raise_ejdb_error(ejdb);
-        } else {
-            return Qnil;
-        }
 
-    }
-
-    return bson_to_ruby(bs);
+    return bs ? bson_to_ruby(bs) : nil_or_raise_ejdb_error(ejdb);
 }
 
+void prepare_query_hint(VALUE res, VALUE hints, char* hint) {
+    VALUE val = get_hash_option(hints, hint);
+    if (!NIL_P(val)) {
+        rb_hash_aset(res, rb_str_concat(rb_str_new2("$"), rb_str_new2(hint)), val);
+    }
+}
 
 VALUE prepare_query_hints(VALUE hints) {
     VALUE res = rb_hash_new();
-    VALUE orderby = get_hash_option(hints, "orderby");
-    if (!NIL_P(orderby)) {
-        rb_hash_aset(res, rb_str_new2("$orderby"), orderby);
-    }
+    prepare_query_hint(res, hints, "orderby");
+    prepare_query_hint(res, hints, "max");
+    prepare_query_hint(res, hints, "skip");
     return res;
 }
 
-
 VALUE EJDB_find(int argc, VALUE* argv, VALUE self) {
     VALUE collName;
     VALUE q;
@@ -544,6 +547,11 @@ void EJDB_rollback_transaction(VALUE self, VALUE collName) {
 }
 
 
+VALUE EJDB_check_valid_oid_string(VALUE clazz, VALUE oid) {
+    return TYPE(oid) == T_STRING && ejdbisvalidoidstr(StringValuePtr(oid)) ? Qtrue : Qfalse;
+}
+
+
 void close_ejdb_results_internal(RBEJDB_RESULTS* rbres) {
     tclistdel(rbres->results);
     if (rbres->log) {
@@ -574,7 +582,7 @@ void EJDB_results_each(VALUE self) {
     Data_Get_Struct(self, RBEJDB_RESULTS, rbresults);
 
     if (!rbresults || !rbresults->results) {
-        rb_raise(rb_eRuntimeError, "Each() method called on invalid ejdb query results");
+        rb_raise(rb_eRuntimeError, "each() method called on invalid ejdb query results");
     }
 
     TCLIST* qres = rbresults->results;
@@ -683,6 +691,8 @@ Init_rbejdb() {
     rb_define_method(ejdbClass, "commit_transaction", RUBY_METHOD_FUNC(EJDB_commit_transaction), 1);
     rb_define_method(ejdbClass, "rollback_transaction", RUBY_METHOD_FUNC(EJDB_rollback_transaction), 1);
 
+    rb_define_singleton_method(ejdbClass, "check_valid_oid_string", RUBY_METHOD_FUNC(EJDB_check_valid_oid_string), 1);
+
 
     ejdbResultsClass = rb_define_class("EJDBResults", rb_cObject);
     rb_include_module(ejdbResultsClass, rb_mEnumerable);
index 7232f12..a44db85 100644 (file)
@@ -41,6 +41,9 @@ class EJDBTestUnit < Test::Unit::TestCase
     assert_equal(parrot2["_id"], obj["_id"])
     assert_equal("Bounty", obj["name"])
 
+    assert EJDB.check_valid_oid_string(parrot2["_id"])
+    assert !EJDB.check_valid_oid_string("ololo")
+
     puts __method__.inspect + " has passed successfull"
   end
 
@@ -428,7 +431,84 @@ class EJDBTestUnit < Test::Unit::TestCase
     puts __method__.inspect + " has passed successfull"
   end
 
-  def test_ejdbg_close
+
+  def test_ejdbg_max_and_skip_hints
+    assert_not_nil $jb
+    assert $jb.is_open?
+
+    results = $jb.find("parrots", {})
+    assert_not_equal(1, results.count)
+
+    results = $jb.find("parrots", {}, {:max => 1})
+    assert_equal(1, results.count)
+
+    results = $jb.find("parrots", {}, {:skip => 1})
+    assert_equal(1, results.count)
+
+    results = $jb.find("parrots", {}, {:skip => 2})
+    assert_equal(0, results.count)
+
+    puts __method__.inspect + " has passed successfull"
+  end
+
+
+  def test_ejdbh_different_hacks
+    assert_nil $jb.load("monsters", "111")
+    assert_nil $jb.load("parrots", "111")
+    assert_nil $jb.load("parrots", "")
+
+    assert_raise(ArgumentError) {
+      $jb.load
+    }
+    assert_raise(ArgumentError) {
+      $jb.load("parrots")
+    }
+    assert_raise(TypeError) {
+      $jb.load("parrots", :what_is_this?)
+    }
+    assert_raise(ArgumentError) {
+      $jb.load("parrots", "", "sldslk")
+    }
+
+    assert_raise(ArgumentError) {
+      $jb.save
+    }
+    assert_raise(TypeError) {
+      $jb.save({})
+    }
+    $jb.save("monsters")
+    assert_raise(RuntimeError) {
+      $jb.save("monsters", :monster) #Cannot convert object to bson
+    }
+
+    $jb.save("monsters", {})
+    assert_raise(RuntimeError) {
+      $jb.save("@&^3872638126//d\n", {})
+    }
+
+    oid = $jb.save("monsters", {:name => :abracadabra})
+    $jb.load("monsters", oid)
+
+    $jb.save("monsters", {:name => :abracadabra}, true)
+
+    assert_raise(RuntimeError) {
+      $jb.save("monsters", :what_is_this?)
+    }
+    assert_raise(RuntimeError) {
+      $jb.save("monsters", [{:name => :abracadabra}])
+    }
+
+    $jb.save("monsters", nil)
+    $jb.save("monsters", {:name => :abracadabra}, {:name => :chupacabra})
+    $jb.save("monsters", self)
+
+    #puts $jb.find("monsters").to_a.to_s
+    assert_equal(6, $jb.find("monsters").count)
+
+    puts __method__.inspect + " has passed successfull"
+  end
+
+  def test_ejdbi_close
     assert_not_nil $jb
     assert $jb.is_open?