[macruby-changes] [1495] MacRuby/branches/experimental
source_changes at macosforge.org
source_changes at macosforge.org
Mon Apr 27 19:23:46 PDT 2009
Revision: 1495
http://trac.macosforge.org/projects/ruby/changeset/1495
Author: lsansonetti at apple.com
Date: 2009-04-27 19:23:44 -0700 (Mon, 27 Apr 2009)
Log Message:
-----------
implemented BridgeSupport constants, some work on Pointer, extracted the objc specs of method_spec.rb into method_objc_spec.rb, started working on pointer_spec.rb
Modified Paths:
--------------
MacRuby/branches/experimental/objc.m
MacRuby/branches/experimental/roxor.cpp
MacRuby/branches/experimental/spec/macruby/method_spec.rb
Added Paths:
-----------
MacRuby/branches/experimental/spec/macruby/objc_method_spec.rb
MacRuby/branches/experimental/spec/macruby/pointer_spec.rb
Modified: MacRuby/branches/experimental/objc.m
===================================================================
--- MacRuby/branches/experimental/objc.m 2009-04-27 02:04:56 UTC (rev 1494)
+++ MacRuby/branches/experimental/objc.m 2009-04-28 02:23:44 UTC (rev 1495)
@@ -75,7 +75,7 @@
static struct st_table *bs_inf_prot_imethods;
static struct st_table *bs_cftypes;
-VALUE rb_cPointer;
+static VALUE rb_cPointer;
struct RPointer
{
@@ -517,6 +517,7 @@
static void rb_objc_rval_to_ocval(VALUE, const char *, void **);
+#if 0
static VALUE
rb_pointer_new_with_type(VALUE recv, SEL sel, VALUE type)
{
@@ -572,6 +573,7 @@
return ret;
}
+#endif
static bool
rb_objc_rval_copy_boxed_data(VALUE rval, bs_element_boxed_t *bs_boxed, void *ocval)
@@ -3264,11 +3266,13 @@
rb_install_boxed_primitives();
#endif
+#if 0
rb_cPointer = rb_define_class("Pointer", rb_cObject);
rb_undef_alloc_func(rb_cPointer);
rb_objc_define_method(*(VALUE *)rb_cPointer, "new_with_type", rb_pointer_new_with_type, 1);
rb_objc_define_method(rb_cPointer, "assign", rb_pointer_assign, 1);
rb_objc_define_method(rb_cPointer, "[]", rb_pointer_aref, 1);
+#endif
rb_ivar_type = rb_intern("@__objc_type__");
Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp 2009-04-27 02:04:56 UTC (rev 1494)
+++ MacRuby/branches/experimental/roxor.cpp 2009-04-28 02:23:44 UTC (rev 1495)
@@ -203,6 +203,8 @@
Function *compile_bs_struct_writer(rb_vm_bs_boxed_t *bs_boxed,
int field);
Function *compile_ffi_function(void *stub, void *imp, int argc);
+ Function *compile_to_rval_convertor(const char *type);
+ Function *compile_to_ocval_convertor(const char *type);
private:
const char *fname;
@@ -477,6 +479,8 @@
std::map<Class, std::map<ID, int> *> ivar_slots;
std::map<SEL, GlobalVariable *> redefined_ops_gvars;
std::map<Class, struct rb_vm_outer *> outers;
+ std::map<std::string, void *> c_stubs, objc_stubs,
+ to_rval_convertors, to_ocval_convertors;
public:
static RoxorVM *current;
@@ -502,8 +506,6 @@
std::map<VALUE, rb_vm_catch_t *> catch_jmp_bufs;
std::vector<jmp_buf *> return_from_block_jmp_bufs;
- std::map<std::string, void *> c_stubs, objc_stubs;
-
bs_parser_t *bs_parser;
std::map<std::string, rb_vm_bs_boxed_t *> bs_boxed;
std::map<std::string, bs_element_function_t *> bs_funcs;
@@ -516,6 +518,16 @@
rb_vm_bs_boxed_t *find_bs_struct(std::string type);
rb_vm_bs_boxed_t *find_bs_opaque(std::string type);
+ void *gen_stub(std::string types, int argc, bool is_objc);
+ void *gen_to_rval_convertor(std::string type);
+ void *gen_to_ocval_convertor(std::string type);
+
+ void insert_stub(const char *types, void *stub, bool is_objc) {
+ std::map<std::string, void *> &m =
+ is_objc ? objc_stubs : c_stubs;
+ m.insert(std::make_pair(types, stub));
+ }
+
#if ROXOR_ULTRA_LAZY_JIT
std::map<SEL, std::map<Class, rb_vm_method_source_t *> *>
method_sources;
@@ -7083,26 +7095,100 @@
return rb_vm_call(obj, selMethodMissing, argc + 1, new_argv, false);
}
-static void *
-vm_gen_stub(std::string types, int argc, bool is_objc)
+inline void *
+RoxorVM::gen_stub(std::string types, int argc, bool is_objc)
{
- std::map<std::string, void *> &stubs =
- is_objc ? GET_VM()->objc_stubs : GET_VM()->c_stubs;
+ std::map<std::string, void *> &stubs = is_objc ? objc_stubs : c_stubs;
std::map<std::string, void *>::iterator iter = stubs.find(types);
if (iter != stubs.end()) {
return iter->second;
}
- //printf("generating %s stub %s argc %d\n", is_objc ? "objc" : "c", types, argc);
-
Function *f = RoxorCompiler::shared->compile_stub(types.c_str(), argc,
is_objc);
- void *stub = (void *)GET_VM()->compile(f);
+ void *stub = (void *)compile(f);
stubs.insert(std::make_pair(types, stub));
return stub;
}
+Function *
+RoxorCompiler::compile_to_rval_convertor(const char *type)
+{
+ // VALUE foo(void *ocval);
+ Function *f = cast<Function>(module->getOrInsertFunction("",
+ Type::VoidTy, PtrTy, NULL));
+ Function::arg_iterator arg = f->arg_begin();
+ Value *ocval = arg++;
+
+ bb = BasicBlock::Create("EntryBlock", f);
+
+ const Type *llvm_type = convert_type(type);
+ ocval = new BitCastInst(ocval, PointerType::getUnqual(llvm_type), "", bb);
+ ocval = new LoadInst(ocval, "", bb);
+
+ Value *rval = compile_conversion_to_ruby(type, llvm_type, ocval);
+
+ ReturnInst::Create(rval, bb);
+
+ return f;
+}
+
+inline void *
+RoxorVM::gen_to_rval_convertor(std::string type)
+{
+ std::map<std::string, void *>::iterator iter =
+ to_rval_convertors.find(type);
+ if (iter != to_rval_convertors.end()) {
+ return iter->second;
+ }
+
+ Function *f = RoxorCompiler::shared->compile_to_rval_convertor(
+ type.c_str());
+ void *convertor = (void *)compile(f);
+ to_rval_convertors.insert(std::make_pair(type, convertor));
+
+ return convertor;
+}
+
+Function *
+RoxorCompiler::compile_to_ocval_convertor(const char *type)
+{
+ // void foo(VALUE rval, void **ocval);
+ Function *f = cast<Function>(module->getOrInsertFunction("",
+ Type::VoidTy, RubyObjTy, PtrTy, NULL));
+ Function::arg_iterator arg = f->arg_begin();
+ Value *rval = arg++;
+ Value *ocval = arg++;
+
+ bb = BasicBlock::Create("EntryBlock", f);
+
+ const Type *llvm_type = convert_type(type);
+ ocval = new BitCastInst(ocval, PointerType::getUnqual(llvm_type), "", bb);
+ compile_conversion_to_c(type, rval, ocval);
+
+ ReturnInst::Create(bb);
+
+ return f;
+}
+
+inline void *
+RoxorVM::gen_to_ocval_convertor(std::string type)
+{
+ std::map<std::string, void *>::iterator iter =
+ to_ocval_convertors.find(type);
+ if (iter != to_ocval_convertors.end()) {
+ return iter->second;
+ }
+
+ Function *f = RoxorCompiler::shared->compile_to_ocval_convertor(
+ type.c_str());
+ void *convertor = (void *)compile(f);
+ to_ocval_convertors.insert(std::make_pair(type, convertor));
+
+ return convertor;
+}
+
static inline void
vm_gen_bs_func_types(bs_element_function_t *bs_func, std::string &types)
{
@@ -7196,8 +7282,8 @@
sel_getName(sel));
abort();
}
- ocache.stub = (rb_vm_objc_stub_t *)vm_gen_stub(types, argc,
- true);
+ ocache.stub = (rb_vm_objc_stub_t *)GET_VM()->gen_stub(types,
+ argc, true);
}
}
else {
@@ -7235,8 +7321,8 @@
fcache.bs_function = bs_func;
fcache.imp = (IMP)dlsym(RTLD_DEFAULT, bs_func->name);
assert(fcache.imp != NULL);
- fcache.stub = (rb_vm_c_stub_t *)vm_gen_stub(types, argc,
- false);
+ fcache.stub = (rb_vm_c_stub_t *)GET_VM()->gen_stub(types,
+ argc, false);
}
else {
// Still nothing, then let's call #method_missing.
@@ -8568,9 +8654,8 @@
bs_const->name);
}
- // TODO
- //rb_objc_ocval_to_rval(sym, bs_const->type, &v);
- v = INT2FIX(42);
+ void *convertor = GET_VM()->gen_to_rval_convertor(bs_const->type);
+ v = ((VALUE (*)(void *))convertor)(sym);
CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(rb_cObject);
assert(iv_dict != NULL);
@@ -8580,6 +8665,8 @@
return v;
}
+VALUE rb_cBoxed;
+
extern "C"
void
rb_vm_check_arity(int given, int requested)
@@ -8983,8 +9070,61 @@
return bs_boxed->bs_type == BS_ELEMENT_OPAQUE ? Qtrue : Qfalse;
}
-VALUE rb_cBoxed;
+VALUE rb_cPointer;
+typedef struct {
+ VALUE type;
+ VALUE (*convert_to_rval)(void *);
+ void (*convert_to_ocval)(VALUE rval, void **);
+ void *val;
+} rb_vm_pointer_t;
+
+static VALUE
+rb_pointer_new(VALUE rcv, SEL sel, VALUE type)
+{
+ StringValuePtr(type);
+
+ rb_vm_pointer_t *ptr = (rb_vm_pointer_t *)xmalloc(sizeof(rb_vm_pointer_t));
+ GC_WB(&ptr->type, type);
+
+ const char *type_str = RSTRING_PTR(type);
+ ptr->convert_to_rval =
+ (VALUE (*)(void *))GET_VM()->gen_to_rval_convertor(type_str);
+ ptr->convert_to_ocval =
+ (void (*)(VALUE, void **))GET_VM()->gen_to_ocval_convertor(type_str);
+ ptr->val = NULL; // TODO
+
+ return Data_Wrap_Struct(rb_cPointer, NULL, NULL, ptr);
+}
+
+static VALUE
+rb_pointer_aref(VALUE rcv, SEL sel, VALUE idx)
+{
+ return Qnil;
+}
+
+static VALUE
+rb_pointer_asef(VALUE rcv, SEL sel, VALUE idx, VALUE val)
+{
+ return Qnil;
+}
+
+static VALUE
+rb_pointer_assign(VALUE rcv, SEL sel, VALUE val)
+{
+ return rb_pointer_asef(rcv, 0, FIX2INT(0), val);
+}
+
+static VALUE
+rb_pointer_type(VALUE rcv, SEL sel)
+{
+ rb_vm_pointer_t *ptr;
+
+ Data_Get_Struct(rcv, rb_vm_pointer_t, ptr);
+
+ return ptr->type;
+}
+
extern "C"
void
Init_BridgeSupport(void)
@@ -8996,6 +9136,20 @@
(void *)rb_boxed_is_opaque, 0);
boxed_ivar_type = rb_intern("__octype__");
+ rb_cPointer = rb_define_class("Pointer", rb_cObject);
+ rb_objc_define_method(*(VALUE *)rb_cPointer, "new",
+ (void *)rb_pointer_new, 1);
+ rb_objc_define_method(*(VALUE *)rb_cPointer, "new_with_type",
+ (void *)rb_pointer_new, 1);
+ rb_objc_define_method(rb_cPointer, "[]",
+ (void *)rb_pointer_aref, 1);
+ rb_objc_define_method(rb_cPointer, "[]=",
+ (void *)rb_pointer_asef, 2);
+ rb_objc_define_method(rb_cPointer, "assign",
+ (void *)rb_pointer_assign, 1);
+ rb_objc_define_method(rb_cPointer, "type",
+ (void *)rb_pointer_type, 0);
+
bs_const_magic_cookie = rb_str_new2("bs_const_magic_cookie");
rb_objc_retain((void *)bs_const_magic_cookie);
}
@@ -9475,7 +9629,8 @@
types.append(convert_ffi_type(RARRAY_AT(args, i)));
}
- rb_vm_c_stub_t *stub = (rb_vm_c_stub_t *)vm_gen_stub(types, argc, false);
+ rb_vm_c_stub_t *stub = (rb_vm_c_stub_t *)GET_VM()->gen_stub(types, argc,
+ false);
Function *f = RoxorCompiler::shared->compile_ffi_function((void *)stub,
sym, argc);
IMP imp = GET_VM()->compile(f);
@@ -9507,8 +9662,8 @@
static void
setup_builtin_stubs(void)
{
- GET_VM()->objc_stubs.insert(std::make_pair("@@:", (void *)builtin_ostub1));
- GET_VM()->objc_stubs.insert(std::make_pair("#@:", (void *)builtin_ostub1));
+ GET_VM()->insert_stub("@@:", (void *)builtin_ostub1, true);
+ GET_VM()->insert_stub("#@:", (void *)builtin_ostub1, true);
}
#if ROXOR_ULTRA_LAZY_JIT
Modified: MacRuby/branches/experimental/spec/macruby/method_spec.rb
===================================================================
--- MacRuby/branches/experimental/spec/macruby/method_spec.rb 2009-04-27 02:04:56 UTC (rev 1494)
+++ MacRuby/branches/experimental/spec/macruby/method_spec.rb 2009-04-28 02:23:44 UTC (rev 1495)
@@ -82,375 +82,6 @@
def @o.isFoo; end
@o.should_not have_method(:'foo?')
end
-end
-framework 'Foundation'
-
-fixture_source = File.dirname(__FILE__) + '/fixtures/method.m'
-fixture_ext = '/tmp/method.bundle'
-if !File.exist?(fixture_ext) or File.mtime(fixture_source) > File.mtime(fixture_ext)
-=begin
- # #system is currently broken
- unless system("/usr/bin/gcc #{fixture_source} -o #{fixture_ext} -g -framework Foundation -dynamiclib -fobjc-gc -arch i386 -arch x86_64 -arch ppc")
- $stderr.puts "cannot compile fixture source file `#{fixture_source}' - aborting"
- exit 1
- end
-=end
- `/usr/bin/gcc #{fixture_source} -o #{fixture_ext} -g -framework Foundation -dynamiclib -fobjc-gc -arch i386 -arch x86_64 -arch ppc`
+ # TODO add overloading specs
end
-require '/tmp/method'
-load_bridge_support_file File.dirname(__FILE__) + '/fixtures/method.bridgesupport'
-
-describe "A pure Objective-C method" do
- before :each do
- @o = TestMethod.new
- end
-
- it "can be called with #foo= if it matches the #setFoo pattern" do
- o = []
-
- # TODO Stopped here: This should be sufficient, but doesn't work.
- # o.should have_method(:'setArray', true)
- # o.should have_method(:'array=', true)
-
- o.respond_to?(:'setArray').should == true
- o.respond_to?(:'array=').should == true
- o.array = [1, 2, 3]
- o.should == [1, 2, 3]
- end
-
- it "can be called with #foo? if it matches the #isFoo pattern" do
- o = NSBundle.mainBundle
- o.respond_to?(:'isLoaded').should == true
- o.respond_to?(:'loaded?').should == true
- o.loaded?.should == true
- end
-
- it "is only exposed in #methods if the second argument is true" do
- o = Object.new
- o.methods.include?(:'performSelector').should == false
- o.methods(true).include?(:'performSelector').should == false
- o.methods(false).include?(:'performSelector').should == false
- o.methods(true, true).include?(:'performSelector').should == true
- o.methods(false, true).include?(:'performSelector').should == true
- end
-
- it "can be called on an immediate object" do
- 123.self.should == 123
- true.self.should == true
- false.self.should == false
- nil.self.should == nil
- end
-
- it "returning void returns nil in Ruby" do
- @o.methodReturningVoid.should == nil
- end
-
- it "returning nil returns nil in Ruby" do
- @o.methodReturningNil.should == nil
- end
-
- it "returning self returns the same receiver object" do
- @o.methodReturningSelf.should == @o
- @o.methodReturningSelf.object_id == @o.object_id
- end
-
- it "returning kCFBooleanTrue returns true in Ruby" do
- @o.methodReturningCFTrue.should == true
- @o.methodReturningCFTrue.class.should == TrueClass
- end
-
- it "returning kCFBooleanFalse returns false in Ruby" do
- @o.methodReturningCFFalse.should == false
- @o.methodReturningCFFalse.class.should == FalseClass
- end
-
- it "returning kCFNull returns nil in Ruby" do
- @o.methodReturningCFNull.should == nil
- @o.methodReturningCFNull.class.should == NilClass
- end
-
- it "returning YES returns true in Ruby" do
- @o.methodReturningYES.should == true
- end
-
- it "returning NO returns true in Ruby" do
- @o.methodReturningNO.should == false
- end
-
- it "returning 'char' or 'unsigned char' returns a Fixnum in Ruby" do
- @o.methodReturningChar.should == 42
- @o.methodReturningChar2.should == -42
- @o.methodReturningUnsignedChar.should == 42
- end
-
- it "returning 'short' or 'unsigned short' returns a Fixnum in Ruby" do
- @o.methodReturningShort.should == 42
- @o.methodReturningShort2.should == -42
- @o.methodReturningUnsignedShort.should == 42
- end
-
- it "returning 'int' or 'unsigned int' returns a Fixnum in Ruby" do
- @o.methodReturningInt.should == 42
- @o.methodReturningInt2.should == -42
- @o.methodReturningUnsignedInt.should == 42
- end
-
- it "returning 'long' or 'unsigned long' returns a Fixnum if possible in Ruby" do
- @o.methodReturningLong.should == 42
- @o.methodReturningLong2.should == -42
- @o.methodReturningUnsignedLong.should == 42
- end
-
- it "returning 'long' or 'unsigned long' returns a Bignum if it cannot fix in a Fixnum in Ruby" do
- @o.methodReturningLong3.should ==
- (RUBY_ARCH == 'x86_64' ? 4611686018427387904 : 1073741824)
- @o.methodReturningLong3.class.should == Bignum
- @o.methodReturningLong4.should ==
- (RUBY_ARCH == 'x86_64' ? -4611686018427387905 : -1073741825)
- @o.methodReturningLong4.class.should == Bignum
- @o.methodReturningUnsignedLong2.should ==
- (RUBY_ARCH == 'x86_64' ? 4611686018427387904 : 1073741824)
- @o.methodReturningUnsignedLong2.class.should == Bignum
- end
-
- it "returning 'float' returns a Float in Ruby" do
- @o.methodReturningFloat.should be_close(3.1415, 0.0001)
- @o.methodReturningFloat.class.should == Float
- end
-
- it "returning 'double' returns a Float in Ruby" do
- @o.methodReturningDouble.should be_close(3.1415, 0.0001)
- @o.methodReturningDouble.class.should == Float
- end
-
- it "returning 'SEL' returns a Symbol or nil in Ruby" do
- @o.methodReturningSEL.class.should == Symbol
- @o.methodReturningSEL.should == :'foo:with:with:'
- @o.methodReturningSEL2.class.should == NilClass
- @o.methodReturningSEL2.should == nil
- end
-
- it "returning 'char *' returns a String or nil in Ruby" do
- @o.methodReturningCharPtr.class.should == String
- @o.methodReturningCharPtr.should == 'foo'
- @o.methodReturningCharPtr2.class.should == NilClass
- @o.methodReturningCharPtr2.should == nil
- end
-
- it "returning 'NSPoint' returns an NSPoint boxed object in Ruby" do
- b = @o.methodReturningNSPoint
- b.class.should == NSPoint
- b.x.class.should == Float
- b.x.should == 1.0
- b.y.class.should == Float
- b.y.should == 2.0
- end
-
- it "returning 'NSSize' returns an NSSize boxed object in Ruby" do
- b = @o.methodReturningNSSize
- b.class.should == NSSize
- b.width.class.should == Float
- b.width.should == 3.0
- b.height.class.should == Float
- b.height.should == 4.0
- end
-
- it "returning 'NSRect' returns an NSRect boxed object in Ruby" do
- b = @o.methodReturningNSRect
- b.class.should == NSRect
- b.origin.class.should == NSPoint
- b.origin.x.should == 1.0
- b.origin.y.should == 2.0
- b.size.class.should == NSSize
- b.size.width.should == 3.0
- b.size.height.should == 4.0
- end
-
- it "returning 'NSRange' returns an NSRange boxed object in Ruby" do
- b = @o.methodReturningNSRange
- b.class.should == NSRange
- b.location.class.should == Fixnum
- b.location.should == 0
- b.length.class.should == Fixnum
- b.length.should == 42
- end
-
- it "accepting the receiver as 'id' should receive the exact same object" do
- @o.methodAcceptingSelf(@o).should == 1
- end
-
- it "accepting the receiver's class as 'id' should receive the exact same object" do
- @o.methodAcceptingSelfClass(@o.class).should == 1
- end
-
- it "accepting 'nil' as 'id' should receive Objective-C's nil" do
- @o.methodAcceptingNil(nil).should == 1
- end
-
- it "accepting 'true' as 'id; should receive CF's kCFBooleanTrue" do
- @o.methodAcceptingTrue(true).should == 1
- end
-
- it "accepting 'false' as 'id' should receive CF's kCFBooleanFalse" do
- @o.methodAcceptingFalse(false).should == 1
- end
-
- it "accepting a Fixnum as 'id' should receive a Fixnum boxed object" do
- @o.methodAcceptingFixnum(42).should == 1
- end
-
- it "accepting nil or false as 'BOOL' should receive NO, any other object should receive YES" do
- @o.methodAcceptingFalseBOOL(nil).should == 1
- @o.methodAcceptingFalseBOOL(false).should == 1
-
- @o.methodAcceptingTrueBOOL(true).should == 1
- @o.methodAcceptingTrueBOOL(0).should == 1
- @o.methodAcceptingTrueBOOL(123).should == 1
- @o.methodAcceptingTrueBOOL('foo').should == 1
- @o.methodAcceptingTrueBOOL(Object.new).should == 1
- end
-
- it "accepting a Fixnum-compatible object as 'char', 'unsigned char', 'short', 'unsigned short', 'int', 'unsigned int', 'long', 'unsigned long' should receive the converted data, or raise an exception" do
- @o.methodAcceptingChar(42).should == 1
- @o.methodAcceptingUnsignedChar(42).should == 1
- @o.methodAcceptingShort(42).should == 1
- @o.methodAcceptingUnsignedShort(42).should == 1
- @o.methodAcceptingInt(42).should == 1
- @o.methodAcceptingUnsignedInt(42).should == 1
- @o.methodAcceptingLong(42).should == 1
- @o.methodAcceptingUnsignedLong(42).should == 1
-
- @o.methodAcceptingChar(42.0).should == 1
- @o.methodAcceptingUnsignedChar(42.0).should == 1
- @o.methodAcceptingShort(42.0).should == 1
- @o.methodAcceptingUnsignedShort(42.0).should == 1
- @o.methodAcceptingInt(42.0).should == 1
- @o.methodAcceptingUnsignedInt(42.0).should == 1
- @o.methodAcceptingLong(42.0).should == 1
- @o.methodAcceptingUnsignedLong(42.0).should == 1
-
- o2 = Object.new
- def o2.to_i; 42; end
-
- @o.methodAcceptingChar(o2).should == 1
- @o.methodAcceptingUnsignedChar(o2).should == 1
- @o.methodAcceptingShort(o2).should == 1
- @o.methodAcceptingUnsignedShort(o2).should == 1
- @o.methodAcceptingInt(o2).should == 1
- @o.methodAcceptingUnsignedInt(o2).should == 1
- @o.methodAcceptingLong(o2).should == 1
- @o.methodAcceptingUnsignedLong(o2).should == 1
-
- lambda { @o.methodAcceptingChar(nil) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingUnsignedChar(nil) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingShort(nil) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingUnsignedShort(nil) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingInt(nil) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingUnsignedInt(nil) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingLong(nil) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingUnsignedLong(nil) }.should raise_error(TypeError)
-
- lambda { @o.methodAcceptingChar(Object.new) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingUnsignedChar(Object.new) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingShort(Object.new) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingUnsignedShort(Object.new) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingInt(Object.new) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingUnsignedInt(Object.new) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingLong(Object.new) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingUnsignedLong(Object.new) }.should raise_error(TypeError)
- end
-
- it "accepting a one-character string as 'char' or 'unsigned char' should receive the first character" do
- @o.methodAcceptingChar('*').should == 1
- @o.methodAcceptingUnsignedChar('*').should == 1
- end
-
- it "accepting a String, Symbol or nil as 'SEL' should receive the appropriate selector" do
- @o.methodAcceptingSEL(:'foo:with:with:').should == 1
- @o.methodAcceptingSEL('foo:with:with:').should == 1
- @o.methodAcceptingSEL2(nil).should == 1
-
- lambda { @o.methodAcceptingSEL(123) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingSEL(Object.new) }.should raise_error(TypeError)
- end
-
- it "accepting a Float-compatible object as 'float' or 'double' should receive the appropriate data" do
- @o.methodAcceptingFloat(3.1415).should == 1
- @o.methodAcceptingDouble(3.1415).should == 1
-
- o2 = Object.new
- def o2.to_f; 3.1415; end
-
- @o.methodAcceptingFloat(o2).should == 1
- @o.methodAcceptingDouble(o2).should == 1
-
- lambda { @o.methodAcceptingFloat(nil) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingDouble(nil) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingFloat(Object.new) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingDouble(Object.new) }.should raise_error(TypeError)
- end
-
- it "accepting a String-compatible object as 'char *' should receive the appropriate data" do
- @o.methodAcceptingCharPtr('foo').should == 1
-
- o2 = Object.new
- def o2.to_str; 'foo' end
-
- @o.methodAcceptingCharPtr(o2).should == 1
-
- lambda { @o.methodAcceptingCharPtr(123) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingCharPtr([]) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingCharPtr(Object.new) }.should raise_error(TypeError)
-
- @o.methodAcceptingCharPtr2(nil).should == 1
- end
-
- it "accepting an NSPoint, NSSize, NSRange or NSRect object as 'NSPoint', 'NSSize', 'NSRange' or 'NSRect' should receive the C structure" do
- p = @o.methodReturningNSPoint
- @o.methodAcceptingNSPoint(p).should == 1
- p = @o.methodReturningNSSize
- @o.methodAcceptingNSSize(p).should == 1
- p = @o.methodReturningNSRect
- @o.methodAcceptingNSRect(p).should == 1
- p = @o.methodReturningNSRange
- @o.methodAcceptingNSRange(p).should == 1
-
- lambda { @o.methodAcceptingNSPoint(nil) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingNSPoint(123) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingNSPoint(Object.new) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingNSPoint(@o.methodReturningNSSize) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingNSSize(nil) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingNSSize(123) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingNSSize(Object.new) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingNSSize(@o.methodReturningNSPoint) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingNSRect(nil) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingNSRect(123) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingNSRect(Object.new) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingNSRect(@o.methodReturningNSPoint) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingNSRange(nil) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingNSRange(123) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingNSRange(Object.new) }.should raise_error(TypeError)
- lambda { @o.methodAcceptingNSRange(@o.methodReturningNSPoint) }.should raise_error(TypeError)
- end
-
- it "accepting an Array of valid objects as a structure type should receive the C structure" do
- @o.methodAcceptingNSPoint([1, 2]).should == 1
- @o.methodAcceptingNSSize([3, 4]).should == 1
- @o.methodAcceptingNSRect([[1, 2], [3, 4]]).should == 1
- @o.methodAcceptingNSRect([1, 2, 3, 4]).should == 1
- @o.methodAcceptingNSRange([0, 42]).should == 1
-
- lambda { @o.methodAcceptingNSPoint([1]) }.should raise_error(ArgumentError)
- lambda { @o.methodAcceptingNSPoint([1, 2, 3]) }.should raise_error(ArgumentError)
- lambda { @o.methodAcceptingNSRect([1, 2, 3]) }.should raise_error(ArgumentError)
- lambda { @o.methodAcceptingNSRect([1, 2, 3, 4, 5]) }.should raise_error(ArgumentError)
- lambda { @o.methodAcceptingNSRect([[1, 2], [3]]) }.should raise_error(ArgumentError)
- lambda { @o.methodAcceptingNSRect([[1, 2], [3, 4, 5]]) }.should raise_error(ArgumentError)
- end
-
- it "accepting various C types should receive these types as expected" do
- @o.methodAcceptingInt(42, float:42, double:42, short:42, NSPoint:[42, 42],
- NSRect:[42, 42, 42, 42], char:42).should == 1
- end
-end
Added: MacRuby/branches/experimental/spec/macruby/objc_method_spec.rb
===================================================================
--- MacRuby/branches/experimental/spec/macruby/objc_method_spec.rb (rev 0)
+++ MacRuby/branches/experimental/spec/macruby/objc_method_spec.rb 2009-04-28 02:23:44 UTC (rev 1495)
@@ -0,0 +1,372 @@
+require File.dirname(__FILE__) + '/../spec_helper'
+
+framework 'Foundation'
+
+fixture_source = File.dirname(__FILE__) + '/fixtures/method.m'
+fixture_ext = '/tmp/method.bundle'
+if !File.exist?(fixture_ext) or File.mtime(fixture_source) > File.mtime(fixture_ext)
+=begin
+ # #system is currently broken
+ unless system("/usr/bin/gcc #{fixture_source} -o #{fixture_ext} -g -framework Foundation -dynamiclib -fobjc-gc -arch i386 -arch x86_64 -arch ppc")
+ $stderr.puts "cannot compile fixture source file `#{fixture_source}' - aborting"
+ exit 1
+ end
+=end
+ `/usr/bin/gcc #{fixture_source} -o #{fixture_ext} -g -framework Foundation -dynamiclib -fobjc-gc -arch i386 -arch x86_64 -arch ppc`
+end
+require '/tmp/method'
+load_bridge_support_file File.dirname(__FILE__) + '/fixtures/method.bridgesupport'
+
+describe "A pure Objective-C method" do
+ before :each do
+ @o = TestMethod.new
+ end
+
+ it "can be called with #foo= if it matches the #setFoo pattern" do
+ o = []
+
+ # TODO Stopped here: This should be sufficient, but doesn't work.
+ # o.should have_method(:'setArray', true)
+ # o.should have_method(:'array=', true)
+
+ o.respond_to?(:'setArray').should == true
+ o.respond_to?(:'array=').should == true
+ o.array = [1, 2, 3]
+ o.should == [1, 2, 3]
+ end
+
+ it "can be called with #foo? if it matches the #isFoo pattern" do
+ o = NSBundle.mainBundle
+ o.respond_to?(:'isLoaded').should == true
+ o.respond_to?(:'loaded?').should == true
+ o.loaded?.should == true
+ end
+
+ it "is only exposed in #methods if the second argument is true" do
+ o = Object.new
+ o.methods.include?(:'performSelector').should == false
+ o.methods(true).include?(:'performSelector').should == false
+ o.methods(false).include?(:'performSelector').should == false
+ o.methods(true, true).include?(:'performSelector').should == true
+ o.methods(false, true).include?(:'performSelector').should == true
+ end
+
+ it "can be called on an immediate object" do
+ 123.self.should == 123
+ true.self.should == true
+ false.self.should == false
+ nil.self.should == nil
+ end
+
+ it "returning void returns nil in Ruby" do
+ @o.methodReturningVoid.should == nil
+ end
+
+ it "returning nil returns nil in Ruby" do
+ @o.methodReturningNil.should == nil
+ end
+
+ it "returning self returns the same receiver object" do
+ @o.methodReturningSelf.should == @o
+ @o.methodReturningSelf.object_id == @o.object_id
+ end
+
+ it "returning kCFBooleanTrue returns true in Ruby" do
+ @o.methodReturningCFTrue.should == true
+ @o.methodReturningCFTrue.class.should == TrueClass
+ end
+
+ it "returning kCFBooleanFalse returns false in Ruby" do
+ @o.methodReturningCFFalse.should == false
+ @o.methodReturningCFFalse.class.should == FalseClass
+ end
+
+ it "returning kCFNull returns nil in Ruby" do
+ @o.methodReturningCFNull.should == nil
+ @o.methodReturningCFNull.class.should == NilClass
+ end
+
+ it "returning YES returns true in Ruby" do
+ @o.methodReturningYES.should == true
+ end
+
+ it "returning NO returns true in Ruby" do
+ @o.methodReturningNO.should == false
+ end
+
+ it "returning 'char' or 'unsigned char' returns a Fixnum in Ruby" do
+ @o.methodReturningChar.should == 42
+ @o.methodReturningChar2.should == -42
+ @o.methodReturningUnsignedChar.should == 42
+ end
+
+ it "returning 'short' or 'unsigned short' returns a Fixnum in Ruby" do
+ @o.methodReturningShort.should == 42
+ @o.methodReturningShort2.should == -42
+ @o.methodReturningUnsignedShort.should == 42
+ end
+
+ it "returning 'int' or 'unsigned int' returns a Fixnum in Ruby" do
+ @o.methodReturningInt.should == 42
+ @o.methodReturningInt2.should == -42
+ @o.methodReturningUnsignedInt.should == 42
+ end
+
+ it "returning 'long' or 'unsigned long' returns a Fixnum if possible in Ruby" do
+ @o.methodReturningLong.should == 42
+ @o.methodReturningLong2.should == -42
+ @o.methodReturningUnsignedLong.should == 42
+ end
+
+ it "returning 'long' or 'unsigned long' returns a Bignum if it cannot fix in a Fixnum in Ruby" do
+ @o.methodReturningLong3.should ==
+ (RUBY_ARCH == 'x86_64' ? 4611686018427387904 : 1073741824)
+ @o.methodReturningLong3.class.should == Bignum
+ @o.methodReturningLong4.should ==
+ (RUBY_ARCH == 'x86_64' ? -4611686018427387905 : -1073741825)
+ @o.methodReturningLong4.class.should == Bignum
+ @o.methodReturningUnsignedLong2.should ==
+ (RUBY_ARCH == 'x86_64' ? 4611686018427387904 : 1073741824)
+ @o.methodReturningUnsignedLong2.class.should == Bignum
+ end
+
+ it "returning 'float' returns a Float in Ruby" do
+ @o.methodReturningFloat.should be_close(3.1415, 0.0001)
+ @o.methodReturningFloat.class.should == Float
+ end
+
+ it "returning 'double' returns a Float in Ruby" do
+ @o.methodReturningDouble.should be_close(3.1415, 0.0001)
+ @o.methodReturningDouble.class.should == Float
+ end
+
+ it "returning 'SEL' returns a Symbol or nil in Ruby" do
+ @o.methodReturningSEL.class.should == Symbol
+ @o.methodReturningSEL.should == :'foo:with:with:'
+ @o.methodReturningSEL2.class.should == NilClass
+ @o.methodReturningSEL2.should == nil
+ end
+
+ it "returning 'char *' returns a String or nil in Ruby" do
+ @o.methodReturningCharPtr.class.should == String
+ @o.methodReturningCharPtr.should == 'foo'
+ @o.methodReturningCharPtr2.class.should == NilClass
+ @o.methodReturningCharPtr2.should == nil
+ end
+
+ it "returning 'NSPoint' returns an NSPoint boxed object in Ruby" do
+ b = @o.methodReturningNSPoint
+ b.class.should == NSPoint
+ b.x.class.should == Float
+ b.x.should == 1.0
+ b.y.class.should == Float
+ b.y.should == 2.0
+ end
+
+ it "returning 'NSSize' returns an NSSize boxed object in Ruby" do
+ b = @o.methodReturningNSSize
+ b.class.should == NSSize
+ b.width.class.should == Float
+ b.width.should == 3.0
+ b.height.class.should == Float
+ b.height.should == 4.0
+ end
+
+ it "returning 'NSRect' returns an NSRect boxed object in Ruby" do
+ b = @o.methodReturningNSRect
+ b.class.should == NSRect
+ b.origin.class.should == NSPoint
+ b.origin.x.should == 1.0
+ b.origin.y.should == 2.0
+ b.size.class.should == NSSize
+ b.size.width.should == 3.0
+ b.size.height.should == 4.0
+ end
+
+ it "returning 'NSRange' returns an NSRange boxed object in Ruby" do
+ b = @o.methodReturningNSRange
+ b.class.should == NSRange
+ b.location.class.should == Fixnum
+ b.location.should == 0
+ b.length.class.should == Fixnum
+ b.length.should == 42
+ end
+
+ it "accepting the receiver as 'id' should receive the exact same object" do
+ @o.methodAcceptingSelf(@o).should == 1
+ end
+
+ it "accepting the receiver's class as 'id' should receive the exact same object" do
+ @o.methodAcceptingSelfClass(@o.class).should == 1
+ end
+
+ it "accepting 'nil' as 'id' should receive Objective-C's nil" do
+ @o.methodAcceptingNil(nil).should == 1
+ end
+
+ it "accepting 'true' as 'id; should receive CF's kCFBooleanTrue" do
+ @o.methodAcceptingTrue(true).should == 1
+ end
+
+ it "accepting 'false' as 'id' should receive CF's kCFBooleanFalse" do
+ @o.methodAcceptingFalse(false).should == 1
+ end
+
+ it "accepting a Fixnum as 'id' should receive a Fixnum boxed object" do
+ @o.methodAcceptingFixnum(42).should == 1
+ end
+
+ it "accepting nil or false as 'BOOL' should receive NO, any other object should receive YES" do
+ @o.methodAcceptingFalseBOOL(nil).should == 1
+ @o.methodAcceptingFalseBOOL(false).should == 1
+
+ @o.methodAcceptingTrueBOOL(true).should == 1
+ @o.methodAcceptingTrueBOOL(0).should == 1
+ @o.methodAcceptingTrueBOOL(123).should == 1
+ @o.methodAcceptingTrueBOOL('foo').should == 1
+ @o.methodAcceptingTrueBOOL(Object.new).should == 1
+ end
+
+ it "accepting a Fixnum-compatible object as 'char', 'unsigned char', 'short', 'unsigned short', 'int', 'unsigned int', 'long', 'unsigned long' should receive the converted data, or raise an exception" do
+ @o.methodAcceptingChar(42).should == 1
+ @o.methodAcceptingUnsignedChar(42).should == 1
+ @o.methodAcceptingShort(42).should == 1
+ @o.methodAcceptingUnsignedShort(42).should == 1
+ @o.methodAcceptingInt(42).should == 1
+ @o.methodAcceptingUnsignedInt(42).should == 1
+ @o.methodAcceptingLong(42).should == 1
+ @o.methodAcceptingUnsignedLong(42).should == 1
+
+ @o.methodAcceptingChar(42.0).should == 1
+ @o.methodAcceptingUnsignedChar(42.0).should == 1
+ @o.methodAcceptingShort(42.0).should == 1
+ @o.methodAcceptingUnsignedShort(42.0).should == 1
+ @o.methodAcceptingInt(42.0).should == 1
+ @o.methodAcceptingUnsignedInt(42.0).should == 1
+ @o.methodAcceptingLong(42.0).should == 1
+ @o.methodAcceptingUnsignedLong(42.0).should == 1
+
+ o2 = Object.new
+ def o2.to_i; 42; end
+
+ @o.methodAcceptingChar(o2).should == 1
+ @o.methodAcceptingUnsignedChar(o2).should == 1
+ @o.methodAcceptingShort(o2).should == 1
+ @o.methodAcceptingUnsignedShort(o2).should == 1
+ @o.methodAcceptingInt(o2).should == 1
+ @o.methodAcceptingUnsignedInt(o2).should == 1
+ @o.methodAcceptingLong(o2).should == 1
+ @o.methodAcceptingUnsignedLong(o2).should == 1
+
+ lambda { @o.methodAcceptingChar(nil) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingUnsignedChar(nil) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingShort(nil) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingUnsignedShort(nil) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingInt(nil) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingUnsignedInt(nil) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingLong(nil) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingUnsignedLong(nil) }.should raise_error(TypeError)
+
+ lambda { @o.methodAcceptingChar(Object.new) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingUnsignedChar(Object.new) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingShort(Object.new) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingUnsignedShort(Object.new) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingInt(Object.new) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingUnsignedInt(Object.new) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingLong(Object.new) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingUnsignedLong(Object.new) }.should raise_error(TypeError)
+ end
+
+ it "accepting a one-character string as 'char' or 'unsigned char' should receive the first character" do
+ @o.methodAcceptingChar('*').should == 1
+ @o.methodAcceptingUnsignedChar('*').should == 1
+ end
+
+ it "accepting a String, Symbol or nil as 'SEL' should receive the appropriate selector" do
+ @o.methodAcceptingSEL(:'foo:with:with:').should == 1
+ @o.methodAcceptingSEL('foo:with:with:').should == 1
+ @o.methodAcceptingSEL2(nil).should == 1
+
+ lambda { @o.methodAcceptingSEL(123) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingSEL(Object.new) }.should raise_error(TypeError)
+ end
+
+ it "accepting a Float-compatible object as 'float' or 'double' should receive the appropriate data" do
+ @o.methodAcceptingFloat(3.1415).should == 1
+ @o.methodAcceptingDouble(3.1415).should == 1
+
+ o2 = Object.new
+ def o2.to_f; 3.1415; end
+
+ @o.methodAcceptingFloat(o2).should == 1
+ @o.methodAcceptingDouble(o2).should == 1
+
+ lambda { @o.methodAcceptingFloat(nil) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingDouble(nil) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingFloat(Object.new) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingDouble(Object.new) }.should raise_error(TypeError)
+ end
+
+ it "accepting a String-compatible object as 'char *' should receive the appropriate data" do
+ @o.methodAcceptingCharPtr('foo').should == 1
+
+ o2 = Object.new
+ def o2.to_str; 'foo' end
+
+ @o.methodAcceptingCharPtr(o2).should == 1
+
+ lambda { @o.methodAcceptingCharPtr(123) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingCharPtr([]) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingCharPtr(Object.new) }.should raise_error(TypeError)
+
+ @o.methodAcceptingCharPtr2(nil).should == 1
+ end
+
+ it "accepting an NSPoint, NSSize, NSRange or NSRect object as 'NSPoint', 'NSSize', 'NSRange' or 'NSRect' should receive the C structure" do
+ p = @o.methodReturningNSPoint
+ @o.methodAcceptingNSPoint(p).should == 1
+ p = @o.methodReturningNSSize
+ @o.methodAcceptingNSSize(p).should == 1
+ p = @o.methodReturningNSRect
+ @o.methodAcceptingNSRect(p).should == 1
+ p = @o.methodReturningNSRange
+ @o.methodAcceptingNSRange(p).should == 1
+
+ lambda { @o.methodAcceptingNSPoint(nil) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingNSPoint(123) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingNSPoint(Object.new) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingNSPoint(@o.methodReturningNSSize) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingNSSize(nil) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingNSSize(123) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingNSSize(Object.new) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingNSSize(@o.methodReturningNSPoint) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingNSRect(nil) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingNSRect(123) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingNSRect(Object.new) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingNSRect(@o.methodReturningNSPoint) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingNSRange(nil) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingNSRange(123) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingNSRange(Object.new) }.should raise_error(TypeError)
+ lambda { @o.methodAcceptingNSRange(@o.methodReturningNSPoint) }.should raise_error(TypeError)
+ end
+
+ it "accepting an Array of valid objects as a structure type should receive the C structure" do
+ @o.methodAcceptingNSPoint([1, 2]).should == 1
+ @o.methodAcceptingNSSize([3, 4]).should == 1
+ @o.methodAcceptingNSRect([[1, 2], [3, 4]]).should == 1
+ @o.methodAcceptingNSRect([1, 2, 3, 4]).should == 1
+ @o.methodAcceptingNSRange([0, 42]).should == 1
+
+ lambda { @o.methodAcceptingNSPoint([1]) }.should raise_error(ArgumentError)
+ lambda { @o.methodAcceptingNSPoint([1, 2, 3]) }.should raise_error(ArgumentError)
+ lambda { @o.methodAcceptingNSRect([1, 2, 3]) }.should raise_error(ArgumentError)
+ lambda { @o.methodAcceptingNSRect([1, 2, 3, 4, 5]) }.should raise_error(ArgumentError)
+ lambda { @o.methodAcceptingNSRect([[1, 2], [3]]) }.should raise_error(ArgumentError)
+ lambda { @o.methodAcceptingNSRect([[1, 2], [3, 4, 5]]) }.should raise_error(ArgumentError)
+ end
+
+ it "accepting various C types should receive these types as expected" do
+ @o.methodAcceptingInt(42, float:42, double:42, short:42, NSPoint:[42, 42],
+ NSRect:[42, 42, 42, 42], char:42).should == 1
+ end
+end
Added: MacRuby/branches/experimental/spec/macruby/pointer_spec.rb
===================================================================
--- MacRuby/branches/experimental/spec/macruby/pointer_spec.rb (rev 0)
+++ MacRuby/branches/experimental/spec/macruby/pointer_spec.rb 2009-04-28 02:23:44 UTC (rev 1495)
@@ -0,0 +1,52 @@
+require File.dirname(__FILE__) + '/../spec_helper'
+
+framework 'Foundation'
+
+describe "A Pointer object" do
+=begin # TODO
+ it "can be created using the #new class method and with a valid Objective-C type or a valid Symbol object" do
+ types = {
+ :object => '@',
+ :char => 'c',
+ :uchar => 'C',
+ :short => 's',
+ :ushort => 'S',
+ :int => 'i',
+ :uint => 'I',
+ :long => 'l',
+ :ulong => 'L',
+ :long_long => 'q',
+ :ulong_long => 'Q',
+ :float => 'f',
+ :double => 'd'
+ }
+
+ types.each do |sym, typestr|
+ p = nil
+ lambda { p = Pointer.new(sym) }.should_not raise_error
+ p.type.should == typestr
+
+ lambda { p = Pointer.new(typestr) }.should_not raise_error
+ p.type.should == typestr
+ end
+
+ lambda { Pointer.new }.should raise_error(ArgumentError)
+ lambda { Pointer.new('invalid') }.should raise_error(TypeError)
+ end
+=end
+
+=begin # TODO
+ it "can be assigned an object of the given type and retrieve it later, using #[] and #[]="
+ p = Pointer.new('@')
+ o = Object.new
+ p[0] = o
+ p[0].should == o
+
+ p = Pointer.new('i')
+ p[0] = 42
+ p[0].should == 42
+
+ lambda { p[0] = Object.new }.should raise_error(TypeError)
+ end
+=end
+end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090427/ca3c01b9/attachment-0001.html>
More information about the macruby-changes
mailing list