From bdd3d35223c6a650dcecfc86ed61377785603eb3 Mon Sep 17 00:00:00 2001 From: Fedor Yudanov Date: Wed, 3 Apr 2013 18:32:43 +0700 Subject: [PATCH] #50 - advanced tests (tests 5,6) --- rbejdb/src/rbbson.c | 41 +++++++++++++++++++++++-- rbejdb/src/rbejdb.c | 37 +++++++++++++++++++++++ rbejdb/test/t2.rb | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 158 insertions(+), 6 deletions(-) diff --git a/rbejdb/src/rbbson.c b/rbejdb/src/rbbson.c index 7713b8c..e0af287 100644 --- a/rbejdb/src/rbbson.c +++ b/rbejdb/src/rbbson.c @@ -62,6 +62,25 @@ int iterate_key_values_callback(VALUE key, VALUE val, VALUE bsonWrap) { switch (TYPE(val)) { case T_OBJECT: + if (0 == strcmp(rb_obj_classname(val), "EJDBBinary")) { + VALUE bdata = rb_iv_get(val, "@data"); + Check_Type(bdata, T_ARRAY); + + int length = NUM2INT(rb_funcall(bdata, rb_intern("length"), 0)); + char* buf = (char*) malloc(sizeof(char) * length); + int i; + + for (i = 0; i < length; i++) { + VALUE byte = rb_ary_entry(bdata, i); + buf[i] = (char) NUM2INT(byte); + } + + bson_append_binary(b, attrName, BSON_BIN_BINARY, buf, length); + + free(buf); + break; + } + //else same as hash :) case T_HASH: ruby_to_bson(val, &subbson, rbbson->flags); bson_append_bson(b, attrName, subbson); @@ -72,7 +91,12 @@ int iterate_key_values_callback(VALUE key, VALUE val, VALUE bsonWrap) { bson_append_finish_array(b); break; case T_STRING: - bson_append_string(b, attrName, StringValuePtr(val)); + if (0 != strcmp("_id", attrName)) { + bson_append_string(b, attrName, StringValuePtr(val)); + } else { + bson_oid_t oid = ruby_to_bson_oid(val); + bson_append_oid(b, attrName, &oid); + } break; case T_FIXNUM: bson_append_int(b, attrName, FIX2INT(val)); @@ -81,7 +105,7 @@ int iterate_key_values_callback(VALUE key, VALUE val, VALUE bsonWrap) { if (0 == strcmp(rb_obj_classname(val), "Time")) { bson_append_date(b, attrName, ruby_time_to_bson_internal(val)); } else { - rb_raise(rb_eRuntimeError, "Cannot convert ruby data object to bson"); + rb_raise(rb_eRuntimeError, "Cannot convert ruby data object to bson: %s", rb_obj_classname(val)); } break; case T_REGEXP: { @@ -200,6 +224,19 @@ VALUE bson_iterator_to_ruby(bson_iterator* it, bson_type t) { case BSON_ARRAY: val = bson_array_to_ruby(it); break; + case BSON_BINDATA: { + const char* buf = bson_iterator_bin_data(it); + int length = bson_iterator_bin_len(it); + + VALUE bdata = rb_ary_new(); + int i; + for (i = 0; i < length; i++) { + rb_ary_push(bdata, INT2NUM(buf[i])); + } + + val = rb_funcall(rb_path2class("EJDBBinary"), rb_intern("new"), 1, bdata); + } + break; case BSON_NULL: val = Qnil; break; diff --git a/rbejdb/src/rbejdb.c b/rbejdb/src/rbejdb.c index dd3ffd0..57d3e72 100644 --- a/rbejdb/src/rbejdb.c +++ b/rbejdb/src/rbejdb.c @@ -35,6 +35,7 @@ VALUE create_EJDB_query_results(TCLIST* qres); VALUE ejdbClass; VALUE ejdbResultsClass; +VALUE ejdbBinaryClass; VALUE get_hash_option(VALUE hash, const char* opt) { @@ -349,6 +350,36 @@ void EJDB_results_close(VALUE self) { } +VALUE EJDB_binary_init(VALUE self, VALUE bdata) { + Check_Type(bdata, T_ARRAY); + + int length = NUM2INT(rb_funcall(bdata, rb_intern("length"), 0)); + int i; + for (i = 0; i < length; i++) { + VALUE byte = rb_ary_entry(bdata, i); + if (NUM2INT(byte) > 255 || NUM2INT(byte) < 0) { + rb_raise(rb_eRuntimeError, "Invalid value in binary array for EJDBBinary"); + } + } + + rb_iv_set(self, "@data", rb_ary_dup(bdata)); +} + + +static VALUE EJDB_block_proxy_context(VALUE yielded_object, VALUE context, int argc, VALUE argv[]){ + VALUE block = context; + return rb_funcall(block, rb_intern("call"), 1, yielded_object); +} + +void EJDB_binary_each(VALUE self) { + VALUE bdata = rb_iv_get(self, "@data"); + Check_Type(bdata, T_ARRAY); + + VALUE block = rb_block_proc(); + rb_block_call(bdata, rb_intern("each"), 0, NULL, RUBY_METHOD_FUNC(EJDB_block_proxy_context), block); +} + + Init_rbejdb() { init_ruby_to_bson(); @@ -377,4 +408,10 @@ Init_rbejdb() { rb_include_module(ejdbResultsClass, rb_mEnumerable); rb_define_method(ejdbResultsClass, "each", RUBY_METHOD_FUNC(EJDB_results_each), 0); rb_define_method(ejdbResultsClass, "close", RUBY_METHOD_FUNC(EJDB_results_close), 0); + + + ejdbBinaryClass = rb_define_class("EJDBBinary", rb_cObject); + rb_include_module(ejdbBinaryClass, rb_mEnumerable); + rb_define_private_method(ejdbBinaryClass, "initialize", RUBY_METHOD_FUNC(EJDB_binary_init), 1); + rb_define_method(ejdbBinaryClass, "each", RUBY_METHOD_FUNC(EJDB_binary_each), 0); } \ No newline at end of file diff --git a/rbejdb/test/t2.rb b/rbejdb/test/t2.rb index 707834e..75f9592 100644 --- a/rbejdb/test/t2.rb +++ b/rbejdb/test/t2.rb @@ -40,6 +40,8 @@ class EJDBTestUnit < Test::Unit::TestCase assert_not_nil obj assert_equal(parrot2["_id"], obj["_id"]) assert_equal("Bounty", obj["name"]) + + puts "test_ejdb1_save_load has passed successfull" end @@ -86,10 +88,12 @@ class EJDBTestUnit < Test::Unit::TestCase results = $jb.find("parrots") assert_not_nil results assert_equal(2, results.to_a.length) + + puts "test_ejdb2_query1 has passed successfull" end - def test_ejdb3_test_query2 + def test_ejdb3_query2 assert_not_nil $jb assert $jb.is_open? @@ -108,11 +112,12 @@ class EJDBTestUnit < Test::Unit::TestCase assert_equal("sugar cane", rv["likes"].join(",")) end } - end + puts "test_ejdb3_query2 has passed successfull" + end - def test_ejdb4_test_query3 + def test_ejdb4_query3 assert_not_nil $jb assert $jb.is_open? @@ -132,7 +137,6 @@ class EJDBTestUnit < Test::Unit::TestCase end } - assert_equal(2, results.to_a.length) # testing force close @@ -141,6 +145,80 @@ class EJDBTestUnit < Test::Unit::TestCase assert_raise(RuntimeError) { results.to_a.length } + + puts "test_ejdb4_query3 has passed successfull" + end + + +=begin + test is written but this functionality is rather special an has low priority... + + def test_ejdb5_circular + assert_not_nil $jb + assert $jb.is_open? + + #Circular query object + cir_query = {} + cir_query["cq"] = cir_query + + err = nil + begin + $jb.find("parrots", cir_query) + rescue Exception => e + err = e + end + + assert_not_nil err + assert_equal(err.message, "Converting circular structure to JSON") + + err = nil + begin + $jb.find("parrots", [cir_query]) + rescue Exception => e + err = e + end + + assert_not_nil err + assert_equal(err.message, "Converting circular structure to JSON") + + puts "test_ejdb5_circular has passed successfull" + end +=end + + def test_ejdb6_save_load_buffer + assert_not_nil $jb + assert $jb.is_open? + + sally = { + "name" => "Sally", + "mood" => "Angry", + "secret" => EJDBBinary.new("Some binary secrect".encode("utf-8").bytes.to_a) + } + + molly = { + "name" => "Molly", + "mood" => "Very angry", + "secret" => nil + } + + sally_oid = $jb.save("birds", sally) + + assert_not_nil sally_oid + assert_not_nil sally["_id"] + + obj = $jb.load("birds", sally_oid) + + assert(obj["secret"].is_a? EJDBBinary) + assert_equal("Some binary secrect", obj["secret"].to_a.pack("U*")) + + oids = $jb.save("birds", sally, molly) + + assert_not_nil oids + assert_not_nil oids.find { |oid| + oid == sally_oid + } + + puts "test_ejdb6_save_load_buffer has passed successfull" end end -- 2.7.4