[macruby-changes] [4441] MacRuby/trunk/spec/frozen

source_changes at macosforge.org source_changes at macosforge.org
Sun Aug 22 06:17:27 PDT 2010


Revision: 4441
          http://trac.macosforge.org/projects/ruby/changeset/4441
Author:   eloy.de.enige at gmail.com
Date:     2010-08-22 06:17:27 -0700 (Sun, 22 Aug 2010)
Log Message:
-----------
Update RubySpec to 0bbe4d3ddcb78c5c1bf12821acfe167f868715e9 2

Added Paths:
-----------
    MacRuby/trunk/spec/frozen/command_line/error_message_spec.rb
    MacRuby/trunk/spec/frozen/core/array/pack/
    MacRuby/trunk/spec/frozen/core/array/pack/c_spec.rb
    MacRuby/trunk/spec/frozen/core/array/pack/i_spec.rb
    MacRuby/trunk/spec/frozen/core/array/pack/l_spec.rb
    MacRuby/trunk/spec/frozen/core/array/pack/n_spec.rb
    MacRuby/trunk/spec/frozen/core/array/pack/q_spec.rb
    MacRuby/trunk/spec/frozen/core/array/pack/s_spec.rb
    MacRuby/trunk/spec/frozen/core/array/pack/shared/
    MacRuby/trunk/spec/frozen/core/array/pack/shared/basic.rb
    MacRuby/trunk/spec/frozen/core/array/pack/shared/integer.rb
    MacRuby/trunk/spec/frozen/core/array/pack/shared/numeric_basic.rb
    MacRuby/trunk/spec/frozen/core/array/pack/v_spec.rb
    MacRuby/trunk/spec/frozen/core/array/repeated_combination_spec.rb
    MacRuby/trunk/spec/frozen/core/array/repeated_permutation_spec.rb
    MacRuby/trunk/spec/frozen/core/array/shared/join.rb
    MacRuby/trunk/spec/frozen/core/dir/initialize_spec.rb
    MacRuby/trunk/spec/frozen/core/file/fixtures/common.rb
    MacRuby/trunk/spec/frozen/core/io/fixtures/reopen_stdout.rb
    MacRuby/trunk/spec/frozen/core/string/unpack/
    MacRuby/trunk/spec/frozen/core/string/unpack/c_spec.rb
    MacRuby/trunk/spec/frozen/core/struct/shared/.equal_value.rb.rej.swp
    MacRuby/trunk/spec/frozen/core/struct/shared/.equal_value.rb.swp
    MacRuby/trunk/spec/frozen/language/fixtures/next.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegate_class/
    MacRuby/trunk/spec/frozen/library/delegate/delegate_class/instance_method_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegate_class/instance_methods_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegate_class/private_instance_methods_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegate_class/protected_instance_methods_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegate_class/public_instance_methods_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/
    MacRuby/trunk/spec/frozen/library/delegate/delegator/case_compare_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/compare_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/complement_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/eql_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/equal_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/equal_value_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/frozen_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/hash_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/marshal_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/method_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/methods_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/not_equal_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/not_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/private_methods_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/protected_methods_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/public_methods_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/send_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/taint_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/tap_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/trust_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/untaint_spec.rb
    MacRuby/trunk/spec/frozen/library/delegate/delegator/untrust_spec.rb
    MacRuby/trunk/spec/frozen/library/set/keep_if_spec.rb
    MacRuby/trunk/spec/frozen/library/set/select_spec.rb
    MacRuby/trunk/spec/frozen/library/set/sortedset/keep_if_spec.rb
    MacRuby/trunk/spec/frozen/library/set/sortedset/select_spec.rb
    MacRuby/trunk/spec/frozen/library/socket/unixserver/for_fd_spec.rb
    MacRuby/trunk/spec/frozen/library/uri/merge_spec.rb
    MacRuby/trunk/spec/frozen/library/uri/route_from_spec.rb
    MacRuby/trunk/spec/frozen/library/uri/route_to_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/_getproperty_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/_invoke_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/_setproperty_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/codepage_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/connect_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/const_load_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/constants_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/create_guid_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/each_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/invoke_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/locale_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/new_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_func_methods_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_get_methods_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_method_help_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_method_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_methods_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_obj_help_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_put_methods_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_show_help_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/setproperty_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/shared/
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/shared/ole_method.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole/shared/setproperty.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/handler_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/message_loop_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/new_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/off_event_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/on_event_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/on_event_with_outargs_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/unadvise_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/dispid_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/event_interface_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/event_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/helpcontext_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/helpfile_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/helpstring_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/invkind_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/invoke_kind_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/name_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/new_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/offset_vtbl_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/params_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/return_type_detail_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/return_type_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/return_vtype_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/shared/
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/shared/name.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/size_opt_params_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/size_params_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/to_s_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/visible_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/default_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/input_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/name_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/ole_type_detail_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/ole_type_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/optional_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/retval_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/shared/
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/shared/name.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/to_s_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/guid_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/helpcontext_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/helpfile_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/helpstring_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/major_version_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/minor_version_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/name_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/new_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/ole_classes_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/ole_methods_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/ole_type_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/progid_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/progids_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/shared/
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/shared/name.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/src_type_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/to_s_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/typekind_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/typelibs_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/variables_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/visible_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/name_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/ole_type_detail_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/ole_type_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/shared/
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/shared/name.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/to_s_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/value_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/variable_kind_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/varkind_spec.rb
    MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/visible_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/
    MacRuby/trunk/spec/frozen/optional/capi/README
    MacRuby/trunk/spec/frozen/optional/capi/array_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/bignum_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/class_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/constants_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/data_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/exception_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/ext/
    MacRuby/trunk/spec/frozen/optional/capi/ext/.gitignore
    MacRuby/trunk/spec/frozen/optional/capi/ext/array_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/bignum_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/class_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/constants_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/data_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/exception_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/float_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/gc_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/globals_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/hash_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/io_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/jruby.h
    MacRuby/trunk/spec/frozen/optional/capi/ext/kernel_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/module_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/mri.h
    MacRuby/trunk/spec/frozen/optional/capi/ext/numeric_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/object_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/proc_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/range_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/rubinius.h
    MacRuby/trunk/spec/frozen/optional/capi/ext/rubyspec.h
    MacRuby/trunk/spec/frozen/optional/capi/ext/safe_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/string_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/struct_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/symbol_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/thread_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/ext/time_spec.c
    MacRuby/trunk/spec/frozen/optional/capi/fixtures/
    MacRuby/trunk/spec/frozen/optional/capi/fixtures/foo.rb
    MacRuby/trunk/spec/frozen/optional/capi/float_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/gc_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/globals_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/hash_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/io_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/kernel_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/module_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/numeric_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/object_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/proc_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/rake_helper.rb
    MacRuby/trunk/spec/frozen/optional/capi/range_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/safe_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/spec_helper.rb
    MacRuby/trunk/spec/frozen/optional/capi/string_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/struct_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/symbol_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/thread_spec.rb
    MacRuby/trunk/spec/frozen/optional/capi/time_spec.rb

Added: MacRuby/trunk/spec/frozen/command_line/error_message_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/command_line/error_message_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/command_line/error_message_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,11 @@
+require File.expand_path('../../spec_helper', __FILE__)
+
+describe "The error message caused by an exception" do
+  it "is not printed to stdout" do
+    out = ruby_exe("this_does_not_exist", :args => "2> #{dev_null()}")
+    out.chomp.empty?.should == true
+
+    out = ruby_exe("end #syntax error", :args => "2> #{dev_null()}")
+    out.chomp.empty?.should == true
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/array/pack/c_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/array/pack/c_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/array/pack/c_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,77 @@
+# -*- encoding: ascii-8bit -*-
+
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+require File.expand_path('../shared/basic', __FILE__)
+require File.expand_path('../shared/numeric_basic', __FILE__)
+
+describe :array_pack_8bit, :shared => true do
+  it "encodes the least significant eight bits of a positive number" do
+    [ [[49],           "1"],
+      [[0b11111111],   "\xFF"],
+      [[0b100000000],  "\x00"],
+      [[0b100000001],  "\x01"]
+    ].should be_computed_by(:pack, pack_format)
+  end
+
+  it "encodes the least significant eight bits of a negative number" do
+    [ [[-1],           "\xFF"],
+      [[-0b10000000],  "\x80"],
+      [[-0b11111111],  "\x01"],
+      [[-0b100000000], "\x00"],
+      [[-0b100000001], "\xFF"]
+    ].should be_computed_by(:pack, pack_format)
+  end
+
+  it "encodes a Float truncated as an Integer" do
+    [ [[5.2], "\x05"],
+      [[5.8], "\x05"]
+    ].should be_computed_by(:pack, pack_format)
+  end
+
+  it "calls #to_int to convert the pack argument to an Integer" do
+    obj = mock('to_int')
+    obj.should_receive(:to_int).and_return(5)
+    [obj].pack(pack_format).should == "\x05"
+  end
+
+  not_compliant_on :rubinius do
+    ruby_version_is '' ... '1.9' do
+      it "accepts a Symbol as a pack argument because it responds to #to_int" do
+        [:hello].pack(pack_format).should == [:hello.to_i].pack('C')
+      end
+    end
+  end
+
+  it "encodes the number of array elements specified by the count modifier" do
+    [ [[1, 2, 3], pack_format(3), "\x01\x02\x03"],
+      [[1, 2, 3], pack_format(2) + pack_format(1), "\x01\x02\x03"]
+    ].should be_computed_by(:pack)
+  end
+
+  it "encodes all remaining elements when passed the '*' modifier" do
+    [1, 2, 3, 4, 5].pack(pack_format('*')).should == "\x01\x02\x03\x04\x05"
+  end
+
+  it "ignores NULL bytes between directives" do
+    [1, 2, 3].pack(pack_format("\000", 2)).should == "\x01\x02"
+  end
+
+  it "ignores spaces between directives" do
+    [1, 2, 3].pack(pack_format(' ', 2)).should == "\x01\x02"
+  end
+end
+
+describe "Array#pack with format 'C'" do
+  it_behaves_like :array_pack_8bit, 'C'
+  it_behaves_like :array_pack_basic, 'C'
+  it_behaves_like :array_pack_numeric_basic, 'C'
+  it_behaves_like :array_pack_no_platform, 'C'
+end
+
+describe "Array#pack with format 'c'" do
+  it_behaves_like :array_pack_8bit, 'c'
+  it_behaves_like :array_pack_basic, 'c'
+  it_behaves_like :array_pack_numeric_basic, 'c'
+  it_behaves_like :array_pack_no_platform, 'c'
+end

Added: MacRuby/trunk/spec/frozen/core/array/pack/i_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/array/pack/i_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/array/pack/i_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,67 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+require File.expand_path('../shared/basic', __FILE__)
+require File.expand_path('../shared/numeric_basic', __FILE__)
+require File.expand_path('../shared/integer', __FILE__)
+
+describe "Array#pack with format 'I'" do
+  it_behaves_like :array_pack_basic, 'I'
+  it_behaves_like :array_pack_numeric_basic, 'I'
+end
+
+describe "Array#pack with format 'i'" do
+  it_behaves_like :array_pack_basic, 'i'
+  it_behaves_like :array_pack_numeric_basic, 'i'
+end
+
+little_endian do
+  describe "Array#pack with format 'I'" do
+    it_behaves_like :array_pack_32bit_le, 'I'
+  end
+
+  describe "Array#pack with format 'I' with modifier '_'" do
+    it_behaves_like :array_pack_32bit_le_platform, 'I_'
+  end
+
+  describe "Array#pack with format 'I' with modifier '!'" do
+    it_behaves_like :array_pack_32bit_le_platform, 'I!'
+  end
+
+  describe "Array#pack with format 'i'" do
+    it_behaves_like :array_pack_32bit_le, 'i'
+  end
+
+  describe "Array#pack with format 'i' with modifier '_'" do
+    it_behaves_like :array_pack_32bit_le_platform, 'i_'
+  end
+
+  describe "Array#pack with format 'i' with modifier '!'" do
+    it_behaves_like :array_pack_32bit_le_platform, 'i!'
+  end
+end
+
+big_endian do
+  describe "Array#pack with format 'I'" do
+    it_behaves_like :array_pack_32bit_be, 'I'
+  end
+
+  describe "Array#pack with format 'I' with modifier '_'" do
+    it_behaves_like :array_pack_32bit_be_platform, 'I_'
+  end
+
+  describe "Array#pack with format 'I' with modifier '!'" do
+    it_behaves_like :array_pack_32bit_be_platform, 'I!'
+  end
+
+  describe "Array#pack with format 'i'" do
+    it_behaves_like :array_pack_32bit_be, 'i'
+  end
+
+  describe "Array#pack with format 'i' with modifier '_'" do
+    it_behaves_like :array_pack_32bit_be_platform, 'i_'
+  end
+
+  describe "Array#pack with format 'i' with modifier '!'" do
+    it_behaves_like :array_pack_32bit_be_platform, 'i!'
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/array/pack/l_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/array/pack/l_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/array/pack/l_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,187 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+require File.expand_path('../shared/basic', __FILE__)
+require File.expand_path('../shared/numeric_basic', __FILE__)
+require File.expand_path('../shared/integer', __FILE__)
+
+describe "Array#pack with format 'L'" do
+  it_behaves_like :array_pack_basic, 'L'
+  it_behaves_like :array_pack_numeric_basic, 'L'
+end
+
+describe "Array#pack with format 'l'" do
+  it_behaves_like :array_pack_basic, 'l'
+  it_behaves_like :array_pack_numeric_basic, 'l'
+end
+
+little_endian do
+  describe "Array#pack with format 'L'" do
+    it_behaves_like :array_pack_32bit_le, 'L'
+  end
+
+  describe "Array#pack with format 'l'" do
+    it_behaves_like :array_pack_32bit_le, 'l'
+  end
+
+  platform_is :wordsize => 32 do
+    describe "Array#pack with format 'L' with modifier '_'" do
+      it_behaves_like :array_pack_32bit_le, 'L_'
+    end
+
+    describe "Array#pack with format 'L' with modifier '!'" do
+      it_behaves_like :array_pack_32bit_le, 'L!'
+    end
+
+    describe "Array#pack with format 'l' with modifier '_'" do
+      it_behaves_like :array_pack_32bit_le, 'l_'
+    end
+
+    describe "Array#pack with format 'l' with modifier '!'" do
+      it_behaves_like :array_pack_32bit_le, 'l!'
+    end
+  end
+
+  platform_is :wordsize => 64 do
+    platform_is_not :os => :windows do
+      describe "Array#pack with format 'L' with modifier '_'" do
+        it_behaves_like :array_pack_64bit_le, 'L_'
+      end
+
+      describe "Array#pack with format 'L' with modifier '!'" do
+        it_behaves_like :array_pack_64bit_le, 'L!'
+      end
+
+      describe "Array#pack with format 'l' with modifier '_'" do
+        it_behaves_like :array_pack_64bit_le, 'l_'
+      end
+
+      describe "Array#pack with format 'l' with modifier '!'" do
+        it_behaves_like :array_pack_64bit_le, 'l!'
+      end
+    end
+
+    platform_is :os => :windows do
+      not_compliant_on :jruby do
+        describe "Array#pack with format 'L' with modifier '_'" do
+          it_behaves_like :array_pack_32bit_le, 'L_'
+        end
+
+        describe "Array#pack with format 'L' with modifier '!'" do
+          it_behaves_like :array_pack_32bit_le, 'L!'
+        end
+
+        describe "Array#pack with format 'l' with modifier '_'" do
+          it_behaves_like :array_pack_32bit_le, 'l_'
+        end
+
+        describe "Array#pack with format 'l' with modifier '!'" do
+          it_behaves_like :array_pack_32bit_le, 'l!'
+        end
+      end
+
+      deviates_on :jruby do
+        describe "Array#pack with format 'L' with modifier '_'" do
+          it_behaves_like :array_pack_64bit_le, 'L_'
+        end
+
+        describe "Array#pack with format 'L' with modifier '!'" do
+          it_behaves_like :array_pack_64bit_le, 'L!'
+        end
+
+        describe "Array#pack with format 'l' with modifier '_'" do
+          it_behaves_like :array_pack_64bit_le, 'l_'
+        end
+
+        describe "Array#pack with format 'l' with modifier '!'" do
+          it_behaves_like :array_pack_64bit_le, 'l!'
+        end
+      end
+    end
+  end
+end
+
+big_endian do
+  describe "Array#pack with format 'L'" do
+    it_behaves_like :array_pack_32bit_be, 'L'
+  end
+
+  describe "Array#pack with format 'l'" do
+    it_behaves_like :array_pack_32bit_be, 'l'
+  end
+
+  platform_is :wordsize => 32 do
+    describe "Array#pack with format 'L' with modifier '_'" do
+      it_behaves_like :array_pack_32bit_be, 'L_'
+    end
+
+    describe "Array#pack with format 'L' with modifier '!'" do
+      it_behaves_like :array_pack_32bit_be, 'L!'
+    end
+
+    describe "Array#pack with format 'l' with modifier '_'" do
+      it_behaves_like :array_pack_32bit_be, 'l_'
+    end
+
+    describe "Array#pack with format 'l' with modifier '!'" do
+      it_behaves_like :array_pack_32bit_be, 'l!'
+    end
+  end
+
+  platform_is :wordsize => 64 do
+    platform_is_not :os => :windows do
+      describe "Array#pack with format 'L' with modifier '_'" do
+        it_behaves_like :array_pack_64bit_be, 'L_'
+      end
+
+      describe "Array#pack with format 'L' with modifier '!'" do
+        it_behaves_like :array_pack_64bit_be, 'L!'
+      end
+
+      describe "Array#pack with format 'l' with modifier '_'" do
+        it_behaves_like :array_pack_64bit_be, 'l_'
+      end
+
+      describe "Array#pack with format 'l' with modifier '!'" do
+        it_behaves_like :array_pack_64bit_be, 'l!'
+      end
+    end
+
+    platform_is :os => :windows do
+      not_compliant_on :jruby do
+        describe "Array#pack with format 'L' with modifier '_'" do
+          it_behaves_like :array_pack_32bit_be, 'L_'
+        end
+
+        describe "Array#pack with format 'L' with modifier '!'" do
+          it_behaves_like :array_pack_32bit_be, 'L!'
+        end
+
+        describe "Array#pack with format 'l' with modifier '_'" do
+          it_behaves_like :array_pack_32bit_be, 'l_'
+        end
+
+        describe "Array#pack with format 'l' with modifier '!'" do
+          it_behaves_like :array_pack_32bit_be, 'l!'
+        end
+      end
+
+      deviates_on :jruby do
+        describe "Array#pack with format 'L' with modifier '_'" do
+          it_behaves_like :array_pack_64bit_be, 'L_'
+        end
+
+        describe "Array#pack with format 'L' with modifier '!'" do
+          it_behaves_like :array_pack_64bit_be, 'L!'
+        end
+
+        describe "Array#pack with format 'l' with modifier '_'" do
+          it_behaves_like :array_pack_64bit_be, 'l_'
+        end
+
+        describe "Array#pack with format 'l' with modifier '!'" do
+          it_behaves_like :array_pack_64bit_be, 'l!'
+        end
+      end
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/array/pack/n_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/array/pack/n_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/array/pack/n_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,17 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+require File.expand_path('../shared/basic', __FILE__)
+require File.expand_path('../shared/numeric_basic', __FILE__)
+require File.expand_path('../shared/integer', __FILE__)
+
+describe "Array#pack with format 'N'" do
+  it_behaves_like :array_pack_basic, 'N'
+  it_behaves_like :array_pack_numeric_basic, 'N'
+  it_behaves_like :array_pack_32bit_be, 'N'
+end
+
+describe "Array#pack with format 'n'" do
+  it_behaves_like :array_pack_basic, 'n'
+  it_behaves_like :array_pack_numeric_basic, 'n'
+  it_behaves_like :array_pack_16bit_be, 'n'
+end

Added: MacRuby/trunk/spec/frozen/core/array/pack/q_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/array/pack/q_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/array/pack/q_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,35 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+require File.expand_path('../shared/basic', __FILE__)
+require File.expand_path('../shared/numeric_basic', __FILE__)
+require File.expand_path('../shared/integer', __FILE__)
+
+describe "Array#pack with format 'Q'" do
+  it_behaves_like :array_pack_basic, 'Q'
+  it_behaves_like :array_pack_numeric_basic, 'Q'
+end
+
+describe "Array#pack with format 'q'" do
+  it_behaves_like :array_pack_basic, 'q'
+  it_behaves_like :array_pack_numeric_basic, 'q'
+end
+
+little_endian do
+  describe "Array#pack with format 'Q'" do
+    it_behaves_like :array_pack_64bit_le, 'Q'
+  end
+
+  describe "Array#pack with format 'q'" do
+    it_behaves_like :array_pack_64bit_le, 'q'
+  end
+end
+
+big_endian do
+  describe "Array#pack with format 'Q'" do
+    it_behaves_like :array_pack_64bit_be, 'Q'
+  end
+
+  describe "Array#pack with format 'q'" do
+    it_behaves_like :array_pack_64bit_be, 'q'
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/array/pack/s_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/array/pack/s_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/array/pack/s_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,67 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+require File.expand_path('../shared/basic', __FILE__)
+require File.expand_path('../shared/numeric_basic', __FILE__)
+require File.expand_path('../shared/integer', __FILE__)
+
+describe "Array#pack with format 'S'" do
+  it_behaves_like :array_pack_basic, 'S'
+  it_behaves_like :array_pack_numeric_basic, 'S'
+end
+
+describe "Array#pack with format 's'" do
+  it_behaves_like :array_pack_basic, 's'
+  it_behaves_like :array_pack_numeric_basic, 's'
+end
+
+little_endian do
+  describe "Array#pack with format 'S'" do
+    it_behaves_like :array_pack_16bit_le, 'S'
+  end
+
+  describe "Array#pack with format 'S' with modifier '_'" do
+    it_behaves_like :array_pack_16bit_le, 'S_'
+  end
+
+  describe "Array#pack with format 'S' with modifier '!'" do
+    it_behaves_like :array_pack_16bit_le, 'S!'
+  end
+
+  describe "Array#pack with format 's'" do
+    it_behaves_like :array_pack_16bit_le, 's'
+  end
+
+  describe "Array#pack with format 's' with modifier '_'" do
+    it_behaves_like :array_pack_16bit_le, 's_'
+  end
+
+  describe "Array#pack with format 's' with modifier '!'" do
+    it_behaves_like :array_pack_16bit_le, 's!'
+  end
+end
+
+big_endian do
+  describe "Array#pack with format 'S'" do
+    it_behaves_like :array_pack_16bit_be, 'S'
+  end
+
+  describe "Array#pack with format 'S' with modifier '_'" do
+    it_behaves_like :array_pack_16bit_be, 'S_'
+  end
+
+  describe "Array#pack with format 'S' with modifier '!'" do
+    it_behaves_like :array_pack_16bit_be, 'S!'
+  end
+
+  describe "Array#pack with format 's'" do
+    it_behaves_like :array_pack_16bit_be, 's'
+  end
+
+  describe "Array#pack with format 's' with modifier '_'" do
+    it_behaves_like :array_pack_16bit_be, 's_'
+  end
+
+  describe "Array#pack with format 's' with modifier '!'" do
+    it_behaves_like :array_pack_16bit_be, 's!'
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/array/pack/shared/basic.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/array/pack/shared/basic.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/array/pack/shared/basic.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,15 @@
+describe :array_pack_basic, :shared => true do
+  it "raises an ArgumentError if there are fewer elements than the format requires" do
+    lambda { [].pack(pack_format(1)) }.should raise_error(ArgumentError)
+  end
+end
+
+describe :array_pack_no_platform, :shared => true do
+  it "raises ArgumentError when the format modifier is '_'" do
+    lambda{ [1].pack(pack_format("_")) }.should raise_error(ArgumentError)
+  end
+
+  it "raises ArgumentError when the format modifier is '!'" do
+    lambda{ [1].pack(pack_format("!")) }.should raise_error(ArgumentError)
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/array/pack/shared/integer.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/array/pack/shared/integer.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/array/pack/shared/integer.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,381 @@
+# -*- encoding: ascii-8bit -*-
+
+describe :array_pack_16bit_le, :shared => true do
+  it "encodes the least significant 16 bits of a positive number" do
+    [ [[0x0000_0021], "\x21\x00"],
+      [[0x0000_4321], "\x21\x43"],
+      [[0x0065_4321], "\x21\x43"],
+      [[0x7865_4321], "\x21\x43"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "encodes the least significant 16 bits of a negative number" do
+    [ [[-0x0000_0021], "\xdf\xff"],
+      [[-0x0000_4321], "\xdf\xbc"],
+      [[-0x0065_4321], "\xdf\xbc"],
+      [[-0x7865_4321], "\xdf\xbc"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "encodes a Float truncated as an Integer" do
+    [ [[2019902241.2],  "\x21\x43"],
+      [[2019902241.8],  "\x21\x43"],
+      [[-2019902241.2], "\xdf\xbc"],
+      [[-2019902241.8], "\xdf\xbc"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "calls #to_int to convert the pack argument to an Integer" do
+    obj = mock('to_int')
+    obj.should_receive(:to_int).and_return(0x1234_5678)
+    [obj].pack(pack_format()).should == "\x78\x56"
+  end
+
+  it "encodes the number of array elements specified by the count modifier" do
+    str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format(2))
+    str.should == "\x78\x65\xcd\xab"
+  end
+
+  it "encodes all remaining elements when passed the '*' modifier" do
+    str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format('*'))
+    str.should == "\x78\x65\xcd\xab\x21\x43"
+  end
+
+  it "ignores NULL bytes between directives" do
+    str = [0x1243_6578, 0xdef0_abcd].pack(pack_format("\000", 2))
+    str.should == "\x78\x65\xcd\xab"
+  end
+
+  it "ignores spaces between directives" do
+    str = [0x1243_6578, 0xdef0_abcd].pack(pack_format(' ', 2))
+    str.should == "\x78\x65\xcd\xab"
+  end
+end
+
+describe :array_pack_16bit_be, :shared => true do
+  it "encodes the least significant 16 bits of a positive number" do
+    [ [[0x0000_0021], "\x00\x21"],
+      [[0x0000_4321], "\x43\x21"],
+      [[0x0065_4321], "\x43\x21"],
+      [[0x7865_4321], "\x43\x21"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "encodes the least significant 16 bits of a negative number" do
+    [ [[-0x0000_0021], "\xff\xdf"],
+      [[-0x0000_4321], "\xbc\xdf"],
+      [[-0x0065_4321], "\xbc\xdf"],
+      [[-0x7865_4321], "\xbc\xdf"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "encodes a Float truncated as an Integer" do
+    [ [[2019902241.2],  "\x43\x21"],
+      [[2019902241.8],  "\x43\x21"],
+      [[-2019902241.2], "\xbc\xdf"],
+      [[-2019902241.8], "\xbc\xdf"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "calls #to_int to convert the pack argument to an Integer" do
+    obj = mock('to_int')
+    obj.should_receive(:to_int).and_return(0x1234_5678)
+    [obj].pack(pack_format()).should == "\x56\x78"
+  end
+
+  it "encodes the number of array elements specified by the count modifier" do
+    str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format(2))
+    str.should == "\x65\x78\xab\xcd"
+  end
+
+  it "encodes all remaining elements when passed the '*' modifier" do
+    str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format('*'))
+    str.should == "\x65\x78\xab\xcd\x43\x21"
+  end
+
+  it "ignores NULL bytes between directives" do
+    str = [0x1243_6578, 0xdef0_abcd].pack(pack_format("\000", 2))
+    str.should == "\x65\x78\xab\xcd"
+  end
+
+  it "ignores spaces between directives" do
+    str = [0x1243_6578, 0xdef0_abcd].pack(pack_format(' ', 2))
+    str.should == "\x65\x78\xab\xcd"
+  end
+end
+
+describe :array_pack_32bit_le, :shared => true do
+  it "encodes the least significant 32 bits of a positive number" do
+    [ [[0x0000_0021], "\x21\x00\x00\x00"],
+      [[0x0000_4321], "\x21\x43\x00\x00"],
+      [[0x0065_4321], "\x21\x43\x65\x00"],
+      [[0x7865_4321], "\x21\x43\x65\x78"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "encodes the least significant 32 bits of a negative number" do
+    [ [[-0x0000_0021], "\xdf\xff\xff\xff"],
+      [[-0x0000_4321], "\xdf\xbc\xff\xff"],
+      [[-0x0065_4321], "\xdf\xbc\x9a\xff"],
+      [[-0x7865_4321], "\xdf\xbc\x9a\x87"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "encodes a Float truncated as an Integer" do
+    [ [[2019902241.2],  "\x21\x43\x65\x78"],
+      [[2019902241.8],  "\x21\x43\x65\x78"],
+      [[-2019902241.2], "\xdf\xbc\x9a\x87"],
+      [[-2019902241.8], "\xdf\xbc\x9a\x87"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "calls #to_int to convert the pack argument to an Integer" do
+    obj = mock('to_int')
+    obj.should_receive(:to_int).and_return(0x1234_5678)
+    [obj].pack(pack_format()).should == "\x78\x56\x34\x12"
+  end
+
+  it "encodes the number of array elements specified by the count modifier" do
+    str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format(2))
+    str.should == "\x78\x65\x43\x12\xcd\xab\xf0\xde"
+  end
+
+  it "encodes all remaining elements when passed the '*' modifier" do
+    str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format('*'))
+    str.should == "\x78\x65\x43\x12\xcd\xab\xf0\xde\x21\x43\x65\x78"
+  end
+
+  it "ignores NULL bytes between directives" do
+    str = [0x1243_6578, 0xdef0_abcd].pack(pack_format("\000", 2))
+    str.should == "\x78\x65\x43\x12\xcd\xab\xf0\xde"
+  end
+
+  it "ignores spaces between directives" do
+    str = [0x1243_6578, 0xdef0_abcd].pack(pack_format(' ', 2))
+    str.should == "\x78\x65\x43\x12\xcd\xab\xf0\xde"
+  end
+end
+
+describe :array_pack_32bit_be, :shared => true do
+  it "encodes the least significant 32 bits of a positive number" do
+    [ [[0x0000_0021], "\x00\x00\x00\x21"],
+      [[0x0000_4321], "\x00\x00\x43\x21"],
+      [[0x0065_4321], "\x00\x65\x43\x21"],
+      [[0x7865_4321], "\x78\x65\x43\x21"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "encodes the least significant 32 bits of a negative number" do
+    [ [[-0x0000_0021], "\xff\xff\xff\xdf"],
+      [[-0x0000_4321], "\xff\xff\xbc\xdf"],
+      [[-0x0065_4321], "\xff\x9a\xbc\xdf"],
+      [[-0x7865_4321], "\x87\x9a\xbc\xdf"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "encodes a Float truncated as an Integer" do
+    [ [[2019902241.2],  "\x78\x65\x43\x21"],
+      [[2019902241.8],  "\x78\x65\x43\x21"],
+      [[-2019902241.2], "\x87\x9a\xbc\xdf"],
+      [[-2019902241.8], "\x87\x9a\xbc\xdf"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "calls #to_int to convert the pack argument to an Integer" do
+    obj = mock('to_int')
+    obj.should_receive(:to_int).and_return(0x1234_5678)
+    [obj].pack(pack_format()).should == "\x12\x34\x56\x78"
+  end
+
+  it "encodes the number of array elements specified by the count modifier" do
+    str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format(2))
+    str.should == "\x12\x43\x65\x78\xde\xf0\xab\xcd"
+  end
+
+  it "encodes all remaining elements when passed the '*' modifier" do
+    str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format('*'))
+    str.should == "\x12\x43\x65\x78\xde\xf0\xab\xcd\x78\x65\x43\x21"
+  end
+
+  it "ignores NULL bytes between directives" do
+    str = [0x1243_6578, 0xdef0_abcd].pack(pack_format("\000", 2))
+    str.should == "\x12\x43\x65\x78\xde\xf0\xab\xcd"
+  end
+
+  it "ignores spaces between directives" do
+    str = [0x1243_6578, 0xdef0_abcd].pack(pack_format(' ', 2))
+    str.should ==  "\x12\x43\x65\x78\xde\xf0\xab\xcd"
+  end
+end
+
+describe :array_pack_32bit_le_platform, :shared => true do
+  it "encodes the least significant 32 bits of a number" do
+    [ [[0x7865_4321],  "\x21\x43\x65\x78"],
+      [[-0x7865_4321], "\xdf\xbc\x9a\x87"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "encodes the number of array elements specified by the count modifier" do
+    str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format(2))
+    str.should == "\x78\x65\x43\x12\xcd\xab\xf0\xde"
+  end
+
+  it "encodes all remaining elements when passed the '*' modifier" do
+    str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format('*'))
+    str.should == "\x78\x65\x43\x12\xcd\xab\xf0\xde\x21\x43\x65\x78"
+  end
+
+  platform_is :wordsize => 64 do
+    it "encodes the least significant 32 bits of a number that is greater than 32 bits" do
+      [ [[0xff_7865_4321],  "\x21\x43\x65\x78"],
+        [[-0xff_7865_4321], "\xdf\xbc\x9a\x87"]
+      ].should be_computed_by(:pack, pack_format())
+    end
+  end
+end
+
+describe :array_pack_32bit_be_platform, :shared => true do
+  it "encodes the least significant 32 bits of a number" do
+    [ [[0x7865_4321],  "\x78\x65\x43\x21"],
+      [[-0x7865_4321], "\x87\x9a\xbc\xdf"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "encodes the number of array elements specified by the count modifier" do
+    str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format(2))
+    str.should == "\x12\x43\x65\x78\xde\xf0\xab\xcd"
+  end
+
+  it "encodes all remaining elements when passed the '*' modifier" do
+    str = [0x1243_6578, 0xdef0_abcd, 0x7865_4321].pack(pack_format('*'))
+    str.should == "\x12\x43\x65\x78\xde\xf0\xab\xcd\x78\x65\x43\x21"
+  end
+
+  platform_is :wordsize => 64 do
+    it "encodes the least significant 32 bits of a number that is greater than 32 bits" do
+      [ [[0xff_7865_4321],  "\x78\x65\x43\x21"],
+        [[-0xff_7865_4321], "\x87\x9a\xbc\xdf"]
+      ].should be_computed_by(:pack, pack_format())
+    end
+  end
+end
+
+describe :array_pack_64bit_le, :shared => true do
+  it "encodes the least significant 64 bits of a positive number" do
+    [ [[0x0000_0000_0000_0021], "\x21\x00\x00\x00\x00\x00\x00\x00"],
+      [[0x0000_0000_0000_4321], "\x21\x43\x00\x00\x00\x00\x00\x00"],
+      [[0x0000_0000_0065_4321], "\x21\x43\x65\x00\x00\x00\x00\x00"],
+      [[0x0000_0000_7865_4321], "\x21\x43\x65\x78\x00\x00\x00\x00"],
+      [[0x0000_0090_7865_4321], "\x21\x43\x65\x78\x90\x00\x00\x00"],
+      [[0x0000_ba90_7865_4321], "\x21\x43\x65\x78\x90\xba\x00\x00"],
+      [[0x00dc_ba90_7865_4321], "\x21\x43\x65\x78\x90\xba\xdc\x00"],
+      [[0x7edc_ba90_7865_4321], "\x21\x43\x65\x78\x90\xba\xdc\x7e"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "encodes the least significant 64 bits of a negative number" do
+    [ [[-0x0000_0000_0000_0021], "\xdf\xff\xff\xff\xff\xff\xff\xff"],
+      [[-0x0000_0000_0000_4321], "\xdf\xbc\xff\xff\xff\xff\xff\xff"],
+      [[-0x0000_0000_0065_4321], "\xdf\xbc\x9a\xff\xff\xff\xff\xff"],
+      [[-0x0000_0000_7865_4321], "\xdf\xbc\x9a\x87\xff\xff\xff\xff"],
+      [[-0x0000_0090_7865_4321], "\xdf\xbc\x9a\x87\x6f\xff\xff\xff"],
+      [[-0x0000_ba90_7865_4321], "\xdf\xbc\x9a\x87\x6f\x45\xff\xff"],
+      [[-0x00dc_ba90_7865_4321], "\xdf\xbc\x9a\x87\x6f\x45\x23\xff"],
+      [[-0x7edc_ba90_7865_4321], "\xdf\xbc\x9a\x87\x6f\x45\x23\x81"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "encodes a Float truncated as an Integer" do
+    [ [[9.14138647331322368e+18],  "\x00\x44\x65\x78\x90\xba\xdc\x7e"],
+      [[-9.14138647331322368e+18], "\x00\xbc\x9a\x87\x6f\x45\x23\x81"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "calls #to_int to convert the pack argument to an Integer" do
+    obj = mock('to_int')
+    obj.should_receive(:to_int).and_return(0x1234_5678_90ab_cdef)
+    [obj].pack(pack_format()).should == "\xef\xcd\xab\x90\x78\x56\x34\x12"
+  end
+
+  it "encodes the number of array elements specified by the count modifier" do
+    str = [0x1234_5678_90ab_cdef,
+           0xdef0_abcd_3412_7856,
+           0x7865_4321_dcba_def0].pack(pack_format(2))
+    str.should == "\xef\xcd\xab\x90\x78\x56\x34\x12\x56\x78\x12\x34\xcd\xab\xf0\xde"
+  end
+
+  it "encodes all remaining elements when passed the '*' modifier" do
+    str = [0xdef0_abcd_3412_7856, 0x7865_4321_dcba_def0].pack(pack_format('*'))
+    str.should == "\x56\x78\x12\x34\xcd\xab\xf0\xde\xf0\xde\xba\xdc\x21\x43\x65\x78"
+  end
+
+  it "ignores NULL bytes between directives" do
+    str = [0xdef0_abcd_3412_7856, 0x7865_4321_dcba_def0].pack(pack_format("\000", 2))
+    str.should == "\x56\x78\x12\x34\xcd\xab\xf0\xde\xf0\xde\xba\xdc\x21\x43\x65\x78"
+  end
+
+  it "ignores spaces between directives" do
+    str = [0xdef0_abcd_3412_7856, 0x7865_4321_dcba_def0].pack(pack_format(' ', 2))
+    str.should == "\x56\x78\x12\x34\xcd\xab\xf0\xde\xf0\xde\xba\xdc\x21\x43\x65\x78"
+  end
+end
+
+describe :array_pack_64bit_be, :shared => true do
+  it "encodes the least significant 64 bits of a positive number" do
+    [ [[0x0000_0000_0000_0021], "\x00\x00\x00\x00\x00\x00\x00\x21"],
+      [[0x0000_0000_0000_4321], "\x00\x00\x00\x00\x00\x00\x43\x21"],
+      [[0x0000_0000_0065_4321], "\x00\x00\x00\x00\x00\x65\x43\x21"],
+      [[0x0000_0000_7865_4321], "\x00\x00\x00\x00\x78\x65\x43\x21"],
+      [[0x0000_0090_7865_4321], "\x00\x00\x00\x90\x78\x65\x43\x21"],
+      [[0x0000_ba90_7865_4321], "\x00\x00\xba\x90\x78\x65\x43\x21"],
+      [[0x00dc_ba90_7865_4321], "\x00\xdc\xba\x90\x78\x65\x43\x21"],
+      [[0x7edc_ba90_7865_4321], "\x7e\xdc\xba\x90\x78\x65\x43\x21"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "encodes the least significant 64 bits of a negative number" do
+    [ [[-0x0000_0000_0000_0021], "\xff\xff\xff\xff\xff\xff\xff\xdf"],
+      [[-0x0000_0000_0000_4321], "\xff\xff\xff\xff\xff\xff\xbc\xdf"],
+      [[-0x0000_0000_0065_4321], "\xff\xff\xff\xff\xff\x9a\xbc\xdf"],
+      [[-0x0000_0000_7865_4321], "\xff\xff\xff\xff\x87\x9a\xbc\xdf"],
+      [[-0x0000_0090_7865_4321], "\xff\xff\xff\x6f\x87\x9a\xbc\xdf"],
+      [[-0x0000_ba90_7865_4321], "\xff\xff\x45\x6f\x87\x9a\xbc\xdf"],
+      [[-0x00dc_ba90_7865_4321], "\xff\x23\x45\x6f\x87\x9a\xbc\xdf"],
+      [[-0x7edc_ba90_7865_4321], "\x81\x23\x45\x6f\x87\x9a\xbc\xdf"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "encodes a Float truncated as an Integer" do
+    [ [[9.14138647331322368e+18],  "\x7e\xdc\xba\x90\x78\x65\x44\x00"],
+      [[-9.14138647331322368e+18], "\x81\x23\x45\x6f\x87\x9a\xbc\x00"]
+    ].should be_computed_by(:pack, pack_format())
+  end
+
+  it "calls #to_int to convert the pack argument to an Integer" do
+    obj = mock('to_int')
+    obj.should_receive(:to_int).and_return(0x1234_5678_90ab_cdef)
+    [obj].pack(pack_format()).should == "\x12\x34\x56\x78\x90\xab\xcd\xef"
+  end
+
+  it "encodes the number of array elements specified by the count modifier" do
+    str = [0x1234_5678_90ab_cdef,
+           0xdef0_abcd_3412_7856,
+           0x7865_4321_dcba_def0].pack(pack_format(2))
+    str.should == "\x12\x34\x56\x78\x90\xab\xcd\xef\xde\xf0\xab\xcd\x34\x12\x78\x56"
+  end
+
+  it "encodes all remaining elements when passed the '*' modifier" do
+    str = [0xdef0_abcd_3412_7856, 0x7865_4321_dcba_def0].pack(pack_format('*'))
+    str.should == "\xde\xf0\xab\xcd\x34\x12\x78\x56\x78\x65\x43\x21\xdc\xba\xde\xf0"
+  end
+
+  it "ignores NULL bytes between directives" do
+    str = [0xdef0_abcd_3412_7856, 0x7865_4321_dcba_def0].pack(pack_format("\000", 2))
+    str.should == "\xde\xf0\xab\xcd\x34\x12\x78\x56\x78\x65\x43\x21\xdc\xba\xde\xf0"
+  end
+
+  it "ignores spaces between directives" do
+    str = [0xdef0_abcd_3412_7856, 0x7865_4321_dcba_def0].pack(pack_format(' ', 2))
+    str.should == "\xde\xf0\xab\xcd\x34\x12\x78\x56\x78\x65\x43\x21\xdc\xba\xde\xf0"
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/array/pack/shared/numeric_basic.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/array/pack/shared/numeric_basic.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/array/pack/shared/numeric_basic.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,21 @@
+describe :array_pack_numeric_basic, :shared => true do
+  it "returns an empty String if count is zero" do
+    [1].pack(pack_format(0)).should == ""
+  end
+
+  it "raises a TypeError when passed a String" do
+    lambda { ["5"].pack(pack_format) }.should raise_error(TypeError)
+  end
+
+  it "raises a TypeError when the object does not respond to #to_int" do
+    obj = mock('not an integer')
+    lambda { [obj].pack(pack_format) }.should raise_error(TypeError)
+  end
+
+  ruby_version_is '1.9' do
+    it "returns an ASCII-8BIT string" do
+      [0xFF].pack(pack_format).encoding.should == Encoding::ASCII_8BIT
+      [0xE3, 0x81, 0x82].pack(pack_format(3)).encoding.should == Encoding::ASCII_8BIT
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/array/pack/v_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/array/pack/v_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/array/pack/v_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,17 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+require File.expand_path('../shared/basic', __FILE__)
+require File.expand_path('../shared/numeric_basic', __FILE__)
+require File.expand_path('../shared/integer', __FILE__)
+
+describe "Array#pack with format 'V'" do
+  it_behaves_like :array_pack_basic, 'V'
+  it_behaves_like :array_pack_numeric_basic, 'V'
+  it_behaves_like :array_pack_32bit_le, 'V'
+end
+
+describe "Array#pack with format 'v'" do
+  it_behaves_like :array_pack_basic, 'v'
+  it_behaves_like :array_pack_numeric_basic, 'v'
+  it_behaves_like :array_pack_16bit_le, 'v'
+end

Added: MacRuby/trunk/spec/frozen/core/array/repeated_combination_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/array/repeated_combination_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/array/repeated_combination_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,41 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+ruby_version_is "1.9" do
+  describe "Array#repeated_combination" do
+    before :each do
+      @array = [10, 11, 12]
+    end
+
+    it "returns an enumerator when no block is provided" do
+      @array.repeated_combination(2).should be_an_instance_of(enumerator_class)
+    end
+
+    it "returns self when a block is given" do
+      @array.repeated_combination(2){}.should equal(@array)
+    end
+
+    it "yields nothing for negative length and return self" do
+      @array.repeated_combination(-1){ fail }.should equal(@array)
+      @array.repeated_combination(-10){ fail }.should equal(@array)
+    end
+
+    it "yields the expected repeated_combinations" do
+      @array.repeated_combination(2).to_a.sort.should == [[10, 10], [10, 11], [10, 12], [11, 11], [11, 12], [12, 12]]
+      @array.repeated_combination(3).to_a.sort.should == [[10, 10, 10], [10, 10, 11], [10, 10, 12], [10, 11, 11], [10, 11, 12],
+                                                          [10, 12, 12], [11, 11, 11], [11, 11, 12], [11, 12, 12], [12, 12, 12]]
+    end
+
+    it "yields [] when length is 0" do
+      @array.repeated_combination(0).to_a.should == [[]] # one repeated_combination of length 0
+      [].repeated_combination(0).to_a.should == [[]] # one repeated_combination of length 0
+    end
+
+    it "yields nothing when the array is empty and num is non zero" do
+      [].repeated_combination(5).to_a.should == [] # one repeated_combination of length 0
+    end
+
+    it "yields a partition consisting of only singletons" do
+      @array.repeated_combination(1).sort.to_a.should == [[10],[11],[12]]
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/array/repeated_permutation_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/array/repeated_permutation_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/array/repeated_permutation_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,51 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+
+ruby_version_is "1.9" do
+  describe "Array#repeated_permutation" do
+
+    before(:each) do
+      @numbers = [10, 11, 12]
+      @permutations = [[10, 10], [10, 11], [10, 12], [11, 10], [11, 11], [11, 12], [12, 10], [12, 11], [12, 12]]
+    end
+
+    it "returns an Enumerator of all repeated permutations of given length when called without a block" do
+      enum = @numbers.repeated_permutation(2)
+      enum.should be_kind_of(Enumerable)
+      enum.to_a.sort.should == @permutations
+    end
+
+    it "yields all repeated_permutations to the block then returns self when called with block but no arguments" do
+      yielded = []
+      @numbers.repeated_permutation(2) {|n| yielded << n}.should equal(@numbers)
+      yielded.sort.should == @permutations
+    end
+
+    it "yields the empty repeated_permutation ([[]]) when the given length is 0" do
+      @numbers.repeated_permutation(0).to_a.should == [[]]
+      [].repeated_permutation(0).to_a.should == [[]]
+    end
+
+    it "does not yield when called on an empty Array with a nonzero argument" do 
+      [].repeated_permutation(10).to_a.should == []
+    end  
+
+    it "handles duplicate elements correctly" do
+      @numbers[-1] = 10
+      @numbers.repeated_permutation(2).sort.should ==
+        [[10, 10], [10, 10], [10, 10], [10, 10], [10, 11], [10, 11], [11, 10], [11, 10], [11, 11]]
+    end
+
+    it "truncates Float arguments" do 
+      @numbers.repeated_permutation(3.7).to_a.sort.should == 
+        @numbers.repeated_permutation(3).to_a.sort
+    end  
+
+    it "returns an Enumerator which works as expected even when the array was modified" do
+      @numbers.shift
+      enum = @numbers.repeated_permutation(2)
+      @numbers.unshift 10
+      enum.to_a.sort.should == @permutations
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/array/shared/join.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/array/shared/join.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/array/shared/join.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,159 @@
+describe :array_join, :shared => true do
+  it "returns an empty string if the Array is empty" do
+    a = @object.new
+    a.send(@method, ':').should == ''
+  end
+
+  ruby_version_is ""..."1.9" do
+    it "returns a string formed by concatenating each element.to_s separated by separator without trailing separator" do
+      obj = mock('foo')
+      def obj.to_s() 'foo' end
+      @object.new(1, 2, 3, 4, obj).send(@method, ' | ').should == '1 | 2 | 3 | 4 | foo'
+
+      obj = mock('o')
+      class << obj; undef :to_s; end
+      obj.should_receive(:method_missing).with(:to_s).and_return("o")
+      @object.new(1, obj).send(@method, ":").should == "1:o"
+    end
+  end
+
+  ruby_version_is "1.9" do
+    it "returns a string formed by concatenating each element.to_str separated by separator without trailing separator" do
+      obj = mock('foo')
+      def obj.to_s() 'foo' end
+      @object.new(1, 2, 3, 4, obj).send(@method, ' | ').should == '1 | 2 | 3 | 4 | foo'
+
+      obj = mock('o')
+      obj.should_receive(:method_missing).with(:to_str).and_return("o")
+      @object.new(1, obj).send(@method, ":").should == "1:o"
+    end
+  end
+
+  it "raises a NoMethodError if an element does not respond to #to_s" do
+    obj = mock('o')
+    class << obj; undef :to_s; end
+    lambda{ @object.new(1,obj).send(@method, ':') }.should raise_error(NoMethodError)
+  end
+
+  it "uses the same separator with nested arrays" do
+    @object.new(1, @object.new(2, @object.new(3, 4), 5), 6).send(@method, ":").should == "1:2:3:4:5:6"
+    @object.new(1, @object.new(2, ArraySpecs::MyArray[3, 4], 5), 6).send(@method, ":").should == "1:2:3:4:5:6"
+  end
+
+  it "tries to convert the passed separator to a String using #to_str" do
+    obj = mock('::')
+    obj.should_receive(:to_str).and_return("::")
+    @object.new(1, 2, 3, 4).send(@method, obj).should == '1::2::3::4'
+  end
+
+  ruby_version_is ""..."1.9" do
+    # Detail of joining recursive arrays is implementation dependent: [ruby-dev:37021]
+    it "handles recursive arrays" do
+      x = @object.new
+      x << x
+      x.send(@method, ':').should be_kind_of(String)
+
+      x = @object.new("one", "two")
+      x << x
+      str = x.send(@method, '/')
+      str.should include("one/two")
+
+      x << "three"
+      x << "four"
+      str = x.send(@method, '/')
+      str.should include("one/two")
+      str.should include("three/four")
+
+      # nested and recursive
+      x = @object.new(@object.new("one", "two"), @object.new("three", "four"))
+      x << x
+      str = x.send(@method, '/')
+      str.should include("one/two")
+      str.should include("three/four")
+
+      x = @object.new
+      y = @object.new
+      y << 9 << x << 8 << y << 7
+      x << 1 << x << 2 << y << 3
+      # representations when recursing from x
+      # these are here to make it easier to understand what is happening
+      str = x.send(@method, ':')
+      str.should include('1')
+      str.should include('2')
+      str.should include('3')
+    end
+  end
+
+  ruby_version_is "1.9" do
+    it "raises an ArgumentError when the Array is recursive" do
+      x = @object.new
+      x << x
+      lambda { x.send(@method, ':') }.should raise_error(ArgumentError)
+
+      x = @object.new("one", "two")
+      x << x
+      lambda { x.send(@method, '/') }.should raise_error(ArgumentError)
+
+      # nested and recursive
+      x = @object.new(@object.new("one", "two"), @object.new("three", "four"))
+      x << x
+      lambda { x.send(@method, '/') }.should raise_error(ArgumentError)
+    end
+  end
+
+  it "does not consider taint of either the array or the separator when the array is empty" do
+    @object.new.send(@method, ":").tainted?.should == false
+    @object.new.taint.send(@method, ":").tainted?.should == false
+    @object.new.send(@method, ":".taint).tainted?.should == false
+    @object.new.taint.send(@method, ":".taint).tainted?.should == false
+  end
+
+   # This doesn't work for Enumerable#join on 1.9. See bug #1732
+  it "returns a string which would be infected with taint of the array, its elements or the separator when the array is not empty" do
+    @object.new("a", "b").send(@method, ":").tainted?.should == false
+    @object.new("a", "b").send(@method, ":".taint).tainted?.should == true
+    @object.new("a", "b").taint.send(@method, ":").tainted?.should == true
+    @object.new("a", "b").taint.send(@method, ":".taint).tainted?.should == true
+    @object.new("a", "b".taint).send(@method, ":").tainted?.should == true
+    @object.new("a", "b".taint).send(@method, ":".taint).tainted?.should == true
+    @object.new("a", "b".taint).taint.send(@method, ":").tainted?.should == true
+    @object.new("a", "b".taint).taint.send(@method, ":".taint).tainted?.should == true
+    @object.new("a".taint, "b").send(@method, ":").tainted?.should == true
+    @object.new("a".taint, "b").send(@method, ":".taint).tainted?.should == true
+    @object.new("a".taint, "b").taint.send(@method, ":").tainted?.should == true
+    @object.new("a".taint, "b").taint.send(@method, ":".taint).tainted?.should == true
+    @object.new("a".taint, "b".taint).send(@method, ":").tainted?.should == true
+    @object.new("a".taint, "b".taint).send(@method, ":".taint).tainted?.should == true
+    @object.new("a".taint, "b".taint).taint.send(@method, ":").tainted?.should == true
+    @object.new("a".taint, "b".taint).taint.send(@method, ":".taint).tainted?.should == true
+  end
+
+  ruby_version_is '1.9' do
+    it "does not consider untrustworthiness of either the array or the separator when the array is empty" do
+      @object.new.send(@method, ":").untrusted?.should == false
+      @object.new.untrust.send(@method, ":").untrusted?.should == false
+      @object.new.send(@method, ":".untrust).untrusted?.should == false
+      @object.new.untrust.send(@method, ":".untrust).untrusted?.should == false
+    end
+
+    # This doesn't work for Enumerable#join on 1.9. See bug #1732
+    it "returns a string which would be infected with untrustworthiness of the array, its elements or the separator when the array is not empty" do
+      @object.new("a", "b").send(@method, ":").untrusted?.should == false
+      @object.new("a", "b").send(@method, ":".untrust).untrusted?.should == true
+      @object.new("a", "b").untrust.send(@method, ":").untrusted?.should == true
+      @object.new("a", "b").untrust.send(@method, ":".untrust).untrusted?.should == true
+      @object.new("a", "b".untrust).send(@method, ":").untrusted?.should == true
+      @object.new("a", "b".untrust).send(@method, ":".untrust).untrusted?.should == true
+      @object.new("a", "b".untrust).untrust.send(@method, ":").untrusted?.should == true
+      @object.new("a", "b".untrust).untrust.send(@method, ":".untrust).untrusted?.should == true
+      @object.new("a".untrust, "b").send(@method, ":").untrusted?.should == true
+      @object.new("a".untrust, "b").send(@method, ":".untrust).untrusted?.should == true
+      @object.new("a".untrust, "b").untrust.send(@method, ":").untrusted?.should == true
+      @object.new("a".untrust, "b").untrust.send(@method, ":".untrust).untrusted?.should == true
+      @object.new("a".untrust, "b".untrust).send(@method, ":").untrusted?.should == true
+      @object.new("a".untrust, "b".untrust).send(@method, ":".untrust).untrusted?.should == true
+      @object.new("a".untrust, "b".untrust).untrust.send(@method, ":").untrusted?.should == true
+      @object.new("a".untrust, "b".untrust).untrust.send(@method, ":".untrust).untrusted?.should == true
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/dir/initialize_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/dir/initialize_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/dir/initialize_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,29 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../fixtures/common', __FILE__)
+
+describe "Dir#initialize" do
+  before :each do
+    DirSpecs.create_mock_dirs
+  end
+
+  after :each do
+    DirSpecs.delete_mock_dirs
+  end
+
+  ruby_version_is ""..."1.9" do
+    it "calls #to_str on non-String arguments" do
+      p = mock('path')
+      p.stub!(:to_str).and_return(DirSpecs.mock_dir)
+
+      Dir.new(p).path.should == DirSpecs.mock_dir
+    end
+  end
+
+  ruby_version_is "1.9" do
+    it "calls #to_path on non-String arguments" do
+      p = mock('path')
+      p.stub!(:to_path).and_return(DirSpecs.mock_dir)
+      Dir.new(p).path.should == DirSpecs.mock_dir
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/file/fixtures/common.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/file/fixtures/common.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/file/fixtures/common.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,3 @@
+module FileSpecs
+  class SubString < String; end
+end

Added: MacRuby/trunk/spec/frozen/core/io/fixtures/reopen_stdout.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/io/fixtures/reopen_stdout.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/io/fixtures/reopen_stdout.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,3 @@
+STDOUT.reopen ARGV[0]
+system "echo from system"
+exec "echo from exec"

Added: MacRuby/trunk/spec/frozen/core/string/unpack/c_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/string/unpack/c_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/string/unpack/c_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,60 @@
+# -*- encoding: utf-8 -*-
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe :string_unpack_8bit, :shared => true do
+  it "decodes one byte for a single format character" do
+    "abc".unpack(unpack_format()).should == [97]
+  end
+
+  it "decodes two bytes for two format characters" do
+    "abc".unpack(unpack_format(nil, 2)).should == [97, 98]
+  end
+
+  it "decods the number of bytes requested by the count modifier" do
+    "abc".unpack(unpack_format(2)).should == [97, 98]
+  end
+
+  it "decodes the remaining bytes when passed the '*' modifier" do
+    "abc".unpack(unpack_format('*')).should == [97, 98, 99]
+  end
+
+  it "decodes the remaining bytes when passed the '*' modifer after another directive" do
+    "abc".unpack(unpack_format()+unpack_format('*')).should == [97, 98, 99]
+  end
+
+  it "decodes zero bytes when no bytes remain and the '*' modifier is passed" do
+    "abc".unpack(unpack_format('*', 2)).should == [97, 98, 99]
+  end
+
+  it "adds nil for each element requested beyond the end of the String" do
+    [ ["",   [nil, nil, nil]],
+      ["a",  [97, nil, nil]],
+      ["ab", [97, 98, nil]]
+    ].should be_computed_by(:unpack, unpack_format(3))
+  end
+
+  it "ignores NULL bytes between directives" do
+    "abc".unpack(unpack_format("\000", 2)).should == [97, 98]
+  end
+
+  it "ignores spaces between directives" do
+    "abc".unpack(unpack_format(' ', 2)).should == [97, 98]
+  end
+end
+
+describe "String#unpack with format 'C'" do
+  it_behaves_like :string_unpack_8bit, 'C'
+
+  it "decodes a byte with most significant bit set as a positive number" do
+    "\xff\x80\x82".unpack('C*').should == [255, 128, 130]
+  end
+end
+
+describe "String#unpack with format 'c'" do
+  it_behaves_like :string_unpack_8bit, 'c'
+
+  it "decodes a byte with most significant bit set as a negative number" do
+    "\xff\x80\x82".unpack('c*').should == [-1, -128, -126]
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/struct/shared/.equal_value.rb.rej.swp
===================================================================
--- MacRuby/trunk/spec/frozen/core/struct/shared/.equal_value.rb.rej.swp	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/struct/shared/.equal_value.rb.rej.swp	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,13 @@
+b0VIM 7.2      
+\xF8pL\xD2S o eloy                                    monkey-patch-HQ.local                   /Volumes/eloy/code/MacRuby/complete/spec/frozen/core/struct/shared/equal_value.rb.rej                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
+ 3210    #"! U                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 tp           ;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ad  <  D     ;       \xF0  \xE2  \xAF  v  4    \xFB  \xF8  \xBA  \x83  D        \xB0
+  y
+  8
+  
+  \xF9  \xF6  \xCF  s  P      \xC6  \x8A  j  9  6  (  \xF5
+  \xBC
+  s
+  B
+  :
+  7
+  \xF9	  \xBB	  u	  A	  9	  6	  \xE1  \xA3  [  $  
    \xF2  \x96  s  5     \xDB  \x98  x  G  D  C                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         x.send(@method, stepping).should == true         stepping[:make] = stone +       stone = StructClasses::Car.new(stepping, "Accord", "1998") +       stepping = StructClasses::Car.new("Honda", "Accord", "1998")         x[:make] = x +       x = StructClasses::Car.new("Honda", "Accord", "1998")         MyClass = Struct.new(:foo)       it "handles recursive structures by returning false if a difference can be found " do     ruby_bug "redmine #1885", "1.8" do        end       car.send(@method, different_car).should == false +     different_car = StructClasses::Car.new("Honda", "Accord", "1995") +     car = StructClasses::Car.new("Honda", "Accord", "1998")     it "returns false if the other is a different object or has different fields" do        end       car.send(@method, similar_car).should == true +     similar_car = StructClasses::Car.new("Honda", "Accord", "1998") +     car = StructClasses::Car.new("Honda", "Accord", "1998")     it "returns true if the other has all the same fields" do        end       car.send(@method, same_car).should == true +     car = same_car = StructClasses::Car.new("Honda", "Accord", "1998")     it "returns true if the other is the same object" do   describe :struct_equal_value, :shared => true do --- 1,28 ----            x.send(@method, stepping).should == true         stepping[:make] = stone -       stone = Struct::Car.new(stepping, "Accord", "1998") -       stepping = Struct::Car.new("Honda", "Accord", "1998")         x[:make] = x -       x = Struct::Car.new("Honda", "Accord", "1998")         MyClass = Struct.new(:foo)       it "handles recursive structures by returning false if a difference can be found " do     ruby_bug "redmine #1885", "1.8" do        end       car.send(@method, different_car).should == false -     different_car = Struct::Car.new("Honda", "Accord", "1995") -     car = Struct::Car.new("Honda", "Accord", "1998")     it "returns false if the other is a different object or has different fields" do        end       car.send(@method, similar_car).should == true -     similar_car = Struct::Car.new("Honda", "Accord", "1998") -     car = Struct::Car.new("Honda", "Accord", "1998")     it "returns true if the other has all the same fields" do        end       car.send(@method, same_car).should == true -     car = same_car = Struct::Car.new("Honda", "Accord", "1998")     it "returns true if the other is the same object" do   describe :struct_equal_value, :shared => true do *** 1,28 **** *************** 
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/core/struct/shared/.equal_value.rb.swp
===================================================================
--- MacRuby/trunk/spec/frozen/core/struct/shared/.equal_value.rb.swp	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/struct/shared/.equal_value.rb.swp	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,14 @@
+b0VIM 7.2      \xD8\xFBpL*S o eloy                                    monkey-patch-HQ.local                   /Volumes/eloy/code/MacRuby/complete/spec/frozen/core/struct/shared/equal_value.rb                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            utf-8
+ 3210    #"! U                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 tp           !                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ad  >
+  \xDE
+     !       \xCF  \x98  Q  "  
    \xDF  \xA3  _  -  '  &  \xD3
+  \x97
+  Q
+  

+  
+  
+  \xF0  \x97  v  :  '  \xE4  \xA3  \x85  V  U     \xF0
+  \xE8
+  \xE2
+  \xDE
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  end   end     end       x.send(@method, stepping).should == false       stone[:year] = "1999" # introduce a difference        x.send(@method, stepping).should == true       stepping[:make] = stone       stone = StructClasses::Car.new(stepping, "Accord", "1998")       stepping = StructClasses::Car.new("Honda", "Accord", "1998")       x[:make] = x       x = StructClasses::Car.new("Honda", "Accord", "1998")       MyClass = Struct.new(:foo)     it "handles recursive structures by returning false if a difference can be found" do   ruby_bug "redmine #1885", "1.8" do    end     car.send(@method, different_car).should == false     different_car = StructClasses::Car.new("Honda", "Accord", "1995")     car = StructClasses::Car.new("Honda", "Accord", "1998")   it "returns false if the other is a different object or has different fields" do    end     car.send(@method, similar_car).should == true     similar_car = StructClasses::Car.new("Honda", "Accord", "1998")     car = StructClasses::Car.new("Honda", "Accord", "1998")   it "returns true if the other has all the same fields" do    end     car.send(@method, same_car).should == true     car = same_car = StructClasses::Car.new("Honda", "Accord", "1998")   it "returns true if the other is the same object" do describe :struct_equal_value, :shared => true do 
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/language/fixtures/next.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/fixtures/next.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/language/fixtures/next.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,128 @@
+class NextSpecs
+  def self.yielding_method(expected)
+    yield.should == expected
+    :method_return_value
+  end
+
+  def self.yielding
+    yield
+  end
+
+  # The methods below are defined to spec the behavior of the next statement
+  # while specifically isolating whether the statement is in an Iter block or
+  # not. In a normal spec example, the code is always nested inside a block.
+  # Rather than rely on that implicit context in this case, the context is
+  # made explicit because of the interaction of next in a loop nested inside
+  # an Iter block.
+  def self.while_next(arg)
+    x = true
+    while x
+      begin
+        ScratchPad << :begin
+        x = false
+        if arg
+          next 42
+        else
+          next
+        end
+      ensure
+        ScratchPad << :ensure
+      end
+    end
+  end
+
+  def self.while_within_iter(arg)
+    yielding do
+      x = true
+      while x
+        begin
+          ScratchPad << :begin
+          x = false
+          if arg
+            next 42
+          else
+            next
+          end
+        ensure
+          ScratchPad << :ensure
+        end
+      end
+    end
+  end
+
+  def self.until_next(arg)
+    x = false
+    until x
+      begin
+        ScratchPad << :begin
+        x = true
+        if arg
+          next 42
+        else
+          next
+        end
+      ensure
+        ScratchPad << :ensure
+      end
+    end
+  end
+
+  def self.until_within_iter(arg)
+    yielding do
+      x = false
+      until x
+        begin
+          ScratchPad << :begin
+          x = true
+          if arg
+            next 42
+          else
+            next
+          end
+        ensure
+          ScratchPad << :ensure
+        end
+      end
+    end
+  end
+
+  def self.loop_next(arg)
+    x = 1
+    loop do
+      break if x == 2
+
+      begin
+        ScratchPad << :begin
+        x += 1
+        if arg
+          next 42
+        else
+          next
+        end
+      ensure
+        ScratchPad << :ensure
+      end
+    end
+  end
+
+  def self.loop_within_iter(arg)
+    yielding do
+      x = 1
+      loop do
+        break if x == 2
+
+        begin
+          ScratchPad << :begin
+          x += 1
+          if arg
+            next 42
+          else
+            next
+          end
+        ensure
+          ScratchPad << :ensure
+        end
+      end
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegate_class/instance_method_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegate_class/instance_method_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegate_class/instance_method_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,54 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "DelegateClass.instance_method" do
+  before :each do
+    @klass = DelegateSpecs::DelegateClass
+    @obj = @klass.new(DelegateSpecs::Simple.new)
+  end
+
+  it "returns a method object for public instance methods of the delegated class" do
+    m = @klass.instance_method(:pub)
+    m.should be_an_instance_of(UnboundMethod)
+    m.bind(@obj).call.should == :foo
+  end
+
+  ruby_bug "#2496", "1.8" do
+    it "returns a method object for protected instance methods of the delegated class" do
+      m = @klass.instance_method(:prot)
+      m.should be_an_instance_of(UnboundMethod)
+      m.bind(@obj).call.should == :protected
+    end
+  end
+
+  it "raises a NameError for a private instance methods of the delegated class" do
+    lambda {
+      @klass.instance_method(:priv)
+    }.should raise_error(NameError)
+  end
+
+  it "returns a method object for public instance methods of the DelegateClass class" do
+    m = @klass.instance_method(:extra)
+    m.should be_an_instance_of(UnboundMethod)
+    m.bind(@obj).call.should == :cheese
+  end
+
+  it "returns a method object for protected instance methods of the DelegateClass class" do
+    m = @klass.instance_method(:extra_protected)
+    m.should be_an_instance_of(UnboundMethod)
+    m.bind(@obj).call.should == :baz
+  end
+
+  it "returns a method object for private instance methods of the DelegateClass class" do
+    m = @klass.instance_method(:extra_private)
+    m.should be_an_instance_of(UnboundMethod)
+    m.bind(@obj).call.should == :bar
+  end
+
+  it "raises a NameError for an invalid method name" do
+    lambda {
+      @klass.instance_method(:invalid_and_silly_method_name)
+    }.should raise_error(NameError)
+  end
+
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegate_class/instance_methods_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegate_class/instance_methods_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegate_class/instance_methods_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,50 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "DelegateClass.instance_methods" do
+  before :each do
+    @methods = DelegateSpecs::DelegateClass.instance_methods
+  end
+
+  ruby_version_is ""..."1.9" do
+    it "includes all public methods of the delegated class" do
+      @methods.should include "pub"
+    end
+
+    ruby_bug "#2496", "1.8" do
+      it "includes all protected methods of the delegated class" do
+        @methods.should include "prot"
+      end
+    end
+
+    it "includes instance methods of the DelegateClass class" do
+      @methods.should include "extra"
+      @methods.should include "extra_protected"
+    end
+
+    it "does not include private methods" do
+      @methods.should_not include "priv"
+      @methods.should_not include "extra_private"
+    end
+  end
+
+  ruby_version_is "1.9" do
+    it "includes all public methods of the delegated class" do
+      @methods.should include :pub
+    end
+
+    it "includes all protected methods of the delegated class" do
+      @methods.should include :prot
+    end
+
+    it "includes instance methods of the DelegateClass class" do
+      @methods.should include :extra
+      @methods.should include :extra_protected
+    end
+
+    it "does not include private methods" do
+      @methods.should_not include :priv
+      @methods.should_not include :extra_private
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegate_class/private_instance_methods_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegate_class/private_instance_methods_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegate_class/private_instance_methods_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,42 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "DelegateClass.private_instance_methods" do
+  before :each do
+    @methods = DelegateSpecs::DelegateClass.private_instance_methods
+  end
+
+  ruby_version_is ""..."1.9" do
+    it "does not include any instance methods of the delegated class" do
+      @methods.should_not include "pub"
+      @methods.should_not include "prot"
+      @methods.should_not include "priv" # since these are not forwarded...
+    end
+
+    it "includes private instance methods of the DelegateClass class" do
+      @methods.should include "extra_private"
+    end
+
+    it "does not include public or protected instance methods of the DelegateClass class" do
+      @methods.should_not include "extra"
+      @methods.should_not include "extra_protected"
+    end
+  end
+
+  ruby_version_is "1.9" do
+    it "does not include any instance methods of the delegated class" do
+      @methods.should_not include :pub
+      @methods.should_not include :prot
+      @methods.should_not include :priv # since these are not forwarded...
+    end
+
+    it "includes private instance methods of the DelegateClass class" do
+      @methods.should include :extra_private
+    end
+
+    it "does not include public or protected instance methods of the DelegateClass class" do
+      @methods.should_not include :extra
+      @methods.should_not include :extra_protected
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegate_class/protected_instance_methods_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegate_class/protected_instance_methods_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegate_class/protected_instance_methods_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,56 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "DelegateClass.protected_instance_methods" do
+  before :each do
+    @methods = DelegateSpecs::DelegateClass.protected_instance_methods
+  end
+
+  ruby_version_is ""..."1.9" do
+    it "does not include public methods of the delegated class" do
+      @methods.should_not include "pub"
+    end
+
+    ruby_bug "#2496", "1.8" do
+      it "includes the protected methods of the delegated class" do
+        @methods.should include "prot"
+      end
+    end
+
+    it "includes protected instance methods of the DelegateClass class" do
+      @methods.should include "extra_protected"
+    end
+
+    it "does not include public instance methods of the DelegateClass class" do
+      @methods.should_not include "extra"
+    end
+
+    it "does not include private methods" do
+      @methods.should_not include "priv"
+      @methods.should_not include "extra_private"
+    end
+  end
+
+  ruby_version_is "1.9" do
+    it "does not include public methods of the delegated class" do
+      @methods.should_not include :pub
+    end
+
+    it "includes the protected methods of the delegated class" do
+      @methods.should include :prot
+    end
+
+    it "includes protected instance methods of the DelegateClass class" do
+      @methods.should include :extra_protected
+    end
+
+    it "does not include public instance methods of the DelegateClass class" do
+      @methods.should_not include :extra
+    end
+
+    it "does not include private methods" do
+      @methods.should_not include :priv
+      @methods.should_not include :extra_private
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegate_class/public_instance_methods_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegate_class/public_instance_methods_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegate_class/public_instance_methods_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,46 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "DelegateClass.public_instance_methods" do
+  before :each do
+    @methods = DelegateSpecs::DelegateClass.public_instance_methods
+  end
+
+  ruby_version_is ""..."1.9" do
+    it "includes all public methods of the delegated class" do
+      @methods.should include "pub"
+    end
+
+    it "does not include the protected methods of the delegated class" do
+      @methods.should_not include "prot"
+    end
+
+    it "includes public instance methods of the DelegateClass class" do
+      @methods.should include "extra"
+    end
+
+    it "does not include private methods" do
+      @methods.should_not include "priv"
+      @methods.should_not include "extra_private"
+    end
+  end
+
+  ruby_version_is "1.9" do
+    it "includes all public methods of the delegated class" do
+      @methods.should include :pub
+    end
+
+    it "does not include the protected methods of the delegated class" do
+      @methods.should_not include :prot
+    end
+
+    it "includes public instance methods of the DelegateClass class" do
+      @methods.should include :extra
+    end
+
+    it "does not include private methods" do
+      @methods.should_not include :priv
+      @methods.should_not include :extra_private
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/case_compare_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/case_compare_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/case_compare_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,11 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "Delegator#===" do
+  it "is delegated" do
+    base = mock('base')
+    delegator = DelegateSpecs::Delegator.new(base)
+    base.should_receive(:===).with(42).and_return(:foo)
+    (delegator === 42).should == :foo
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/compare_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/compare_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/compare_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,11 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "Delegator#<=>" do
+  it "is delegated" do
+    base = mock('base')
+    delegator = DelegateSpecs::Delegator.new(base)
+    base.should_receive(:<=>).with(42).and_return(1)
+    (delegator <=> 42).should == 1
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/complement_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/complement_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/complement_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,13 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "Delegator#~" do
+  ruby_bug "redmine:2224", "1.8" do
+    it "is delegated" do
+      base = mock('base')
+      delegator = DelegateSpecs::Delegator.new(base)
+      base.should_receive(:~).and_return(:foo)
+      (~delegator).should == :foo
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/eql_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/eql_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/eql_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,13 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "Delegator#eql?" do
+  ruby_bug "redmine:2224", "1.8" do
+    it "is delegated" do
+      base = mock('base')
+      delegator = DelegateSpecs::Delegator.new(base)
+      base.should_receive(:eql?).with(42).and_return(:foo)
+      delegator.eql?(42).should == :foo
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/equal_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/equal_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/equal_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,13 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "Delegator#equal?" do
+  it "returns true only when compared with the delegator" do
+    obj = mock('base')
+    delegator = DelegateSpecs::Delegator.new(obj)
+    obj.should_not_receive(:equal?)
+    delegator.equal?(obj).should be_false
+    delegator.equal?(nil).should be_false
+    delegator.equal?(delegator).should be_true
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/equal_value_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/equal_value_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/equal_value_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,32 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "Delegator#==" do
+  before :each do
+    @base = mock('base')
+    @delegator = DelegateSpecs::Delegator.new(@base)
+  end
+
+  ruby_version_is ""..."1.9" do
+    it "is delegated when passed self" do
+      @base.should_receive(:==).and_return(false)
+      (@delegator == @delegator).should be_false
+    end
+  end
+
+  ruby_version_is "1.9" do
+    it "is not delegated when passed self" do
+      @base.should_not_receive(:==)
+      (@delegator == @delegator).should be_true
+    end
+  end
+  it "is delegated when passed the delegated object" do
+    @base.should_receive(:==).and_return(false)
+    (@delegator == @base).should be_false
+  end
+
+  it "is delegated in general" do
+    @base.should_receive(:==).and_return(true)
+    (@delegator == 42).should be_true
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/frozen_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/frozen_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/frozen_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,49 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "Delegator when frozen" do
+  before :each do
+    @array = [42, :hello]
+    @delegate = DelegateSpecs::Delegator.new(@array)
+    @delegate.freeze
+  end
+
+  it "is still readable" do
+    @delegate.should == [42, :hello]
+    @delegate.include?("bar").should be_false
+  end
+
+  it "is frozen" do
+    @delegate.frozen?.should be_true
+  end
+
+  ruby_bug "redmine:2221", "1.8.7" do
+    it "is not writeable" do
+      lambda{ @delegate[0] += 2 }.should raise_error( RuntimeError )
+    end
+
+    it "creates a frozen clone" do
+      @delegate.clone.frozen?.should be_true
+    end
+  end
+
+  it "creates an unfrozen dup" do
+    @delegate.dup.frozen?.should be_false
+  end
+
+  ruby_version_is "" ... "1.9" do
+    it "causes mutative calls to raise TypeError" do
+      lambda{ @delegate.__setobj__("hola!") }.should raise_error( TypeError )
+    end
+  end
+
+  ruby_version_is "1.9" do
+    it "causes mutative calls to raise RuntimeError" do
+      lambda{ @delegate.__setobj__("hola!") }.should raise_error( RuntimeError )
+    end
+  end
+
+  it "returns false if only the delegated object is frozen" do
+    DelegateSpecs::Delegator.new([1,2,3].freeze).frozen?.should be_false
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/hash_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/hash_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/hash_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,13 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "Delegator#hash" do
+  ruby_bug "redmine:2224", "1.8" do
+    it "is delegated" do
+      base = mock('base')
+      delegator = DelegateSpecs::Delegator.new(base)
+      base.should_receive(:hash).and_return(42)
+      delegator.hash.should == 42
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/marshal_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/marshal_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/marshal_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,23 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require 'delegate'
+
+describe "SimpleDelegator" do
+  before :each do
+    @obj = "hello"
+    @delegate = SimpleDelegator.new(@obj)
+  end
+
+  it "can be marshalled" do
+    m = Marshal.load(Marshal.dump(@delegate))
+    m.class.should == SimpleDelegator
+    (m == @obj).should be_true
+  end
+
+  ruby_bug "redmine:1744", "1.8.7" do
+    it "can be marshalled with its instance variables intact" do
+      @delegate.instance_variable_set(:@foo, "bar")
+      m = Marshal.load(Marshal.dump(@delegate))
+      m.instance_variable_get(:@foo).should == "bar"
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/method_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/method_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/method_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,67 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "Delegator#method" do
+  before :each do
+    @simple = DelegateSpecs::Simple.new
+    @delegate = DelegateSpecs::Delegator.new(@simple)
+  end
+
+  it "returns a method object for public methods of the delegate object" do
+    m = @delegate.method(:pub)
+    m.should be_an_instance_of(Method)
+    m.call.should == :foo
+  end
+
+  it "returns a method object for protected methods of the delegate object" do
+    m = @delegate.method(:prot)
+    m.should be_an_instance_of(Method)
+    m.call.should == :protected
+  end
+
+  it "raises a NameError for a private methods of the delegate object" do
+    lambda {
+      @delegate.method(:priv)
+    }.should raise_error(NameError)
+  end
+
+  it "returns a method object for public methods of the Delegator class" do
+    m = @delegate.method(:extra)
+    m.should be_an_instance_of(Method)
+    m.call.should == :cheese
+  end
+
+  it "returns a method object for protected methods of the Delegator class" do
+    m = @delegate.method(:extra_protected)
+    m.should be_an_instance_of(Method)
+    m.call.should == :baz
+  end
+
+  it "returns a method object for private methods of the Delegator class" do
+    m = @delegate.method(:extra_private)
+    m.should be_an_instance_of(Method)
+    m.call.should == :bar
+  end
+
+  it "raises a NameError for an invalid method name" do
+    lambda {
+      @delegate.method(:invalid_and_silly_method_name)
+    }.should raise_error(NameError)
+  end
+
+  ruby_version_is "1.9" do
+    it "returns a method that respond_to_missing?" do
+      m = @delegate.method(:pub_too)
+      m.should be_an_instance_of(Method)
+      m.call.should == :pub_too
+    end
+  end
+
+  it "raises a NameError if method is no longer valid because object has changed" do
+    m = @delegate.method(:pub)
+    @delegate.__setobj__([1,2,3])
+    lambda {
+      m.call
+    }.should raise_error(NameError)
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/methods_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/methods_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/methods_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,50 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "Delegator#methods" do
+  before :each do
+    @simple = DelegateSpecs::Simple.new
+    @delegate = DelegateSpecs::Delegator.new(@simple)
+    @methods = @delegate.methods
+  end
+
+  ruby_version_is ""..."1.9" do
+    it "includes all public methods of the delegate object" do
+      @methods.should include "pub"
+    end
+
+    it "includes all protected methods of the delegate object" do
+      @methods.should include "prot"
+    end
+
+    it "includes instance methods of the Delegator class" do
+      @methods.should include "extra"
+      @methods.should include "extra_protected"
+    end
+
+    it "does not include private methods" do
+      @methods.should_not include "priv"
+      @methods.should_not include "extra_private"
+    end
+  end
+
+  ruby_version_is "1.9" do
+    it "includes all public methods of the delegate object" do
+      @methods.should include :pub
+    end
+
+    it "includes all protected methods of the delegate object" do
+      @methods.should include :prot
+    end
+
+    it "includes instance methods of the Delegator class" do
+      @methods.should include :extra
+      @methods.should include :extra_protected
+    end
+
+    it "does not include private methods" do
+      @methods.should_not include :priv
+      @methods.should_not include :extra_private
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/not_equal_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/not_equal_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/not_equal_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,26 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+ruby_version_is "1.9" do
+  describe "Delegator#!=" do
+    before :each do
+      @base = mock('base')
+      @delegator = DelegateSpecs::Delegator.new(@base)
+    end
+
+    it "is not delegated when passed self" do
+      @base.should_not_receive(:"!=")
+      (@delegator != @delegator).should be_false
+    end
+
+    it "is delegated when passed the delegated object" do
+      @base.should_receive(:"!=").and_return(true)
+      (@delegator != @base).should be_true
+    end
+
+    it "is delegated in general" do
+      @base.should_receive(:"!=").and_return(false)
+      (@delegator != 42).should be_false
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/not_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/not_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/not_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,13 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+ruby_version_is "1.9" do
+  describe "Delegator#!" do
+    it "is delegated" do
+      base = mock('base')
+      delegator = DelegateSpecs::Delegator.new(base)
+      base.should_receive(:"!").and_return(:foo)
+      (!delegator).should == :foo
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/private_methods_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/private_methods_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/private_methods_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,34 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "Delegator#private_methods" do
+  before :each do
+    @simple = DelegateSpecs::Simple.new
+    @delegate = DelegateSpecs::Delegator.new(@simple)
+    @methods = @delegate.private_methods
+  end
+
+  ruby_version_is ""..."1.9" do
+    it "does not include any method of the delegate object" do # since delegates does not forward private calls
+      @methods.should_not include "priv"
+      @methods.should_not include "prot"
+      @methods.should_not include "pub"
+    end
+
+    it "includes all private instance methods of the Delegate class" do
+      @methods.should include "extra_private"
+    end
+  end
+
+  ruby_version_is "1.9" do
+    it "does not include any method of the delegate object" do # since delegates does not forward private calls
+      @methods.should_not include :priv
+      @methods.should_not include :prot
+      @methods.should_not include :pub
+    end
+
+    it "includes all private instance methods of the Delegate class" do
+      @methods.should include :extra_private
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/protected_methods_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/protected_methods_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/protected_methods_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,32 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "Delegator#protected_methods" do
+  before :each do
+    @simple = DelegateSpecs::Simple.new
+    @delegate = DelegateSpecs::Delegator.new(@simple)
+    @methods = @delegate.protected_methods
+  end
+
+  ruby_version_is ""..."1.9" do
+    ruby_bug "#2496", "1.8" do
+      it "includes protected methods of the delegate object" do
+        @methods.should include "prot"
+      end
+    end
+
+    it "includes protected instance methods of the Delegator class" do
+      @methods.should include "extra_protected"
+    end
+  end
+
+  ruby_version_is "1.9" do
+    it "includes protected methods of the delegate object" do
+      @methods.should include :prot
+    end
+
+    it "includes protected instance methods of the Delegator class" do
+      @methods.should include :extra_protected
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/public_methods_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/public_methods_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/public_methods_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,30 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "Delegator#public_methods" do
+  before :each do
+    @simple = DelegateSpecs::Simple.new
+    @delegate = DelegateSpecs::Delegator.new(@simple)
+    @methods = @delegate.public_methods
+  end
+
+  ruby_version_is ""..."1.9" do
+    it "includes public methods of the delegate object" do
+      @methods.should include "pub"
+    end
+
+    it "includes public instance methods of the Delegator class" do
+      @methods.should include "extra"
+    end
+  end
+
+  ruby_version_is "1.9" do
+    it "includes public methods of the delegate object" do
+      @methods.should include :pub
+    end
+
+    it "includes public instance methods of the Delegator class" do
+      @methods.should include :extra
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/send_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/send_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/send_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,26 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "SimpleDelegator.new" do
+  before :each do
+    @simple = DelegateSpecs::Simple.new
+    @delegate = SimpleDelegator.new(@simple)
+  end
+
+  it "forwards public method calls" do
+    @delegate.pub.should == :foo
+  end
+
+  it "forwards protected method calls" do
+    @delegate.prot.should == :protected
+  end
+
+  it "doesn't forward private method calls" do
+    lambda{ @delegate.priv }.should raise_error( NoMethodError )
+  end
+
+  it "doesn't forward private method calls even via send or __send__" do
+    lambda{ @delegate.send(:priv, 42)     }.should raise_error( NoMethodError )
+    lambda{ @delegate.__send__(:priv, 42) }.should raise_error( NoMethodError )
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/taint_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/taint_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/taint_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,25 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "Delegator#taint" do
+  before :each do
+    @delegate = DelegateSpecs::Delegator.new("")
+  end
+
+  it "returns self" do
+    @delegate.taint.equal?(@delegate).should be_true
+  end
+
+  it "taints the delegator" do
+    @delegate.__setobj__(nil)
+    @delegate.taint
+    @delegate.tainted?.should be_true
+  end
+
+  ruby_bug "redmine:2223", "1.8" do
+    it "taints the delegated object" do
+      @delegate.taint
+      @delegate.__getobj__.tainted?.should be_true
+    end
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/tap_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/tap_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/tap_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+ruby_version_is "1.9" do
+  describe "Delegator#tap" do
+    it "yield the delegator object" do
+      obj = mock('base')
+      delegator = DelegateSpecs::Delegator.new(obj)
+      obj.should_not_receive(:tap)
+      yielded = []
+      delegator.tap do |x|
+        yielded << x
+      end
+      yielded.size.should == 1
+      yielded[0].equal?(delegator).should be_true
+    end
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/trust_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/trust_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/trust_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,26 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+ruby_version_is "1.9" do
+  describe "Delegator#trust" do
+    before :each do
+      @delegate = lambda{$SAFE=4; DelegateSpecs::Delegator.new([])}.call
+    end
+
+    it "returns self" do
+      @delegate.trust.equal?(@delegate).should be_true
+    end
+
+    it "trusts the delegator" do
+      @delegate.trust
+      @delegate.untrusted?.should be_false
+      lambda{$SAFE=4; @delegate.data = :foo }.should raise_error( SecurityError )
+    end
+
+    it "trusts the delegated object" do
+      @delegate.trust
+      @delegate.__getobj__.untrusted?.should be_false
+      lambda{$SAFE=4; @delegate << 42}.should raise_error( SecurityError )
+    end
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/untaint_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/untaint_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/untaint_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,26 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "Delegator#untaint" do
+  before :each do
+    @delegate = lambda{$SAFE=4; DelegateSpecs::Delegator.new("")}.call
+  end
+
+  it "returns self" do
+    @delegate.untaint.equal?(@delegate).should be_true
+  end
+
+  it "untaints the delegator" do
+    @delegate.untaint
+    @delegate.tainted?.should be_false
+    # No additional meaningful test; that it does or not taint
+    # "for real" the delegator has no consequence
+  end
+
+  ruby_bug "redmine:2223", "1.8" do
+    it "untaints the delegated object" do
+      @delegate.untaint
+      @delegate.__getobj__.tainted?.should be_false
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/delegate/delegator/untrust_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/delegate/delegator/untrust_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/delegate/delegator/untrust_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,26 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+ruby_version_is "1.9" do
+  describe "Delegator#untrust" do
+    before :each do
+      @delegate = DelegateSpecs::Delegator.new("")
+    end
+
+    it "returns self" do
+      @delegate.untrust.equal?(@delegate).should be_true
+    end
+
+    it "untrusts the delegator" do
+      @delegate.__setobj__(nil)
+      @delegate.untrust
+      @delegate.untrusted?.should be_true
+      lambda{$SAFE=4; @delegate.data = :foo }.should_not raise_error
+    end
+
+    it "untrusts the delegated object" do
+      @delegate.untrust
+      @delegate.__getobj__.untrusted?.should be_true
+    end
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/set/keep_if_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/set/keep_if_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/set/keep_if_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,40 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require 'set'
+
+ruby_version_is "1.9" do
+  describe "Set#keep_if" do
+    before(:each) do
+      @set = Set["one", "two", "three"]
+    end
+
+    it "yields every element of self" do
+      ret = []
+      @set.keep_if { |x| ret << x }
+      ret.sort.should == ["one", "two", "three"].sort
+    end
+
+    it "keeps every element from self for which the passed block returns true" do
+      @set.keep_if { |x| x.size != 3 }
+      @set.size.should eql(1)
+
+      @set.should_not include("one")
+      @set.should_not include("two")
+      @set.should include("three")
+    end
+
+    it "returns self" do
+      @set.keep_if {}.should equal(@set)
+    end
+
+    it "returns an Enumerator when passed no block" do
+      enum = @set.keep_if
+      enum.should be_an_instance_of(enumerator_class)
+
+      enum.each { |x| x.size != 3 }
+
+      @set.should_not include("one")
+      @set.should_not include("two")
+      @set.should include("three")
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/set/select_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/set/select_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/set/select_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,44 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require 'set'
+
+ruby_version_is "1.9" do
+  describe "Set#select!" do
+    before(:each) do
+      @set = Set["one", "two", "three"]
+    end
+
+    it "yields every element of self" do
+      ret = []
+      @set.select! { |x| ret << x }
+      ret.sort.should == ["one", "two", "three"].sort
+    end
+
+    it "keeps every element from self for which the passed block returns true" do
+      @set.select! { |x| x.size != 3 }
+      @set.size.should eql(1)
+
+      @set.should_not include("one")
+      @set.should_not include("two")
+      @set.should include("three")
+    end
+
+    it "returns self when self was modified" do
+      @set.select! { false }.should equal(@set)
+    end
+
+    it "returns nil when self was not modified" do
+      @set.select! { true }.should be_nil
+    end
+
+    it "returns an Enumerator when passed no block" do
+      enum = @set.select!
+      enum.should be_an_instance_of(enumerator_class)
+
+      enum.each { |x| x.size != 3 }
+
+      @set.should_not include("one")
+      @set.should_not include("two")
+      @set.should include("three")
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/set/sortedset/keep_if_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/set/sortedset/keep_if_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/set/sortedset/keep_if_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,33 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require 'set'
+
+ruby_version_is "1.9" do
+  describe "SortedSet#keep_if" do
+    before(:each) do
+      @set = SortedSet["one", "two", "three"]
+    end
+
+    it "yields each Object in self in sorted order" do
+      ret = []
+      @set.keep_if { |x| ret << x }
+      ret.should == ["one", "two", "three"].sort
+    end
+
+    it "keeps every element from self for which the passed block returns true" do
+      @set.keep_if { |x| x.size != 3 }
+      @set.to_a.should == ["three"]
+    end
+
+    it "returns self" do
+      @set.keep_if {}.should equal(@set)
+    end
+
+    it "returns an Enumerator when passed no block" do
+      enum = @set.keep_if
+      enum.should be_an_instance_of(enumerator_class)
+
+      enum.each { |x| x.size != 3 }
+      @set.to_a.should == ["three"]
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/set/sortedset/select_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/set/sortedset/select_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/set/sortedset/select_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,37 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require 'set'
+
+ruby_version_is "1.9" do
+  describe "SortedSet#select!" do
+    before(:each) do
+      @set = SortedSet["one", "two", "three"]
+    end
+
+    it "yields each Object in self in sorted order" do
+      res = []
+      @set.select! { |x| res << x }
+      res.should == ["one", "two", "three"].sort
+    end
+
+    it "keeps every element from self for which the passed block returns true" do
+      @set.select! { |x| x.size != 3 }
+      @set.to_a.should == ["three"]
+    end
+
+    it "returns self when self was modified" do
+      @set.select! { false }.should equal(@set)
+    end
+
+    it "returns nil when self was not modified" do
+      @set.select! { true }.should be_nil
+    end
+
+    it "returns an Enumerator when passed no block" do
+      enum = @set.select!
+      enum.should be_an_instance_of(enumerator_class)
+
+      enum.each { |x| x.size != 3 }
+      @set.to_a.should == ["three"]
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/socket/unixserver/for_fd_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/socket/unixserver/for_fd_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/socket/unixserver/for_fd_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,33 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe "UNIXServer#for_fd" do
+  before :each do
+    @unix_path = tmp("unix_socket")
+    @unix = UNIXServer.new(@unix_path)
+  end
+
+  after :each do
+    # UG. We can't use the new_fd helper, because we need fds that are
+    # associated with sockets. But for_fd has the same issue as IO#new, it
+    # creates a fd aliasing issue with closing, causing EBADF errors.
+    #
+    # Thusly, the rescue for EBADF here. I'd love a better solution, but
+    # I'm not aware of one.
+
+    begin
+      @unix.close unless @unix.closed?
+    rescue Errno::EBADF
+      # I hate this API too
+    end
+
+    rm_r @unix_path
+  end
+
+  it "can calculate the path" do
+    b = UNIXServer.for_fd(@unix.fileno)
+
+    b.path.should == @unix_path
+    b.close
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/uri/merge_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/uri/merge_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/uri/merge_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,22 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require 'uri'
+
+describe "URI#merge" do
+  it "returns the receiver and the argument, joined as per URI.join" do
+    URI("http://localhost/").merge("main.rbx").should == URI.parse("http://localhost/main.rbx")
+    URI("http://localhost/a/b/c/d").merge("http://ruby-lang.com/foo").should == URI.parse("http://ruby-lang.com/foo")
+    URI("http://localhost/a/b/c/d").merge("../../e/f").to_s.should == "http://localhost/a/e/f"
+  end
+
+  it "accepts URI objects as argument" do
+    URI("http://localhost/").merge(URI("main.rbx")).should == URI.parse("http://localhost/main.rbx")
+  end
+
+  ruby_bug "redmine:3506", "1.9.2" do
+    it "accepts a string-like argument" do
+      str = mock('string-like')
+      str.should_receive(:to_str).and_return("foo/bar")
+      URI("http://localhost/").merge(str).should == URI.parse("http://localhost/foo/bar")
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/uri/route_from_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/uri/route_from_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/uri/route_from_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,25 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require 'uri'
+
+describe "URI#route_from" do
+
+  #this could be split out a good bit better
+  it "gives the minimal difference between the current URI and the target" do
+    URI("http://example.com/a.html").route_from('http://example.com/a.html').to_s.should == ""
+    URI("http://example.com/a.html").route_from('http://example.com/b.html').to_s.should == "a.html"
+    URI("http://example.com/a/").route_from('http://example.com/b/').to_s.should == "../a/"
+    URI("http://example.com/b/").route_from('http://example.com/a/c').to_s.should == "../b/"
+    URI("http://example.com/b/").route_from('http://example.com/a/b/').to_s.should == "../../b/"
+    URI("http://example.com/b/").route_from('http://EXAMPLE.cOm/a/b/').to_s.should == "../../b/"
+    URI("http://example.net/b/").route_from('http://example.com/a/b/').to_s.should == "//example.net/b/"
+    URI("mailto:foo at example.com#bar").route_from('mailto:foo at example.com').to_s.should == "#bar"
+  end
+
+  ruby_bug "redmine:3506", "1.9.2" do
+    it "accepts a string-like argument" do
+      str = mock('string-like')
+      str.should_receive(:to_str).and_return("http://example.com/b.html")
+      URI("http://example.com/a.html").route_from(str).to_s.should == "a.html"
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/uri/route_to_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/uri/route_to_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/uri/route_to_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,28 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require 'uri'
+
+describe "URI#route_to" do
+
+  #this could be split out a good bit better
+  it "gives the minimal difference between the current URI and the target" do
+    URI("http://example.com/a.html").route_to('http://example.com/a.html').to_s.should == ""
+    URI("http://example.com/a.html").route_to('http://example.com/b.html').to_s.should == "b.html"
+    URI("http://example.com/a/").route_to('http://example.com/b/').to_s.should == "../b/"
+    URI("http://example.com/a/c").route_to('http://example.com/b/').to_s.should == "../b/"
+    URI("http://example.com/a/b/").route_to('http://example.com/b/').to_s.should == "../../b/"
+    URI("http://example.com/a/b/").route_to('http://EXAMPLE.cOm/b/').to_s.should == "../../b/"
+    URI("http://example.com/a/b/").route_to('http://example.net/b/').to_s.should == "//example.net/b/"
+    URI("mailto:foo at example.com").route_to('mailto:foo at example.com#bar').to_s.should == "#bar"
+
+    #this was a little surprising to me
+    URI("mailto:foo at example.com#bar").route_to('mailto:foo at example.com').to_s.should == ""
+  end
+
+  ruby_bug "redmine:3506", "1.9.2" do
+    it "accepts a string-like argument" do
+      str = mock('string-like')
+      str.should_receive(:to_str).and_return("http://example.com/b.html")
+      URI("http://example.com/a.html").route_to(str).to_s.should == "b.html"
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/_getproperty_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/_getproperty_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/_getproperty_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,15 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE#_getproperty' do
+    before :each do
+      @ie = WIN32OLE.new 'InternetExplorer.application'
+    end
+    
+    it 'gets name' do
+      @ie._getproperty(0, [], []).should =~ /explorer/i
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/_invoke_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/_invoke_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/_invoke_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,21 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE#_invoke' do
+    before :each do
+      @shell = WIN32OLE.new 'Shell.application'
+    end
+    
+    it 'raises ArgumentError if insufficient number of arguments are given' do
+      lambda { @shell._invoke() }.should raise_error ArgumentError
+      lambda { @shell._invoke(0) }.should raise_error ArgumentError
+      lambda { @shell._invoke(0, []) }.should raise_error ArgumentError
+    end
+    
+    it 'dispatches the method bound to a specific ID' do
+      @shell._invoke(0x60020002, [0], [WIN32OLE::VARIANT::VT_VARIANT]).title.should =~ /Desktop/i
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/_setproperty_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/_setproperty_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/_setproperty_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1 @@
+# TODO: add specs
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/codepage_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/codepage_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/codepage_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,22 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE.codepage' do
+    # default value is influenced by Encoding.default_external in 1.9
+    ruby_version_is ""..."1.9" do
+      it 'returns the current codepage' do
+        WIN32OLE.codepage.should == WIN32OLE::CP_ACP
+      end
+    end
+  end
+
+  describe 'WIN32OLE.codepage=' do
+    it 'sets codepage' do
+      cp = WIN32OLE.codepage
+      WIN32OLE.codepage = WIN32OLE::CP_UTF8
+      WIN32OLE.codepage.should == WIN32OLE::CP_UTF8
+      WIN32OLE.codepage = cp
+    end
+  end
+
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/connect_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/connect_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/connect_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,15 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE.connect' do    
+    it 'creates WIN32OLE object given valid argument' do
+      obj = WIN32OLE.connect("winmgmts:")
+      obj.should be_kind_of WIN32OLE
+    end
+    
+    it 'raises TypeError when given invalid argument' do
+      lambda { WIN32OLE.connect 1 }.should raise_error TypeError
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/const_load_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/const_load_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/const_load_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,32 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE.const_load when passed Shell.Application OLE object' do
+    before :each do
+      @win32ole = WIN32OLE.new 'Shell.Application'
+    end
+    
+    it 'loads constant SsfWINDOWS into WIN32OLE namespace' do
+      WIN32OLE.const_defined?(:SsfWINDOWS).should be_false
+      WIN32OLE.const_load @win32ole
+      WIN32OLE.const_defined?(:SsfWINDOWS).should be_true
+    end
+  end
+  
+  describe 'WIN32OLE.const_load when namespace is specified' do
+    before :each do
+      module WIN32OLE_RUBYSPEC; end
+      @win32ole = WIN32OLE.new 'Shell.Application'
+    end
+    
+    it 'loads constants into given namespace' do
+      module WIN32OLE_RUBYSPEC; end
+      
+      WIN32OLE_RUBYSPEC.const_defined?(:SsfWINDOWS).should be_false
+      WIN32OLE.const_load @win32ole, WIN32OLE_RUBYSPEC
+      WIN32OLE_RUBYSPEC.const_defined?(:SsfWINDOWS).should be_true
+      
+    end
+  end
+
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/constants_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/constants_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/constants_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,50 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe "WIN32OLE class" do
+    it 'defines constant CP_ACP' do
+      WIN32OLE::CP_ACP.should == 0
+    end
+
+    it 'defines constant CP_OEMCP' do
+      WIN32OLE::CP_OEMCP.should == 1
+    end
+
+    it 'defines constant CP_MACCP' do
+      WIN32OLE::CP_MACCP.should == 2
+    end
+
+    it 'defines constant CP_THREAD_ACP' do
+      WIN32OLE::CP_THREAD_ACP.should == 3
+    end
+
+    it 'defines constant CP_SYMBOL' do
+      WIN32OLE::CP_SYMBOL.should == 42
+    end
+
+    it 'defines constant CP_UTF7' do
+      WIN32OLE::CP_UTF7.should == 65000
+    end
+
+    it 'defines constant CP_UTF8' do
+      WIN32OLE::CP_UTF8.should == 65001
+    end
+    
+    # 1.8 only constants
+    ruby_version_is ""..."1.9" do
+      # there are none
+    end
+
+    # 1.9 only constants
+    ruby_version_is "1.9" do
+      it 'defines constant LOCALE_SYSTEM_DEFAULT' do
+        WIN32OLE::LOCALE_SYSTEM_DEFAULT.should == 0x0800
+      end
+
+      it 'defines constant LOCALE_USER_DEFAULT' do
+        WIN32OLE::LOCALE_USER_DEFAULT.should == 0x0400
+      end
+    end
+  end
+
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/create_guid_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/create_guid_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/create_guid_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,11 @@
+platform_is :windows do
+  require 'win32ole'
+
+  ruby_version_is "1.9" do
+    describe 'WIN32OLE.create_guid' do    
+      it 'generates guid with valid format' do
+        WIN32OLE.create_guid.should =~ /^\{[A-Z0-9]{8}\-[A-Z0-9]{4}\-[A-Z0-9]{4}\-[A-Z0-9]{4}\-[A-Z0-9]{12}/
+      end
+    end
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/each_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/each_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/each_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1 @@
+# TODO: add WIN32OLE.each specs
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/invoke_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/invoke_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/invoke_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,13 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE#invoke' do    
+    before :each do
+      @ie = WIN32OLE.new 'InternetExplorer.application'
+    end
+    
+    it 'get name by invoking "Name" OLE method' do
+      @ie.invoke('Name').should =~ /explorer/i
+    end
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/locale_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/locale_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/locale_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,32 @@
+platform_is :windows do
+  require 'win32ole'
+
+  ruby_version_is "1.9" do
+    describe 'WIN32OLE.locale' do    
+      it 'gets locale' do
+        WIN32OLE.locale.should == WIN32OLE::LOCALE_SYSTEM_DEFAULT
+      end
+    end
+
+    describe 'WIN32OLE.locale=' do
+      it 'sets locale to Japanese, if available' do
+        begin
+          begin
+            WIN32OLE.locale = 1041
+          rescue WIN32OLERuntimeError
+            STDERR.puts("\n#{__FILE__}:#{__LINE__}:#{self.class.name}.test_s_locale_set is skipped(Japanese locale is not installed)")
+            return
+          end
+
+          WIN32OLE.locale.should == 1041
+          WIN32OLE.locale = WIN32OLE::LOCALE_SYSTEM_DEFAULT
+          lambda { WIN32OLE.locale = 111 }.should raise_error WIN32OLERuntimeError
+          WIN32OLE.locale.should == WIN32OLE::LOCALE_SYSTEM_DEFAULT
+        ensure
+          WIN32OLE.locale.should == WIN32OLE::LOCALE_SYSTEM_DEFAULT
+        end        
+      end
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/new_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/new_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/new_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,26 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE.new' do
+    it 'creates a WIN32OLE object from OLE server name' do
+      shell = WIN32OLE.new 'Shell.Application'
+      shell.should be_kind_of WIN32OLE
+      shell = nil
+    end
+    
+    it 'creates a WIN32OLE object from valid CLSID' do
+      shell = WIN32OLE.new("{13709620-C279-11CE-A49E-444553540000}")
+      shell.should be_kind_of WIN32OLE
+    end
+    
+    it 'raises TypeError if argument cannot be converted to String' do
+      lambda { WIN32OLE.new(42) }.should raise_error( TypeError )
+    end
+    
+    it 'raises WIN32OLERuntimeError if invalid string is given' do
+      lambda { WIN32OLE.new('foo') }.should raise_error( WIN32OLERuntimeError )
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_func_methods_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_func_methods_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_func_methods_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,23 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE#ole_func_methods' do
+    before :each do
+      @ie = WIN32OLE.new 'InternetExplorer.application'
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @ie.ole_func_methods(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns an array of WIN32OLE_METHODs' do
+      @ie.ole_func_methods.all? { |m| m.kind_of? WIN32OLE_METHOD }.should be_true
+    end
+    
+    it 'contains a "AddRef" method for Internet Explorer' do
+      @ie.ole_func_methods.map { |m| m.name }.include?('AddRef').should be_true
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_get_methods_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_get_methods_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_get_methods_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,15 @@
+platform_is :windows do
+  
+  describe "WIN32OLE#ole_get_methods" do
+    
+    before :each do
+      @win32ole = WIN32OLE.new('Shell.Application')
+    end
+    
+    it "returns an array of WIN32OLE_METHOD objects" do
+      @win32ole.ole_get_methods.all? {|m| m.kind_of? WIN32OLE_METHOD}.should be_true
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_method_help_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_method_help_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_method_help_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,11 @@
+require File.expand_path('../shared/ole_method', __FILE__)
+
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE#ole_method_help' do
+    it_behaves_like :win32ole_ole_method, :ole_method_help
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_method_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_method_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_method_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,11 @@
+require File.expand_path('../shared/ole_method', __FILE__)
+
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE#ole_method' do
+    it_behaves_like :win32ole_ole_method, :ole_method
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_methods_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_methods_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_methods_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,23 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE#ole_methods' do
+    before :each do
+      @ie = WIN32OLE.new 'InternetExplorer.application'
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @ie.ole_methods(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns an array of WIN32OLE_METHODs' do
+      @ie.ole_methods.all? { |m| m.kind_of? WIN32OLE_METHOD }.should be_true
+    end
+    
+    it 'contains a "AddRef" method for Internet Explorer' do
+      @ie.ole_methods.map { |m| m.name }.include?('AddRef').should be_true
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_obj_help_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_obj_help_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_obj_help_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,19 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE#ole_obj_help' do
+    before :each do
+      @ie = WIN32OLE.new 'InternetExplorer.application'
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @ie.ole_obj_help(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns an instance of WIN32OLE_TYPE' do
+      @ie.ole_obj_help.kind_of?(WIN32OLE_TYPE).should be_true
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_put_methods_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_put_methods_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_put_methods_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,23 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE#ole_put_methods' do
+    before :each do
+      @ie = WIN32OLE.new 'InternetExplorer.application'
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @ie.ole_put_methods(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns an array of WIN32OLE_METHODs' do
+      @ie.ole_put_methods.all? { |m| m.kind_of? WIN32OLE_METHOD }.should be_true
+    end
+    
+    it 'contains a "Height" method for Internet Explorer' do
+      @ie.ole_put_methods.map { |m| m.name }.include?('Height').should be_true
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_show_help_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_show_help_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/ole_show_help_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,6 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE.ole_show_help' do    
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/setproperty_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/setproperty_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/setproperty_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,11 @@
+require File.expand_path('../shared/setproperty', __FILE__)
+
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE#setproperty' do
+    it_behaves_like :win32ole_setproperty, :setproperty
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/shared/ole_method.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/shared/ole_method.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/shared/ole_method.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,21 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe :win32ole_ole_method, :shared => true do
+    before :each do
+      @ie = WIN32OLE.new("InternetExplorer.application")
+    end
+    
+    it 'raises ArgumentError if no argument is given' do
+      lambda { @ie.send(@method) }.should raise_error ArgumentError
+    end
+    
+    it 'returns the WIN32OLE_METHOD "Quit" if given "Quit"' do
+      result = @ie.send(@method, "Quit")
+      result.kind_of?(WIN32OLE_METHOD).should be_true
+      result.name.should == 'Quit'
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole/shared/setproperty.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole/shared/setproperty.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole/shared/setproperty.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,24 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe :win32ole_setproperty, :shared => true do
+    before :each do
+      @ie = WIN32OLE.new("InternetExplorer.application")
+    end
+    
+    it 'raises ArgumentError if no argument is given' do
+      lambda { @ie.send(@method) }.should raise_error ArgumentError
+    end
+    
+    it 'sets height to 500 and returns nil' do
+      height = 500
+      result = @ie.send(@method, 'Height', height)
+      result.should == nil
+      ruby_version_is ""..."1.9" do # 1.9 does not support collection for WIN32OLE objects
+        @ie['Height'].should == height
+      end
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/handler_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/handler_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/handler_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,31 @@
+platform_is :windows do
+  require 'win32ole'
+
+  # TODO: need specs here
+  ruby_version_is "1.9" do
+    describe 'WIN32OLE_EVENT#handler' do
+      before :each do
+        @ole = WIN32OLE.new('InternetExplorer.Application')
+        @event = ''
+      end
+
+      after :each do
+        @ole = nil
+      end
+
+    end
+    
+    describe 'WIN32OLE_EVENT#handler=' do
+      before :each do
+        @ole = WIN32OLE.new('InternetExplorer.Application')
+        @event = ''
+      end
+
+      after :each do
+        @ole = nil
+      end
+
+    end
+    
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/message_loop_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/message_loop_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/message_loop_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,11 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  # not sure how we should test this
+  describe 'WIN32OLE_EVENT.message_loop' do
+    it 'exists' do
+      lambda { WIN32OLE_EVENT.message_loop }.should_not raise_error NoMethodError
+    end
+  end
+
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/new_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/new_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/new_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,36 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_EVENT.new' do
+    before :each do
+      @ole = WIN32OLE.new('InternetExplorer.Application')
+      @event = ''
+    end
+
+    after :each do
+      @ole = nil
+    end
+
+    it 'raises TypeError given invalid argument' do
+      lambda { WIN32OLE_EVENT.new "A" }.should raise_error TypeError
+    end
+
+    it 'raises RuntimeError if event does not exist' do
+      lambda { WIN32OLE_EVENT.new(@ole, 'A') }.should raise_error RuntimeError
+    end
+
+    ruby_bug "#3576","1.8" do
+      it 'raises RuntimeError if OLE object has no events' do
+        dict = WIN32OLE.new('Scripting.Dictionary')
+        lambda { WIN32OLE_EVENT.new(dict) }.should raise_error RuntimeError
+      end
+    end
+
+    it 'creates WIN32OLE_EVENT object' do
+      ev = WIN32OLE_EVENT.new(@ole, 'DWebBrowserEvents')
+      ev.should be_kind_of WIN32OLE_EVENT
+    end
+
+  end
+
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/off_event_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/off_event_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/off_event_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,17 @@
+platform_is :windows do
+  require 'win32ole'
+
+  ruby_version_is "1.9" do
+    describe 'WIN32OLE_EVENT#off_event' do
+      before :each do
+        @ole = WIN32OLE.new('InternetExplorer.Application')
+        @event = ''
+      end
+
+      after :each do
+        @ole = nil
+      end
+
+    end
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/on_event_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/on_event_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/on_event_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,65 @@
+platform_is :windows do
+  require 'win32ole'
+
+  def default_handler(event, *args)
+    @event += event
+  end
+  
+  def alternate_handler(event, *args)
+    @event2 = "alternate"
+  end
+  
+  def handler3(event, *args)
+    @event3 += event
+  end
+
+
+  describe 'WIN32OLE_EVENT#on_event with no argument' do
+    before :each do
+      @ole    = WIN32OLE.new('InternetExplorer.Application')
+      @ev     = WIN32OLE_EVENT.new(@ole, 'DWebBrowserEvents')
+      @event  = ''
+      @event2 = ''
+      @event3 = ''
+    end
+
+    after :each do
+      @ole = nil
+    end
+
+    it 'sets event handler properly, and the handler is invoked by event loop' do
+      @ev.on_event { |*args| default_handler(*args) }
+      @ole.StatusText='hello'
+      WIN32OLE_EVENT.message_loop
+      @event.should =~ /StatusTextChange/
+    end
+
+    it 'accepts a String argument, sets event handler properly, and the handler is invoked by event loop' do
+      @ev.on_event("StatusTextChange") { |*args| @event = 'foo' }
+      @ole.StatusText='hello'
+      WIN32OLE_EVENT.message_loop
+      @event.should =~ /foo/
+    end
+    
+    it 'registers multiple event handlers for the same event' do
+      @ev.on_event("StatusTextChange") { |*args| default_handler(*args) }
+      @ev.on_event("StatusTextChange") { |*args| alternate_handler(*args) }
+      @ole.StatusText= 'hello'
+      WIN32OLE_EVENT.message_loop
+      @event2.should == 'alternate'
+    end
+
+    ruby_version_is "1.9" do
+
+      it 'accepts a Symbol argument, sets event handler properly, and the handler is invoked by event loop' do
+        @ev.on_event(:StatusTextChange) { |*args| @event = 'foo' }
+        @ole.StatusText='hello'
+        WIN32OLE_EVENT.message_loop
+        @event.should =~ /foo/
+      end
+
+    end
+
+  end
+
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/on_event_with_outargs_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/on_event_with_outargs_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/on_event_with_outargs_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,8 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_EVENT#on_event_with_outargs' do
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/unadvise_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/unadvise_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_event/unadvise_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,17 @@
+platform_is :windows do
+  require 'win32ole'
+
+  ruby_version_is "1.9" do
+    describe 'WIN32OLE_EVENT#unadvise' do
+      before :each do
+        @ole = WIN32OLE.new('InternetExplorer.Application')
+        @event = ''
+      end
+
+      after :each do
+        @ole = nil
+      end
+
+    end
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/dispid_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/dispid_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/dispid_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,20 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#dispid' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+      @m = WIN32OLE_METHOD.new(ole_type, "namespace")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @m.dispid(0) }.should raise_error ArgumentError
+    end
+    
+    it 'returns expected dispatch ID for Shell\'s namespace method' do
+      @m.dispid.should == 1610743810 # value found in MRI's test
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/event_interface_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/event_interface_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/event_interface_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,26 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#event_interface' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Internet Controls", "WebBrowser")
+      @navigate_method = WIN32OLE_METHOD.new(ole_type, "NavigateComplete")
+      ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+      @namespace_method = WIN32OLE_METHOD.new(ole_type, "namespace")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @navigate_method.event_interface(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns expected string for browser\'s "NavigateComplete" method' do
+      @navigate_method.event_interface.should == "DWebBrowserEvents"
+    end
+    
+    it 'returns nil if method has no event interface' do
+      @namespace_method.event_interface.should be_nil
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/event_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/event_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/event_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,20 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#event?' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Internet Controls", "WebBrowser")
+      @navigate_method = WIN32OLE_METHOD.new(ole_type, "NavigateComplete")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @navigate_method.event?(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns true for browser\'s "NavigateComplete" method' do
+      @navigate_method.event?.should be_true
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/helpcontext_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/helpcontext_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/helpcontext_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,26 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#helpcontext' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Internet Controls", "WebBrowser")
+      @navigate_method = WIN32OLE_METHOD.new(ole_type, "NavigateComplete")
+      ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "File")
+      @m_file_name = WIN32OLE_METHOD.new(ole_type, "name")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @navigate_method.helpcontext(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns expected value for browser\'s "NavigateComplete" method' do
+      @navigate_method.helpcontext.should == 0
+    end
+    
+    it 'returns expected value for Scripting Runtime\'s "name" method' do
+      @m_file_name.helpcontext.should == 2181996 # value indicated in MRI's test
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/helpfile_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/helpfile_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/helpfile_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,20 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#helpfile' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "File")
+      @m_file_name = WIN32OLE_METHOD.new(ole_type, "name")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @m_file_name.helpfile(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns expected value for Scripting Runtime\'s "File" method' do
+      @m_file_name.helpfile.should =~ /VBENLR.*\.CHM$/i
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/helpstring_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/helpstring_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/helpstring_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,20 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#helpstring' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "File")
+      @m_file_name = WIN32OLE_METHOD.new(ole_type, "name")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @m_file_name.helpstring(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns expected value for Scripting Runtime\'s "File" method' do
+      @m_file_name.helpstring.should == "Get name of file" # value indicated in MRI's test
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/invkind_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/invkind_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/invkind_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,20 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#invkind' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "File")
+      @m_file_name = WIN32OLE_METHOD.new(ole_type, "name")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @m_file_name.invkind(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns expected value for Scripting Runtime\'s "name" method' do
+      @m_file_name.invkind.should == 2
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/invoke_kind_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/invoke_kind_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/invoke_kind_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,20 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#invoke_kind' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "File")
+      @m_file_name = WIN32OLE_METHOD.new(ole_type, "name")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @m_file_name.invoke_kind(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns expected value for Scripting Runtime\'s "name" method' do
+      @m_file_name.invoke_kind.should =~ /^(UNKNOWN|PROPERTY|PROPERTYGET|PROPERTYPUT|PROPERTYPUTREF|FUNC)$/
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/name_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/name_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/name_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,11 @@
+require File.expand_path('../shared/name', __FILE__)
+
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#name' do
+    it_behaves_like :win32ole_method_name, :name
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/new_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/new_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/new_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,33 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD.new' do
+    before :each do
+      @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+    end
+    
+    it 'raises TypeError when given non-strings' do
+      lambda { WIN32OLE_METHOD.new(1, 2) }.should raise_error TypeError
+    end
+    
+    it 'raises ArgumentError if only 1 arugment is given' do
+      lambda { WIN32OLE_METHOD.new("hello") }.should raise_error ArgumentError
+      lambda { WIN32OLE_METHOD.new(@ole_type) }.should raise_error ArgumentError
+    end
+    
+    it 'returns a valid WIN32OLE_METHOD object' do
+      WIN32OLE_METHOD.new(@ole_type, "Open").should be_kind_of WIN32OLE_METHOD
+      WIN32OLE_METHOD.new(@ole_type, "open").should be_kind_of WIN32OLE_METHOD
+    end
+    
+    it 'raises WIN32OLERuntimeError if the method does not exist' do
+      lambda { WIN32OLE_METHOD.new(@ole_type, "NonexistentMethod") }.should raise_error WIN32OLERuntimeError
+    end
+    
+    it 'raises TypeError if second argument is not a String' do
+      lambda { WIN32OLE_METHOD.new(@ole_type, 5) }.should raise_error TypeError
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/offset_vtbl_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/offset_vtbl_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/offset_vtbl_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,20 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#offset_vtbl' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "File")
+      @m_file_name = WIN32OLE_METHOD.new(ole_type, "name")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @m_file_name.offset_vtbl(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns expected value for Scripting Runtime\'s "name" method' do
+      @m_file_name.offset_vtbl.should == 32
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/params_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/params_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/params_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,28 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#params' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "File")
+      @m_file_name = WIN32OLE_METHOD.new(ole_type, "name")
+      ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+      @m_browse_for_folder = WIN32OLE_METHOD.new(ole_type, "BrowseForFolder")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @m_file_name.params(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns empty array for Scripting Runtime\'s "name" method' do
+      @m_file_name.params.should be_kind_of Array
+      @m_file_name.params.should be_empty
+    end
+    
+    it 'returns 4-element array of WIN32OLE_PARAM for Shell\'s "BrowseForFolder" method' do
+      @m_browse_for_folder.params.all? { |p| p.kind_of? WIN32OLE_PARAM }.should be_true
+      @m_browse_for_folder.params.size == 4
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/return_type_detail_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/return_type_detail_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/return_type_detail_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,21 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#return_type_detail' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+      @m_browse_for_folder = WIN32OLE_METHOD.new(ole_type, "BrowseForFolder")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @m_browse_for_folder.return_type_detail(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns expected value for Shell Control\'s "BrowseForFolder" method' do
+      @m_browse_for_folder.return_type_detail.should be_kind_of Array
+      @m_browse_for_folder.return_type_detail.should == ['PTR', 'USERDEFINED', 'Folder']
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/return_type_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/return_type_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/return_type_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,20 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#return_type' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "File")
+      @m_file_name = WIN32OLE_METHOD.new(ole_type, "name")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @m_file_name.return_type(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns expected value for Scripting Runtime\'s "name" method' do
+      @m_file_name.return_type.should == 'BSTR'
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/return_vtype_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/return_vtype_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/return_vtype_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,20 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#return_vtype' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+      @m_browse_for_folder = WIN32OLE_METHOD.new(ole_type, "BrowseForFolder")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @m_browse_for_folder.return_vtype(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns expected value for Shell Control\'s "BrowseForFolder" method' do
+      @m_browse_for_folder.return_vtype.should == 26
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/shared/name.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/shared/name.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/shared/name.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,20 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe :win32ole_method_name, :shared => true do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "File")
+      @m_file_name = WIN32OLE_METHOD.new(ole_type, "name")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @m_file_name.send(@method, 1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns expected value for Scripting Runtime\'s "name" method' do
+      @m_file_name.send(@method).should == 'Name' # note the capitalization
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/size_opt_params_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/size_opt_params_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/size_opt_params_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,20 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#size_opt_params' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+      @m_browse_for_folder = WIN32OLE_METHOD.new(ole_type, "BrowseForFolder")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @m_browse_for_folder.size_opt_params(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns expected value for Shell Control\'s "BrowseForFolder" method' do
+      @m_browse_for_folder.size_opt_params.should == 1
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/size_params_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/size_params_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/size_params_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,20 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#size_params' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+      @m_browse_for_folder = WIN32OLE_METHOD.new(ole_type, "BrowseForFolder")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @m_browse_for_folder.size_params(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns expected value for Shell Control\'s "BrowseForFolder" method' do
+      @m_browse_for_folder.size_params.should == 4
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/to_s_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/to_s_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/to_s_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,11 @@
+require File.expand_path('../shared/name', __FILE__)
+
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#name' do
+    it_behaves_like :win32ole_method_name, :to_s
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/visible_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/visible_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_method/visible_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,20 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_METHOD#visible?' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+      @m_browse_for_folder = WIN32OLE_METHOD.new(ole_type, "BrowseForFolder")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @m_browse_for_folder.visible?(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns true for Shell Control\'s "BrowseForFolder" method' do
+      @m_browse_for_folder.visible?.should be_true
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/default_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/default_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/default_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,31 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_PARAM#default' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+      m_browse_for_folder = WIN32OLE_METHOD.new(ole_type, "BrowseForFolder")
+      @params = m_browse_for_folder.params
+      
+      ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "FileSystemObject")
+      m_copyfile = WIN32OLE_METHOD.new(ole_type, "CopyFile")
+      @param_overwritefiles = m_copyfile.params[2]
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @params[0].default(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns nil for each of WIN32OLE_PARAM for Shell\'s "BrowseForFolder" method' do
+      @params.each do |p|
+        p.default.should be_nil
+      end
+    end
+    
+    it 'returns true for 3rd parameter of FileSystemObject\'s "CopyFile" method' do
+      @param_overwritefiles.default.should == true # not be_true
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/input_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/input_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/input_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,21 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_PARAM#input?' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "FileSystemObject")
+      m_copyfile = WIN32OLE_METHOD.new(ole_type, "CopyFile")
+      @param_overwritefiles = m_copyfile.params[2]
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @param_overwritefiles.input?(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns true for 3rd parameter of FileSystemObject\'s "CopyFile" method' do
+      @param_overwritefiles.input?.should == true
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/name_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/name_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/name_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,11 @@
+require File.expand_path('../shared/name', __FILE__)
+
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_PARAM#name' do
+    it_behaves_like :win32ole_param_name, :name
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/ole_type_detail_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/ole_type_detail_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/ole_type_detail_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,21 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_PARAM#ole_type_detail' do
+    before :each do
+      ole_type_detail = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "FileSystemObject")
+      m_copyfile = WIN32OLE_METHOD.new(ole_type_detail, "CopyFile")
+      @param_overwritefiles = m_copyfile.params[2]
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @param_overwritefiles.ole_type_detail(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns ["BOOL"] for 3rd parameter of FileSystemObject\'s "CopyFile" method' do
+      @param_overwritefiles.ole_type_detail.should == ['BOOL']
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/ole_type_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/ole_type_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/ole_type_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,21 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_PARAM#ole_type' do
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "FileSystemObject")
+      m_copyfile = WIN32OLE_METHOD.new(ole_type, "CopyFile")
+      @param_overwritefiles = m_copyfile.params[2]
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @param_overwritefiles.ole_type(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns "BOOL" for 3rd parameter of FileSystemObject\'s "CopyFile" method' do
+      @param_overwritefiles.ole_type.should == 'BOOL'
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/optional_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/optional_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/optional_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,21 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_PARAM#optional?' do
+    before :each do
+      ole_type_detail = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "FileSystemObject")
+      m_copyfile = WIN32OLE_METHOD.new(ole_type_detail, "CopyFile")
+      @param_overwritefiles = m_copyfile.params[2]
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @param_overwritefiles.optional?(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns true for 3rd parameter of FileSystemObject\'s "CopyFile" method' do
+      @param_overwritefiles.optional?.should be_true
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/retval_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/retval_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/retval_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,21 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_PARAM#retval?' do
+    before :each do
+      ole_type_detail = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "FileSystemObject")
+      m_copyfile = WIN32OLE_METHOD.new(ole_type_detail, "CopyFile")
+      @param_overwritefiles = m_copyfile.params[2]
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @param_overwritefiles.retval?(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns false for 3rd parameter of FileSystemObject\'s "CopyFile" method' do
+      @param_overwritefiles.retval?.should be_false
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/shared/name.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/shared/name.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/shared/name.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,21 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe :win32ole_param_name, :shared => true do
+    before :each do
+      ole_type_detail = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "FileSystemObject")
+      m_copyfile = WIN32OLE_METHOD.new(ole_type_detail, "CopyFile")
+      @param_overwritefiles = m_copyfile.params[2]
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @param_overwritefiles.send(@method, 1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns expected value for Scripting Runtime\'s "name" method' do
+      @param_overwritefiles.send(@method).should == 'OverWriteFiles' # note the capitalization
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/to_s_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/to_s_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_param/to_s_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,11 @@
+require File.expand_path('../shared/name', __FILE__)
+
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_PARAM#to_s' do
+    it_behaves_like :win32ole_param_name, :to_s
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/guid_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/guid_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/guid_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_TYPE#guid for Shell Controls' do
+    before :each do
+      @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+    end
+
+    after :each do
+      @ole_type = nil
+    end
+
+    it 'returns String with expected format' do
+      @ole_type.guid.should =~ /\A\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\}\z/
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/helpcontext_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/helpcontext_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/helpcontext_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_TYPE#helpcontext for Shell Controls' do
+    before :each do
+      @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+    end
+
+    after :each do
+      @ole_type = nil
+    end
+
+    it 'returns an Integer' do
+      @ole_type.helpcontext.should be_kind_of Integer
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/helpfile_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/helpfile_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/helpfile_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_TYPE#helpfile for Shell Controls' do
+    before :each do
+      @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+    end
+
+    after :each do
+      @ole_type = nil
+    end
+
+    it 'returns an empty string' do
+      @ole_type.helpfile.should be_empty
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/helpstring_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/helpstring_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/helpstring_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_TYPE#helpstring for Shell Controls' do
+    before :each do
+      @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+    end
+
+    after :each do
+      @ole_type = nil
+    end
+
+    it 'returns expected string' do
+      @ole_type.helpstring.should == "Shell Object Type Information"
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/major_version_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/major_version_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/major_version_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_TYPE#major_version for Shell Controls' do
+    before :each do
+      @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+    end
+
+    after :each do
+      @ole_type = nil
+    end
+
+    it 'returns an Integer' do
+      @ole_type.major_version.should be_kind_of Integer
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/minor_version_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/minor_version_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/minor_version_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_TYPE#minor_version for Shell Controls' do
+    before :each do
+      @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+    end
+
+    after :each do
+      @ole_type = nil
+    end
+
+    it 'returns an Integer' do
+      @ole_type.minor_version.should be_kind_of Integer
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/name_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/name_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/name_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,11 @@
+require File.expand_path('../shared/name', __FILE__)
+
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_TYPE#name' do
+    it_behaves_like :win32ole_type_name, :name
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/new_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/new_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/new_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,39 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_TYPE.new' do
+    it 'raises ArgumentError with no argument' do
+      lambda { WIN32OLE_TYPE.new }.should raise_error ArgumentError
+    end
+
+    it 'raises ArgumentError with invalid string' do
+      lambda { WIN32OLE_TYPE.new("foo") }.should raise_error ArgumentError
+    end
+
+    it 'raises TypeError if second argument is not a String' do
+      lambda { WIN32OLE_TYPE.new(1,2) }.should raise_error TypeError
+      lambda { WIN32OLE_TYPE.new('Microsoft Shell Controls And Automation',2) }.
+      should raise_error TypeError
+    end
+
+    it 'raise WIN32OLERuntimeError if OLE object specified is not found' do
+      lambda { WIN32OLE_TYPE.new('Microsoft Shell Controls And Automation','foo') }.
+      should raise_error WIN32OLERuntimeError
+      lambda { WIN32OLE_TYPE.new('Microsoft Shell Controls And Automation','Application') }.
+      should raise_error WIN32OLERuntimeError
+    end
+
+    it 'creates WIN32OLE_TYPE object from name and valid type' do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+      ole_type.should be_kind_of WIN32OLE_TYPE
+    end
+
+    ruby_version_is "1.9" do
+      it 'creates WIN32OLE_TYPE object from CLSID and valid type' do
+        ole_type2 = WIN32OLE_TYPE.new("{13709620-C279-11CE-A49E-444553540000}", "Shell")
+        ole_type2.should be_kind_of WIN32OLE_TYPE
+      end
+    end
+
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/ole_classes_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/ole_classes_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/ole_classes_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_TYPE.ole_classes for Shell Controls' do
+    before :each do
+      @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+    end
+
+    after :each do
+      @ole_type = nil
+    end
+
+    it 'returns array of WIN32OLE_TYPEs' do
+      WIN32OLE_TYPE.ole_classes("Microsoft Shell Controls And Automation").all? {|e| e.kind_of? WIN32OLE_TYPE }.should be_true
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/ole_methods_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/ole_methods_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/ole_methods_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_TYPE#ole_methods for Shell Controls' do
+    before :each do
+      @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+    end
+
+    after :each do
+      @ole_type = nil
+    end
+
+    it 'returns an Integer' do
+      @ole_type.ole_methods.all? { |m| m.kind_of? WIN32OLE_METHOD }.should be_true
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/ole_type_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/ole_type_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/ole_type_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_TYPE#ole_type for Shell Controls' do
+    before :each do
+      @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+    end
+
+    after :each do
+      @ole_type = nil
+    end
+
+    it 'returns string "Class"' do
+      @ole_type.ole_type.should == "Class"
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/progid_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/progid_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/progid_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_TYPE#progid for Shell Controls' do
+    before :each do
+      @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+    end
+
+    after :each do
+      @ole_type = nil
+    end
+
+    it 'returns expected string' do
+      @ole_type.progid.should == "Shell.Application.1"
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/progids_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/progids_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/progids_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,14 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_TYPE.progids' do
+    it 'raises ArgumentError if an argument is given' do
+      lambda { WIN32OLE_TYPE.progids(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns an array containing "Shell.Explorer"' do
+      WIN32OLE_TYPE.progids().include?('Shell.Explorer').should be_true
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/shared/name.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/shared/name.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/shared/name.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,19 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe :win32ole_type_name, :shared => true do
+    before :each do
+      @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "ShellSpecialFolderConstants")
+    end
+    
+    it 'raises ArgumentError if argument is given' do
+      lambda { @ole_type.send(@method, 1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns a String' do
+      @ole_type.send(@method).should == 'ShellSpecialFolderConstants'
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/src_type_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/src_type_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/src_type_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_TYPE#src_type for Shell Controls' do
+    before :each do
+      @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+    end
+
+    after :each do
+      @ole_type = nil
+    end
+
+    it 'returns nil' do
+      @ole_type.src_type.should be_nil
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/to_s_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/to_s_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/to_s_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,11 @@
+require File.expand_path('../shared/name', __FILE__)
+
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_TYPE#to_s' do
+    it_behaves_like :win32ole_type_name, :to_s
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/typekind_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/typekind_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/typekind_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_TYPE#typekind for Shell Controls' do
+    before :each do
+      @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+    end
+
+    after :each do
+      @ole_type = nil
+    end
+
+    it 'returns an Integer' do
+      @ole_type.typekind.should be_kind_of Integer
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/typelibs_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/typelibs_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/typelibs_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,22 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_TYPE.typelibs for Shell Controls' do
+    before :each do
+      @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+    end
+
+    after :each do
+      @ole_type = nil
+    end
+    
+    it 'raises ArgumentError if any argument is give' do
+      lambda { WIN32OLE_TYPE.typelibs(1) }.should raise_error ArgumentError
+    end
+    
+    it 'returns array of type libraries' do
+      WIN32OLE_TYPE.typelibs().include?("Microsoft Shell Controls And Automation").should be_true
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/variables_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/variables_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/variables_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_TYPE#variables for Shell Controls' do
+    before :each do
+      @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+    end
+
+    after :each do
+      @ole_type = nil
+    end
+
+    it 'returns an empty array' do
+      @ole_type.variables.should == []
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/visible_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/visible_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_type/visible_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+
+  describe 'WIN32OLE_TYPE#visible? for Shell Controls' do
+    before :each do
+      @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+    end
+
+    after :each do
+      @ole_type = nil
+    end
+
+    it 'returns true' do
+      @ole_type.visible?.should be_true
+    end
+
+  end
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/name_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/name_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/name_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,11 @@
+require File.expand_path('../shared/name', __FILE__)
+
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_VARIABLE#name' do
+    it_behaves_like :win32ole_variable_new, :name
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/ole_type_detail_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/ole_type_detail_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/ole_type_detail_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,19 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_VARIABLE#ole_type_detail' do
+    # not sure how WIN32OLE_VARIABLE objects are supposed to be generated
+    # WIN32OLE_VARIABLE.new even seg faults in some cases
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "ShellSpecialFolderConstants")
+      @var = ole_type.variables[0]
+    end
+    
+    it 'returns a nonempty Array' do
+      @var.ole_type_detail.should be_kind_of Array
+      @var.ole_type_detail.should_not be_empty
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/ole_type_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/ole_type_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/ole_type_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_VARIABLE#ole_type' do
+    # not sure how WIN32OLE_VARIABLE objects are supposed to be generated
+    # WIN32OLE_VARIABLE.new even seg faults in some cases
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "ShellSpecialFolderConstants")
+      @var = ole_type.variables[0]
+    end
+    
+    it 'returns a String' do
+      @var.ole_type.should be_kind_of String
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/shared/name.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/shared/name.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/shared/name.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe :win32ole_variable_new, :shared => true do
+    # not sure how WIN32OLE_VARIABLE objects are supposed to be generated
+    # WIN32OLE_VARIABLE.new even seg faults in some cases
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "ShellSpecialFolderConstants")
+      @var = ole_type.variables[0]
+    end
+    
+    it 'returns a String' do
+      @var.send(@method).should be_kind_of String
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/to_s_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/to_s_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/to_s_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,11 @@
+require File.expand_path('../shared/name', __FILE__)
+
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_VARIABLE#to_s' do
+    it_behaves_like :win32ole_variable_new, :to_s
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/value_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/value_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/value_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,19 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_VARIABLE#value' do
+    # not sure how WIN32OLE_VARIABLE objects are supposed to be generated
+    # WIN32OLE_VARIABLE.new even seg faults in some cases
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "ShellSpecialFolderConstants")
+      @var = ole_type.variables[0]
+    end
+    
+    it 'returns a Integer' do
+      # according to doc, this could return nil
+      @var.value.should be_kind_of Integer
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/variable_kind_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/variable_kind_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/variable_kind_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,19 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_VARIABLE#variable_kind' do
+    # not sure how WIN32OLE_VARIABLE objects are supposed to be generated
+    # WIN32OLE_VARIABLE.new even seg faults in some cases
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "ShellSpecialFolderConstants")
+      @var = ole_type.variables[0]
+    end
+    
+    it 'returns a String' do
+      @var.variable_kind.should be_kind_of String
+      @var.variable_kind.should == 'CONSTANT'
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/varkind_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/varkind_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/varkind_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_VARIABLE#varkind' do
+    # not sure how WIN32OLE_VARIABLE objects are supposed to be generated
+    # WIN32OLE_VARIABLE.new even seg faults in some cases
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "ShellSpecialFolderConstants")
+      @var = ole_type.variables[0]
+    end
+    
+    it 'returns an Integer' do
+      @var.varkind.should be_kind_of Integer
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/visible_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/visible_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/win32ole/win32ole_variable/visible_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+platform_is :windows do
+  require 'win32ole'
+  
+  describe 'WIN32OLE_VARIABLE#visible?' do
+    # not sure how WIN32OLE_VARIABLE objects are supposed to be generated
+    # WIN32OLE_VARIABLE.new even seg faults in some cases
+    before :each do
+      ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "ShellSpecialFolderConstants")
+      @var = ole_type.variables[0]
+    end
+    
+    it 'returns a String' do
+      @var.visible?.should be_true
+    end
+    
+  end
+  
+end
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/optional/capi/README
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/README	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/README	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,16 @@
+C-API Specs
+
+These specs test the C-API from Ruby. The following are conventions for the
+specs:
+
+1.  Put specs for functions related to a Ruby class in a file named according
+    to the class. For example, for rb_ary_new function, put the specs in
+    optional/capi/array_spec.rb
+2.  Put the C file containing the C functions for array_spec.rb in
+    optional/capi/ext/array_spec.c
+3.  Add a '#define HAVE_RB_ARY_NEW  1' to rubyspec.h
+4.  Name the C extension class 'CApiArraySpecs'.
+5.  Name the C functions 'array_spec_rb_ary_new'.
+6.  Wrap the code in the optional/capi/ext/array_spec.c in
+    '#ifdef HAVE_RB_ARY_NEW'
+6.  Attach the C function to the class using the name 'rb_ary_new'

Added: MacRuby/trunk/spec/frozen/optional/capi/array_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/array_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/array_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,260 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("array")
+
+describe "C-API Array function" do
+  before :each do
+    @s = CApiArraySpecs.new
+  end
+
+  describe "rb_ary_new" do
+    it "returns an empty array" do
+      @s.rb_ary_new.should == []
+    end
+  end
+
+  describe "rb_ary_new2" do
+    it "returns an empty array" do
+      @s.rb_ary_new2(5).should == []
+    end
+  end
+
+  describe "rb_ary_push" do
+    it "adds an element to the array" do
+      @s.rb_ary_push([], 4).should == [4]
+    end
+  end
+
+  describe "rb_ary_pop" do
+    it "removes and returns the last element in the array" do
+      a = [1,2,3]
+      @s.rb_ary_pop(a).should == 3
+      a.should == [1,2]
+    end
+  end
+
+  describe "rb_ary_join" do
+    it "joins elements of an array with a string" do
+      a = [1,2,3]
+      b = ","
+      @s.rb_ary_join(a,b).should == "1,2,3"
+    end
+  end
+
+  describe "rb_ary_reverse" do
+    it "reverses the order of elements in the array" do
+      a = [1,2,3]
+      @s.rb_ary_reverse(a).should == [3,2,1]
+    end
+  end
+
+  describe "rb_ary_entry" do
+    it "returns nil when passed an empty array" do
+      @s.rb_ary_entry([], 0).should == nil
+    end
+
+    it "returns elements from the end when passed a negative index" do
+      @s.rb_ary_entry([1, 2, 3], -1).should == 3
+      @s.rb_ary_entry([1, 2, 3], -2).should == 2
+    end
+
+    it "returns nil if the index is out of range" do
+      @s.rb_ary_entry([1, 2, 3], 3).should == nil
+      @s.rb_ary_entry([1, 2, 3], -10).should == nil
+    end
+  end
+
+  describe "rb_ary_clear" do
+    it "removes all elements from the array" do
+      @s.rb_ary_clear([]).should == []
+      @s.rb_ary_clear([1, 2, 3]).should == []
+    end
+  end
+
+  describe "rb_ary_dup" do
+    it "duplicates the array" do
+      @s.rb_ary_dup([]).should == []
+
+      a = [1, 2, 3]
+      b = @s.rb_ary_dup(a)
+
+      b.should == a
+      b.should_not equal(a)
+    end
+  end
+
+  describe "rb_ary_unshift" do
+    it "prepends the element to the array" do
+      a = [1, 2, 3]
+      @s.rb_ary_unshift(a, "a").should == ["a", 1, 2, 3]
+      a.should == ['a', 1, 2, 3]
+    end
+  end
+
+  describe "rb_ary_shift" do
+    it "removes and returns the first element" do
+      a = [5, 1, 1, 5, 4]
+      @s.rb_ary_shift(a).should == 5
+      a.should == [1, 1, 5, 4]
+    end
+
+    it "returns nil when the array is empty" do
+      @s.rb_ary_shift([]).should == nil
+    end
+  end
+
+  describe "rb_ary_store" do
+    it "overwrites the element at the given position" do
+      a = [1, 2, 3]
+      @s.rb_ary_store(a, 1, 5)
+      a.should == [1, 5, 3]
+    end
+
+    it "writes to elements offset from the end if passed a negative index" do
+      a = [1, 2, 3]
+      @s.rb_ary_store(a, -1, 5)
+      a.should == [1, 2, 5]
+    end
+
+    it "raises on IndexError if the negative index is greater than the length" do
+      a = [1, 2, 3]
+
+      lambda { @s.rb_ary_store(a, -10, 5) }.should raise_error(IndexError)
+    end
+
+    it "enlarges the array as needed" do
+      a = []
+      @s.rb_ary_store(a, 2, 7)
+      a.should == [nil, nil, 7]
+    end
+  end
+
+  ruby_version_is ""..."1.9" do
+    describe "RARRAY" do
+      it "returns a struct with a pointer to a C array of the array's elements" do
+        a = [1, 2, 3]
+        b = []
+        @s.RARRAY_ptr_iterate(a) do |e|
+          b << e
+        end
+        a.should == b
+      end
+
+      it "allows assigning to the elements of the C array" do
+        a = [1, 2, 3]
+        @s.RARRAY_ptr_assign(a, :nasty)
+        a.should == [:nasty, :nasty, :nasty]
+      end
+
+      it "allows changing the array and calling an rb_ary_xxx function" do
+        a = [1, 2, 3]
+        @s.RARRAY_ptr_assign_call(a)
+        a.should == [1, 5, 7, 9]
+      end
+
+      it "allows changing the array and calling a method via rb_funcall" do
+        a = [1, 2, 3]
+        @s.RARRAY_ptr_assign_funcall(a)
+        a.should == [1, 1, 2, 3]
+      end
+
+      it "returns a struct with the length of the array" do
+        @s.RARRAY_len([1, 2, 3]).should == 3
+      end
+    end
+  end
+
+  describe "RARRAY_PTR" do
+    it "returns a pointer to a C array of the array's elements" do
+      a = [1, 2, 3]
+      b = []
+      @s.RARRAY_PTR_iterate(a) do |e|
+        b << e
+      end
+      a.should == b
+    end
+
+    it "allows assigning to the elements of the C array" do
+      a = [1, 2, 3]
+      @s.RARRAY_PTR_assign(a, :set)
+      a.should == [:set, :set, :set]
+    end
+  end
+
+  describe "RARRAY_LEN" do
+    it "returns the size of the array" do
+      @s.RARRAY_LEN([1, 2, 3]).should == 3
+    end
+  end
+
+  describe "rb_assoc_new" do
+    it "returns an array containing the two elements" do
+      @s.rb_assoc_new(1, 2).should == [1, 2]
+      @s.rb_assoc_new(:h, [:a, :b]).should == [:h, [:a, :b]]
+    end
+  end
+
+  describe "rb_ary_includes" do
+    it "returns true if the array includes the element" do
+      @s.rb_ary_includes([1, 2, 3], 2).should be_true
+    end
+
+    it "returns false if the array does not include the element" do
+      @s.rb_ary_includes([1, 2, 3], 4).should be_false
+    end
+  end
+
+  describe "rb_ary_aref" do
+    it "returns the element at the given index" do
+      @s.rb_ary_aref([:me, :you], 0).should == :me
+      @s.rb_ary_aref([:me, :you], 1).should == :you
+    end
+
+    it "returns nil for an out of range index" do
+      @s.rb_ary_aref([1, 2, 3], 6).should be_nil
+    end
+
+    it "returns a new array where the first argument is the index and the second is the length" do
+      @s.rb_ary_aref([1, 2, 3, 4], 0, 2).should == [1, 2]
+      @s.rb_ary_aref([1, 2, 3, 4], -4, 3).should == [1, 2, 3]
+    end
+
+    it "accepts a range" do
+      @s.rb_ary_aref([1, 2, 3, 4], 0..-1).should == [1, 2, 3, 4]
+    end
+
+    it "returns nil when the start of a range is out of bounds" do
+      @s.rb_ary_aref([1, 2, 3, 4], 6..10).should be_nil
+    end
+
+    it "returns an empty array when the start of a range equals the last element" do
+      @s.rb_ary_aref([1, 2, 3, 4], 4..10).should == []
+    end
+  end
+
+  describe "rb_iterate" do
+    it "calls an callback function as a block passed to an method" do
+      s = [1,2,3,4]
+      s2 = @s.rb_iterate(s)
+
+      s2.should == s
+
+      # Make sure they're different objects
+      s2.equal?(s).should be_false
+    end
+  end
+
+  describe "rb_ary_delete" do
+    it "removes an element from an array and returns it" do
+      ary = [1, 2, 3, 4]
+      @s.rb_ary_delete(ary, 3).should == 3
+      ary.should == [1, 2, 4]
+    end
+
+    it "returns nil if the element is not in the array" do
+      ary = [1, 2, 3, 4]
+      @s.rb_ary_delete(ary, 5).should be_nil
+      ary.should == [1, 2, 3, 4]
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/bignum_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/bignum_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/bignum_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,91 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("bignum")
+
+def ensure_bignum(n)
+  0xffff_ffff_ffff_ffff_ffff.coerce(n)[0]
+end
+
+describe "CApiBignumSpecs" do
+  before :each do
+    @s = CApiBignumSpecs.new
+    @max_long = ensure_bignum(2**(0.size * 8 - 1) - 1)
+    @min_long = ensure_bignum(- at max_long - 1)
+    @max_ulong = ensure_bignum(2**(0.size * 8) - 1)
+  end
+
+  describe "rb_big2long" do
+    it "converts a Bignum" do
+      @s.rb_big2long(@max_long).should == @max_long
+      @s.rb_big2long(@min_long).should == @min_long
+      @s.rb_big2long(ensure_bignum(0)).should == 0
+    end
+
+    it "raises RangeError if passed Bignum overflow long" do
+      lambda { @s.rb_big2long(ensure_bignum(@max_long + 1)) }.should raise_error(RangeError)
+      lambda { @s.rb_big2long(ensure_bignum(@min_long - 1)) }.should raise_error(RangeError)
+    end
+  end
+
+  describe "rb_big2ll" do
+    it "converts a Bignum" do
+      @s.rb_big2ll(@max_long).should == @max_long
+      @s.rb_big2ll(@min_long).should == @min_long
+      @s.rb_big2ll(ensure_bignum(0)).should == 0
+    end
+
+    it "raises RangeError if passed Bignum overflow long" do
+      lambda { @s.rb_big2ll(ensure_bignum(@max_long << 40)) }.should raise_error(RangeError)
+      lambda { @s.rb_big2ll(ensure_bignum(@min_long << 40)) }.should raise_error(RangeError)
+    end
+  end
+
+  describe "rb_big2ulong" do
+    it "converts a Bignum" do
+      @s.rb_big2ulong(@max_ulong).should == @max_ulong
+      @s.rb_big2long(ensure_bignum(0)).should == 0
+    end
+
+    it "wraps around if passed a negative bignum" do
+      @s.rb_big2ulong(ensure_bignum(-1)).should == @max_ulong
+      @s.rb_big2ulong(ensure_bignum(@min_long + 1)).should == -(@min_long - 1)
+    end
+
+    it "raises RangeError if passed Bignum overflow long" do
+      lambda { @s.rb_big2ulong(ensure_bignum(@max_ulong + 1)) }.should raise_error(RangeError)
+      lambda { @s.rb_big2ulong(ensure_bignum(@min_long)) }.should raise_error(RangeError)
+    end
+  end
+
+  describe "rb_big2dbl" do
+    it "converts a Bignum to a double value" do
+      @s.rb_big2dbl(ensure_bignum(1)).eql?(1.0).should == true
+      @s.rb_big2dbl(ensure_bignum(Float::MAX.to_i)).eql?(Float::MAX).should == true
+    end
+
+    it "returns Infinity if the number is too big for a double" do
+      huge_bignum = ensure_bignum(Float::MAX.to_i * 2)
+      @s.rb_big2dbl(huge_bignum).should == infinity_value
+    end
+
+    ruby_bug "#3362", "1.8.7.249" do
+      it "returns -Infinity if the number is negative and too big for a double" do
+        huge_bignum = -ensure_bignum(Float::MAX.to_i * 2)
+        @s.rb_big2dbl(huge_bignum).should == -infinity_value
+      end
+    end
+  end
+
+  describe "rb_big2str" do
+
+    it "converts a Bignum to a string with base 10" do
+      @s.rb_big2str(ensure_bignum(1), 10).eql?("1").should == true
+      @s.rb_big2str(ensure_bignum(4611686018427387904), 10).eql?("4611686018427387904").should == true
+    end
+
+    it "converts a Bignum to a string with a different base" do
+      @s.rb_big2str(ensure_bignum(1), 16).eql?("1").should == true
+      @s.rb_big2str(ensure_bignum(4611686018427387904), 16).eql?("4000000000000000").should == true
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/class_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/class_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/class_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,238 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("class")
+
+class CApiClassSpecs
+  module M
+    def included?
+      true
+    end
+  end
+
+  class IncludesM
+  end
+
+  class Alloc
+    attr_reader :initialized
+    attr_reader :arguments
+
+    def initialize(*args)
+      @initialized = true
+      @arguments   = args
+    end
+  end
+
+  class Attr
+    def initialize
+      @foo, @bar, @baz = 1, 2, 3
+    end
+  end
+
+  class CVars
+    @@cvar  = :cvar
+    @c_ivar = :c_ivar
+
+    def new_cv
+      @@new_cv if defined? @@new_cv
+    end
+
+    def new_cvar
+      @@new_cvar if defined? @@new_cvar
+    end
+
+    def rbdcv_cvar
+      @@rbdcv_cvar if defined? @@rbdcv_cvar
+    end
+  end
+
+  class Inherited
+    def self.inherited(klass)
+      klass
+    end
+  end
+
+  class NewClass
+    def self.inherited(klass)
+      raise "#{name}.inherited called"
+    end
+  end
+
+  class Super
+    def call_super_method
+      :super_method
+    end
+  end
+
+  class Sub < Super
+    def call_super_method
+      :subclass_method
+    end
+  end
+end
+
+describe "C-API Class function" do
+  before :each do
+    @s = CApiClassSpecs.new
+  end
+
+  describe "rb_class_new_instance" do
+    it "allocates and initializes a new object" do
+      o = @s.rb_class_new_instance(0, nil, CApiClassSpecs::Alloc)
+      o.class.should == CApiClassSpecs::Alloc
+      o.initialized.should be_true
+    end
+
+    it "passes arguments to the #initialize method" do
+      o = @s.rb_class_new_instance(2, [:one, :two], CApiClassSpecs::Alloc)
+      o.arguments.should == [:one, :two]
+    end
+  end
+
+  describe "rb_include_module" do
+    it "includes a module into a class" do
+      o = CApiClassSpecs::IncludesM.new
+      lambda { o.included? }.should raise_error(NameError)
+      @s.rb_include_module(CApiClassSpecs::IncludesM, CApiClassSpecs::M)
+      o.included?.should be_true
+    end
+  end
+
+  describe "rb_define_attr" do
+    before :each do
+      @a = CApiClassSpecs::Attr.new
+    end
+
+    it "defines an attr_reader when passed true, false" do
+      @s.rb_define_attr(CApiClassSpecs::Attr, :foo, true, false)
+      @a.foo.should == 1
+      lambda { @a.foo = 5 }.should raise_error(NameError)
+    end
+
+    it "defines an attr_writer when passed false, true" do
+      @s.rb_define_attr(CApiClassSpecs::Attr, :bar, false, true)
+      lambda { @a.bar }.should raise_error(NameError)
+      @a.bar = 5
+      @a.instance_variable_get(:@bar).should == 5
+    end
+
+    it "defines an attr_accessor when passed true, true" do
+      @s.rb_define_attr(CApiClassSpecs::Attr, :baz, true, true)
+      @a.baz.should == 3
+      @a.baz = 6
+      @a.baz.should == 6
+    end
+  end
+
+  describe "rb_call_super" do
+    it "calls the method in the superclass" do
+      @s.define_call_super_method CApiClassSpecs::Sub, "call_super_method"
+      obj = CApiClassSpecs::Sub.new
+      obj.call_super_method.should == :super_method
+    end
+  end
+
+  describe "rb_class2name" do
+    it "returns the class name" do
+      @s.rb_class2name(CApiClassSpecs).should == "CApiClassSpecs"
+    end
+  end
+
+  describe "rb_cvar_defined" do
+    it "returns false when the class variable is not defined" do
+      @s.rb_cvar_defined(CApiClassSpecs::CVars, "@@nocvar").should be_false
+    end
+
+    it "returns true when the class variable is defined" do
+      @s.rb_cvar_defined(CApiClassSpecs::CVars, "@@cvar").should be_true
+    end
+
+    it "returns true if the class instance variable is defined" do
+      @s.rb_cvar_defined(CApiClassSpecs::CVars, "@c_ivar").should be_true
+    end
+  end
+
+  describe "rb_cv_set" do
+    it "sets a class variable" do
+      o = CApiClassSpecs::CVars.new
+      o.new_cv.should be_nil
+      @s.rb_cv_set(CApiClassSpecs::CVars, "@@new_cv", 1)
+      o.new_cv.should == 1
+    end
+  end
+
+  describe "rb_cv_get" do
+    it "returns the value of the class variable" do
+      @s.rb_cvar_get(CApiClassSpecs::CVars, "@@cvar").should == :cvar
+    end
+
+    it "raises a NameError if the class variable is not defined" do
+      lambda {
+        @s.rb_cv_get(CApiClassSpecs::CVars, "@@no_cvar")
+      }.should raise_error(NameError)
+    end
+  end
+
+  describe "rb_cvar_set" do
+    it "sets a class variable" do
+      o = CApiClassSpecs::CVars.new
+      o.new_cvar.should be_nil
+      @s.rb_cvar_set(CApiClassSpecs::CVars, "@@new_cvar", 1)
+      o.new_cvar.should == 1
+    end
+    
+  end
+  
+  describe "rb_define_class_variable" do
+    it "sets a class variable" do 
+      o = CApiClassSpecs::CVars.new
+      o.rbdcv_cvar.should be_nil
+      @s.rb_define_class_variable(CApiClassSpecs::CVars, "@@rbdcv_cvar", 1)
+      o.rbdcv_cvar.should == 1
+    end
+  end
+
+  describe "rb_cvar_get" do
+    it "returns the value of the class variable" do
+      @s.rb_cvar_get(CApiClassSpecs::CVars, "@@cvar").should == :cvar
+    end
+
+    it "raises a NameError if the class variable is not defined" do
+      lambda {
+        @s.rb_cvar_get(CApiClassSpecs::CVars, "@@no_cvar")
+      }.should raise_error(NameError)
+    end
+  end
+
+  describe "rb_class_inherited" do
+    before :each do
+      @subclass = Class.new
+    end
+
+    it "calls superclass.inherited(subclass)" do
+      @s.rb_class_inherited(CApiClassSpecs::Inherited, @subclass).should equal(@subclass)
+    end
+
+    it "calls Object.inherited(subclass) if superclass is C NULL" do
+      Object.should_receive(:inherited).with(@subclass)
+
+      # Pass false to have the specs helper C function pass NULL
+      @s.rb_class_inherited(false, @subclass)
+    end
+  end
+
+  describe "rb_class_new" do
+    it "returns an new subclass of the superclass" do
+      subclass = @s.rb_class_new(CApiClassSpecs::NewClass)
+      CApiClassSpecs::NewClass.should be_ancestor_of(subclass)
+    end
+
+    it "raises a TypeError if passed Class as the superclass" do
+      lambda { @s.rb_class_new(Class) }.should raise_error(TypeError)
+    end
+
+    it "raises a TypeError if passed a singleton class as the superclass" do
+      metaclass = Object.new.metaclass
+      lambda { @s.rb_class_new(metaclass) }.should raise_error(TypeError)
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/constants_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/constants_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/constants_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,235 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("constants")
+
+describe "C-API constant" do
+  before :each do
+    @s = CApiConstantsSpecs.new
+  end
+
+  specify "rb_cArray references the Array class" do
+    @s.rb_cArray.should == Array
+  end
+
+  specify "rb_cBignum references the Bignum class" do
+    @s.rb_cBignum.should == Bignum
+  end
+
+  specify "rb_cClass references the Class class" do
+    @s.rb_cClass.should == Class
+  end
+
+  specify "rb_mComparable references the Comparable module" do
+    @s.rb_mComparable.should == Comparable
+  end
+
+  specify "rb_cData references the Data class" do
+    @s.rb_cData.should == Data
+  end
+
+  specify "rb_mEnumerable references the Enumerable module" do
+    @s.rb_mEnumerable.should == Enumerable
+  end
+
+  specify "rb_cFalseClass references the FalseClass class" do
+    @s.rb_cFalseClass.should == FalseClass
+  end
+
+  specify "rb_cFile references the File class" do
+    @s.rb_cFile.should == File
+  end
+
+  specify "rb_cFixnum references the Fixnum class" do
+    @s.rb_cFixnum.should == Fixnum
+  end
+
+  specify "rb_cFloat references the Float class" do
+    @s.rb_cFloat.should == Float
+  end
+
+  specify "rb_cHash references the Hash class" do
+    @s.rb_cHash.should == Hash
+  end
+
+  specify "rb_cInteger references the Integer class" do
+    @s.rb_cInteger.should == Integer
+  end
+
+  specify "rb_cIO references the IO class" do
+    @s.rb_cIO.should == IO
+  end
+
+  specify "rb_mKernel references the Kernel module" do
+    @s.rb_mKernel.should == Kernel
+  end
+
+  specify "rb_cMatch references the MatchData class" do
+    @s.rb_cMatch.should == MatchData
+  end
+
+  specify "rb_cModule references the Module class" do
+    @s.rb_cModule.should == Module
+  end
+
+  specify "rb_cNilClass references the NilClass class" do
+    @s.rb_cNilClass.should == NilClass
+  end
+
+  specify "rb_cNumeric references the Numeric class" do
+    @s.rb_cNumeric.should == Numeric
+  end
+
+  specify "rb_cObject references the Object class" do
+    @s.rb_cObject.should == Object
+  end
+
+  specify "rb_cRange references the Range class" do
+    @s.rb_cRange.should == Range
+  end
+
+  specify "rb_cRegexp references the Regexp class" do
+    @s.rb_cRegexp.should == Regexp
+  end
+
+  specify "rb_cString references the String class" do
+    @s.rb_cString.should == String
+  end
+
+  specify "rb_cStruct references the Struct class" do
+    @s.rb_cStruct.should == Struct
+  end
+
+  specify "rb_cSymbol references the Symbol class" do
+    @s.rb_cSymbol.should == Symbol
+  end
+
+  specify "rb_cThread references the Thread class" do
+    @s.rb_cThread.should == Thread
+  end
+
+  specify "rb_cTrueClass references the TrueClass class" do
+    @s.rb_cTrueClass.should == TrueClass
+  end
+
+  specify "rb_cProc references the Proc class" do
+    @s.rb_cProc.should == Proc
+  end
+end
+
+describe "C-API exception constant" do
+  before :each do
+    @s = CApiConstantsSpecs.new
+  end
+
+  specify "rb_eArgError references the ArgumentError class" do
+    @s.rb_eArgError.should == ArgumentError
+  end
+
+  specify "rb_eEOFError references the EOFError class" do
+    @s.rb_eEOFError.should == EOFError
+  end
+
+  specify "rb_eErrno references the Errno module" do
+    @s.rb_mErrno.should == Errno
+  end
+
+  specify "rb_eException references the Exception class" do
+    @s.rb_eException.should == Exception
+  end
+
+  specify "rb_eFloatDomainError references the FloatDomainError class" do
+    @s.rb_eFloatDomainError.should == FloatDomainError
+  end
+
+  specify "rb_eIndexError references the IndexError class" do
+    @s.rb_eIndexError.should == IndexError
+  end
+
+  specify "rb_eInterrupt references the Interrupt class" do
+    @s.rb_eInterrupt.should == Interrupt
+  end
+
+  specify "rb_eIOError references the IOError class" do
+    @s.rb_eIOError.should == IOError
+  end
+
+  specify "rb_eLoadError references the LoadError class" do
+    @s.rb_eLoadError.should == LoadError
+  end
+
+  specify "rb_eLocalJumpError references the LocalJumpError class" do
+    @s.rb_eLocalJumpError.should == LocalJumpError
+  end
+
+  specify "rb_eNameError references the NameError class" do
+    @s.rb_eNameError.should == NameError
+  end
+
+  specify "rb_eNoMemError references the NoMemoryError class" do
+    @s.rb_eNoMemError.should == NoMemoryError
+  end
+
+  specify "rb_eNoMethodError references the NoMethodError class" do
+    @s.rb_eNoMethodError.should == NoMethodError
+  end
+
+  specify "rb_eNotImpError references the NotImplementedError class" do
+    @s.rb_eNotImpError.should == NotImplementedError
+  end
+
+  specify "rb_eRangeError references the RangeError class" do
+    @s.rb_eRangeError.should == RangeError
+  end
+
+  specify "rb_eRegexpError references the RegexpError class" do
+    @s.rb_eRegexpError.should == RegexpError
+  end
+
+  specify "rb_eRuntimeError references the RuntimeError class" do
+    @s.rb_eRuntimeError.should == RuntimeError
+  end
+
+  specify "rb_eScriptError references the ScriptError class" do
+    @s.rb_eScriptError.should == ScriptError
+  end
+
+  specify "rb_eSecurityError references the SecurityError class" do
+    @s.rb_eSecurityError.should == SecurityError
+  end
+
+  specify "rb_eSignal references the SignalException class" do
+    @s.rb_eSignal.should == SignalException
+  end
+
+  specify "rb_eStandardError references the StandardError class" do
+    @s.rb_eStandardError.should == StandardError
+  end
+
+  specify "rb_eSyntaxError references the SyntaxError class" do
+    @s.rb_eSyntaxError.should == SyntaxError
+  end
+
+  specify "rb_eSystemCallError references the SystemCallError class" do
+    @s.rb_eSystemCallError.should == SystemCallError
+  end
+
+  specify "rb_eSystemExit references the SystemExit class" do
+    @s.rb_eSystemExit.should == SystemExit
+  end
+
+  specify "rb_eSysStackError references the SystemStackError class" do
+    @s.rb_eSysStackError.should == SystemStackError
+  end
+
+  specify "rb_eTypeError references the TypeError class" do
+    @s.rb_eTypeError.should == TypeError
+  end
+
+  specify "rb_eThreadError references the ThreadError class" do
+    @s.rb_eThreadError.should == ThreadError
+  end
+
+  specify "rb_eZeroDivError references the ZeroDivisionError class" do
+    @s.rb_eZeroDivError.should == ZeroDivisionError
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/data_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/data_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/data_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,32 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("data")
+
+describe "CApiAllocSpecs (a class with an alloc func defined)" do
+  it "calls the alloc func" do
+    @s = CApiAllocSpecs.new
+    @s.wrapped_data.should == 42 # not defined in initialize
+  end
+end
+
+describe "CApiWrappedStruct" do
+  before :each do
+    @s = CApiWrappedStructSpecs.new
+  end
+  
+  it "Data_Wrap_Struct should wrap and Data_Get_Struct should return data" do
+    a = @s.wrap_struct(1024)
+    @s.get_struct(a).should == 1024
+  end
+
+  it "RDATA()->data should return the struct data" do
+    a = @s.wrap_struct(1024)
+    @s.get_struct_rdata(a).should == 1024
+  end
+
+  it "Changing RDATA()->data should change the wrapped struct" do
+    a = @s.wrap_struct(1024)
+    @s.change_struct(a, 100)
+    @s.get_struct(a).should == 100
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/exception_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/exception_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/exception_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,55 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("exception")
+
+describe "C-API Exception function" do
+  before :each do
+    @s = CApiExceptionSpecs.new
+  end
+
+  describe "rb_exc_new" do
+    it "creates an exception from a C string and length" do
+      @s.rb_exc_new('foo').to_s.should == 'foo'
+    end
+  end
+
+  describe "rb_exc_new2" do
+    it "creates an exception from a C string" do
+      @s.rb_exc_new2('foo').to_s.should == 'foo'
+    end
+  end
+
+  describe "rb_exc_new3" do
+    it "creates an exception from a Ruby string" do
+      @s.rb_exc_new3('foo').to_s.should == 'foo'
+    end
+  end
+
+  describe "rb_exc_raise" do
+    it "raises passed exception" do
+      runtime_error = RuntimeError.new '42'
+      lambda { @s.rb_exc_raise(runtime_error) }.should raise_error(RuntimeError, '42')
+    end
+  end
+
+  extended_on :rubinius do
+    # TODO make these shared and test on 1.9 too.
+    describe "rb_set_errinfo" do
+      after :each do
+        @s.rb_set_errinfo(nil)
+      end
+
+      it "accepts nil" do
+        @s.rb_set_errinfo(nil).should be_nil
+      end
+
+      it "accepts an Exception instance" do
+        @s.rb_set_errinfo(Exception.new).should be_nil
+      end
+
+      it "raises a TypeError if the object is not nil or an Exception instance" do
+        lambda { @s.rb_set_errinfo("error") }.should raise_error(TypeError)
+      end
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/.gitignore
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/.gitignore	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/.gitignore	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,9 @@
+# signature of implementation that
+# last compiled an extension
+*.sig
+
+# build artifacts
+*.o
+*.so
+*.bundle
+*.dll

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/array_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/array_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/array_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,296 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RARRAY
+static VALUE array_spec_RARRAY_ptr_assign_call(VALUE self, VALUE array) {
+  VALUE* ptr;
+
+  ptr = RARRAY(array)->ptr;
+  ptr[1] = INT2FIX(5);
+  ptr[2] = INT2FIX(7);
+  rb_ary_push(array, INT2FIX(9));
+
+  return array;
+}
+
+static VALUE array_spec_RARRAY_ptr_assign_funcall(VALUE self, VALUE array) {
+  VALUE* ptr;
+
+  ptr = RARRAY(array)->ptr;
+  ptr[1] = INT2FIX(1);
+  ptr[2] = INT2FIX(2);
+  rb_funcall(array, rb_intern("<<"), 1, INT2FIX(3));
+
+  return array;
+}
+
+static VALUE array_spec_RARRAY_len(VALUE self, VALUE array) {
+  return INT2FIX(RARRAY(array)->len);
+}
+
+static VALUE array_spec_RARRAY_ptr_iterate(VALUE self, VALUE array) {
+  int i;
+  VALUE* ptr;
+
+  ptr = RARRAY(array)->ptr;
+  for(i = 0; i < RARRAY_LEN(array); i++) {
+    rb_yield(ptr[i]);
+  }
+  return Qnil;
+}
+
+static VALUE array_spec_RARRAY_ptr_assign(VALUE self, VALUE array, VALUE value) {
+  int i;
+  VALUE* ptr;
+
+  ptr = RARRAY(array)->ptr;
+  for(i = 0; i < RARRAY_LEN(array); i++) {
+    ptr[i] = value;
+  }
+  return array;
+}
+#endif
+
+#if defined(HAVE_RARRAY_LEN) && defined(HAVE_RARRAY_PTR)
+static VALUE array_spec_RARRAY_PTR_iterate(VALUE self, VALUE array) {
+  int i;
+  VALUE* ptr;
+
+  ptr = RARRAY_PTR(array);
+  for(i = 0; i < RARRAY_LEN(array); i++) {
+    rb_yield(ptr[i]);
+  }
+  return Qnil;
+}
+
+static VALUE array_spec_RARRAY_PTR_assign(VALUE self, VALUE array, VALUE value) {
+  int i;
+  VALUE* ptr;
+
+  ptr = RARRAY_PTR(array);
+  for(i = 0; i < RARRAY_LEN(array); i++) {
+    ptr[i] = value;
+  }
+  return Qnil;
+}
+
+static VALUE array_spec_RARRAY_LEN(VALUE self, VALUE array) {
+  return INT2FIX(RARRAY_LEN(array));
+}
+#endif
+
+#ifdef HAVE_RB_ARY_AREF
+static VALUE array_spec_rb_ary_aref(int argc, VALUE *argv, VALUE self) {
+  VALUE ary, args;
+  rb_scan_args(argc, argv, "1*", &ary, &args);
+  return rb_ary_aref(RARRAY_LEN(args), RARRAY_PTR(args), ary);
+}
+#endif
+
+#ifdef HAVE_RB_ARY_CLEAR
+static VALUE array_spec_rb_ary_clear(VALUE self, VALUE array) {
+  return rb_ary_clear(array);
+}
+#endif
+
+#ifdef HAVE_RB_ARY_DELETE
+static VALUE array_spec_rb_ary_delete(VALUE self, VALUE array, VALUE item) {
+  return rb_ary_delete(array, item);
+}
+#endif
+
+#ifdef HAVE_RB_ARY_DUP
+static VALUE array_spec_rb_ary_dup(VALUE self, VALUE array) {
+  return rb_ary_dup(array);
+}
+#endif
+
+#ifdef HAVE_RB_ARY_ENTRY
+static VALUE array_spec_rb_ary_entry(VALUE self, VALUE array, VALUE offset) {
+  return rb_ary_entry(array, FIX2INT(offset));
+}
+#endif
+
+#ifdef HAVE_RB_ARY_INCLUDES
+static VALUE array_spec_rb_ary_includes(VALUE self, VALUE ary, VALUE item) {
+  return rb_ary_includes(ary, item);
+}
+#endif
+
+#ifdef HAVE_RB_ARY_JOIN
+static VALUE array_spec_rb_ary_join(VALUE self, VALUE array1, VALUE array2) {
+  return rb_ary_join(array1, array2);
+}
+#endif
+
+#ifdef HAVE_RB_ARY_NEW
+static VALUE array_spec_rb_ary_new(VALUE self) {
+  VALUE ret;
+  ret = rb_ary_new();
+  return ret;
+}
+#endif
+
+#ifdef HAVE_RB_ARY_NEW2
+static VALUE array_spec_rb_ary_new2(VALUE self, VALUE length) {
+  return rb_ary_new2(NUM2LONG(length));
+}
+#endif
+
+#ifdef HAVE_RB_ARY_POP
+static VALUE array_spec_rb_ary_pop(VALUE self, VALUE array) {
+  return rb_ary_pop(array);
+}
+#endif
+
+#ifdef HAVE_RB_ARY_PUSH
+static VALUE array_spec_rb_ary_push(VALUE self, VALUE array, VALUE item) {
+  rb_ary_push(array, item);
+  return array;
+}
+#endif
+
+#ifdef HAVE_RB_ARY_REVERSE
+static VALUE array_spec_rb_ary_reverse(VALUE self, VALUE array) {
+  return rb_ary_reverse(array);
+}
+#endif
+
+#ifdef HAVE_RB_ARY_SHIFT
+static VALUE array_spec_rb_ary_shift(VALUE self, VALUE array) {
+  return rb_ary_shift(array);
+}
+#endif
+
+#ifdef HAVE_RB_ARY_STORE
+static VALUE array_spec_rb_ary_store(VALUE self, VALUE array, VALUE offset, VALUE value) {
+  rb_ary_store(array, FIX2INT(offset), value);
+
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_ARY_UNSHIFT
+static VALUE array_spec_rb_ary_unshift(VALUE self, VALUE array, VALUE val) {
+  return rb_ary_unshift(array, val);
+}
+#endif
+
+#ifdef HAVE_RB_ASSOC_NEW
+static VALUE array_spec_rb_assoc_new(VALUE self, VALUE first, VALUE second) {
+  return rb_assoc_new(first, second);
+}
+#endif
+
+#if defined(HAVE_RB_ITERATE) && defined(HAVE_RB_EACH)
+static VALUE copy_ary(VALUE el, VALUE new_ary) {
+  return rb_ary_push(new_ary, el);
+}
+
+static VALUE array_spec_rb_iterate(VALUE self, VALUE ary) {
+  VALUE new_ary = rb_ary_new();
+
+  rb_iterate(rb_each, ary, copy_ary, new_ary);
+
+  return new_ary;
+}
+#endif
+
+void Init_array_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiArraySpecs", rb_cObject);
+
+#ifdef HAVE_RARRAY
+  rb_define_method(cls, "RARRAY_ptr_iterate", array_spec_RARRAY_ptr_iterate, 1);
+  rb_define_method(cls, "RARRAY_ptr_assign", array_spec_RARRAY_ptr_assign, 2);
+  rb_define_method(cls, "RARRAY_ptr_assign_call",
+      array_spec_RARRAY_ptr_assign_call, 1);
+  rb_define_method(cls, "RARRAY_ptr_assign_funcall",
+      array_spec_RARRAY_ptr_assign_funcall, 1);
+  rb_define_method(cls, "RARRAY_len", array_spec_RARRAY_len, 1);
+#endif
+
+#if defined(HAVE_RARRAY_LEN) && defined(HAVE_RARRAY_PTR)
+  rb_define_method(cls, "RARRAY_LEN", array_spec_RARRAY_LEN, 1);
+  rb_define_method(cls, "RARRAY_PTR_iterate", array_spec_RARRAY_PTR_iterate, 1);
+  rb_define_method(cls, "RARRAY_PTR_assign", array_spec_RARRAY_PTR_assign, 2);
+#endif
+
+#ifdef HAVE_RB_ARY_AREF
+  rb_define_method(cls, "rb_ary_aref", array_spec_rb_ary_aref, -1);
+#endif
+
+#ifdef HAVE_RB_ARY_CLEAR
+  rb_define_method(cls, "rb_ary_clear", array_spec_rb_ary_clear, 1);
+#endif
+
+#ifdef HAVE_RB_ARY_DELETE
+  rb_define_method(cls, "rb_ary_delete", array_spec_rb_ary_delete, 2);
+#endif
+
+#ifdef HAVE_RB_ARY_DUP
+  rb_define_method(cls, "rb_ary_dup", array_spec_rb_ary_dup, 1);
+#endif
+
+#ifdef HAVE_RB_ARY_ENTRY
+  rb_define_method(cls, "rb_ary_entry", array_spec_rb_ary_entry, 2);
+#endif
+
+#ifdef HAVE_RB_ARY_INCLUDES
+  rb_define_method(cls, "rb_ary_includes", array_spec_rb_ary_includes, 2);
+#endif
+
+#ifdef HAVE_RB_ARY_JOIN
+  rb_define_method(cls, "rb_ary_join", array_spec_rb_ary_join, 2);
+#endif
+
+#ifdef HAVE_RB_ARY_NEW
+  rb_define_method(cls, "rb_ary_new", array_spec_rb_ary_new, 0);
+#endif
+
+#ifdef HAVE_RB_ARY_NEW2
+  rb_define_method(cls, "rb_ary_new2", array_spec_rb_ary_new2, 1);
+#endif
+
+#ifdef HAVE_RB_ARY_POP
+  rb_define_method(cls, "rb_ary_pop", array_spec_rb_ary_pop, 1);
+#endif
+
+#ifdef HAVE_RB_ARY_PUSH
+  rb_define_method(cls, "rb_ary_push", array_spec_rb_ary_push, 2);
+#endif
+
+#ifdef HAVE_RB_ARY_REVERSE
+  rb_define_method(cls, "rb_ary_reverse", array_spec_rb_ary_reverse, 1);
+#endif
+
+#ifdef HAVE_RB_ARY_SHIFT
+  rb_define_method(cls, "rb_ary_shift", array_spec_rb_ary_shift, 1);
+#endif
+
+#ifdef HAVE_RB_ARY_STORE
+  rb_define_method(cls, "rb_ary_store", array_spec_rb_ary_store, 3);
+#endif
+
+#ifdef HAVE_RB_ARY_UNSHIFT
+  rb_define_method(cls, "rb_ary_unshift", array_spec_rb_ary_unshift, 2);
+#endif
+
+#ifdef HAVE_RB_ASSOC_NEW
+  rb_define_method(cls, "rb_assoc_new", array_spec_rb_assoc_new, 2);
+#endif
+
+#if defined(HAVE_RB_ITERATE) && defined(HAVE_RB_EACH)
+  rb_define_method(cls, "rb_iterate", array_spec_rb_iterate, 1);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/bignum_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/bignum_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/bignum_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,65 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_BIG2DBL
+static VALUE bignum_spec_rb_big2dbl(VALUE self, VALUE num) {
+  return rb_float_new(rb_big2dbl(num));
+}
+#endif
+
+#ifdef HAVE_RB_BIG2LL
+static VALUE bignum_spec_rb_big2ll(VALUE self, VALUE num) {
+  return rb_ll2inum(rb_big2ll(num));
+}
+#endif
+
+#ifdef HAVE_RB_BIG2LONG
+static VALUE bignum_spec_rb_big2long(VALUE self, VALUE num) {
+  return LONG2NUM(rb_big2long(num));
+}
+#endif
+
+#ifdef HAVE_RB_BIG2STR
+static VALUE bignum_spec_rb_big2str(VALUE self, VALUE num, VALUE base) {
+  return rb_big2str(num, FIX2INT(base));
+}
+#endif
+
+#ifdef HAVE_RB_BIG2ULONG
+static VALUE bignum_spec_rb_big2ulong(VALUE self, VALUE num) {
+  return ULONG2NUM(rb_big2ulong(num));
+}
+#endif
+
+void Init_bignum_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiBignumSpecs", rb_cObject);
+
+#ifdef HAVE_RB_BIG2DBL
+  rb_define_method(cls, "rb_big2dbl", bignum_spec_rb_big2dbl, 1);
+#endif
+
+#ifdef HAVE_RB_BIG2LL
+  rb_define_method(cls, "rb_big2ll", bignum_spec_rb_big2ll, 1);
+#endif
+
+#ifdef HAVE_RB_BIG2LONG
+  rb_define_method(cls, "rb_big2long", bignum_spec_rb_big2long, 1);
+#endif
+
+#ifdef HAVE_RB_BIG2STR
+  rb_define_method(cls, "rb_big2str", bignum_spec_rb_big2str, 2);
+#endif
+
+#ifdef HAVE_RB_BIG2ULONG
+  rb_define_method(cls, "rb_big2ulong", bignum_spec_rb_big2ulong, 1);
+#endif
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/class_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/class_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/class_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,189 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_CALL_SUPER
+static VALUE class_spec_call_super_method(VALUE self) {
+  return rb_call_super(0, 0);
+}
+
+static VALUE class_spec_define_call_super_method(VALUE self, VALUE obj, VALUE str_name) {
+  rb_define_method(obj, RSTRING_PTR(str_name), class_spec_call_super_method, 0);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_CLASS2NAME
+static VALUE class_spec_rbclass2name(VALUE self, VALUE klass) {
+  return rb_str_new2( rb_class2name(klass) );
+}
+#endif
+
+#ifdef HAVE_RB_CLASS_INHERITED
+static VALUE class_spec_rb_class_inherited(VALUE self, VALUE super, VALUE klass) {
+  if(super == Qfalse) {
+    return rb_class_inherited((VALUE)(0), klass);
+  } else {
+    return rb_class_inherited(super, klass);
+  }
+}
+#endif
+
+#ifdef HAVE_RB_CLASS_NEW
+static VALUE class_spec_rb_class_new(VALUE self, VALUE super) {
+  return rb_class_new(super);
+}
+#endif
+
+#ifdef HAVE_RB_CLASS_NEW_INSTANCE
+static VALUE class_spec_rb_class_new_instance(VALUE self,
+                                      VALUE nargs, VALUE args,
+                                      VALUE klass) {
+  int c_nargs = FIX2INT(nargs);
+  VALUE c_args[c_nargs];
+  int i;
+
+  for (i = 0; i < c_nargs; i++)
+    c_args[i] = rb_ary_entry(args, i);
+
+  return rb_class_new_instance(c_nargs, c_args, klass);
+}
+
+#endif
+
+#ifdef HAVE_RB_CVAR_DEFINED
+static VALUE class_spec_cvar_defined(VALUE self, VALUE klass, VALUE id) {
+  ID as_id = rb_intern(StringValuePtr(id));
+  return rb_cvar_defined(klass, as_id);
+}
+#endif
+
+#ifdef HAVE_RB_CVAR_GET
+static VALUE class_spec_cvar_get(VALUE self, VALUE klass, VALUE name) {
+	return rb_cvar_get(klass, rb_intern(StringValuePtr(name)));
+}
+#endif
+
+#ifdef RUBY_VERSION_IS_1_8
+#ifdef HAVE_RB_CVAR_SET
+static VALUE class_spec_cvar_set(VALUE self, VALUE klass, VALUE name, VALUE val) {
+	rb_cvar_set(klass, rb_intern(StringValuePtr(name)), val, 0);
+  return Qnil;
+}
+#endif
+#endif
+
+#ifdef RUBY_VERSION_IS_1_9
+#ifdef HAVE_RB_CVAR_SET
+static VALUE class_spec_cvar_set(VALUE self, VALUE klass, VALUE name, VALUE val) {
+	rb_cvar_set(klass, rb_intern(StringValuePtr(name)), val);
+  return Qnil;
+}
+#endif
+#endif
+
+
+#ifdef HAVE_RB_CV_GET
+static VALUE class_spec_cv_get(VALUE self, VALUE klass, VALUE name) {
+	return rb_cv_get(klass, StringValuePtr(name));
+}
+#endif
+
+#ifdef HAVE_RB_CV_SET
+static VALUE class_spec_cv_set(VALUE self, VALUE klass, VALUE name, VALUE val) {
+	rb_cv_set(klass, StringValuePtr(name), val);
+
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_DEFINE_ATTR
+VALUE class_spec_define_attr(VALUE self, VALUE klass, VALUE sym, VALUE read, VALUE write) {
+  int int_read, int_write;
+  int_read = read == Qtrue ? 1 : 0;
+  int_write = write == Qtrue ? 1 : 0;
+  rb_define_attr(klass, rb_id2name(SYM2ID(sym)), int_read, int_write);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_DEFINE_CLASS_VARIABLE
+static VALUE class_spec_define_class_variable(VALUE self, VALUE klass, VALUE name, VALUE val) {
+  rb_define_class_variable(klass, StringValuePtr(name), val);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_INCLUDE_MODULE
+static VALUE class_spec_include_module(VALUE self, VALUE klass, VALUE module) {
+  rb_include_module(klass, module);
+  return klass;
+}
+#endif
+
+void Init_class_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiClassSpecs", rb_cObject);
+
+#ifdef HAVE_RB_CALL_SUPER
+  rb_define_method(cls, "define_call_super_method", class_spec_define_call_super_method, 2);
+#endif
+
+#ifdef HAVE_RB_CLASS2NAME
+  rb_define_method(cls, "rb_class2name", class_spec_rbclass2name, 1);
+#endif
+
+#ifdef HAVE_RB_CLASS_INHERITED
+  rb_define_method(cls, "rb_class_inherited", class_spec_rb_class_inherited, 2);
+#endif
+
+#ifdef HAVE_RB_CLASS_NEW
+  rb_define_method(cls, "rb_class_new", class_spec_rb_class_new, 1);
+#endif
+
+#ifdef HAVE_RB_CLASS_NEW_INSTANCE
+  rb_define_method(cls, "rb_class_new_instance", class_spec_rb_class_new_instance, 3);
+#endif
+
+#ifdef HAVE_RB_CVAR_DEFINED
+  rb_define_method(cls, "rb_cvar_defined", class_spec_cvar_defined, 2);
+#endif
+
+#ifdef HAVE_RB_CVAR_GET
+  rb_define_method(cls, "rb_cvar_get", class_spec_cvar_get, 2);
+#endif
+
+#ifdef HAVE_RB_CVAR_SET
+  rb_define_method(cls, "rb_cvar_set", class_spec_cvar_set, 3);
+#endif
+
+#ifdef HAVE_RB_CV_GET
+  rb_define_method(cls, "rb_cv_get", class_spec_cv_get, 2);
+#endif
+
+#ifdef HAVE_RB_CV_SET
+  rb_define_method(cls, "rb_cv_set", class_spec_cv_set, 3);
+#endif
+
+#ifdef HAVE_RB_DEFINE_ATTR
+  rb_define_method(cls, "rb_define_attr", class_spec_define_attr, 4);
+#endif
+
+#ifdef HAVE_RB_DEFINE_CLASS_VARIABLE
+  rb_define_method(cls, "rb_define_class_variable", class_spec_define_class_variable, 3);
+#endif
+
+#ifdef HAVE_RB_INCLUDE_MODULE
+  rb_define_method(cls, "rb_include_module", class_spec_include_module, 2);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/constants_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/constants_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/constants_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,567 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_CARRAY
+static VALUE constants_spec_rb_cArray(VALUE self) {
+  return rb_cArray;
+}
+#endif
+
+#ifdef HAVE_RB_CBIGNUM
+static VALUE constants_spec_rb_cBignum(VALUE self) {
+  return rb_cBignum;
+}
+#endif
+
+#ifdef HAVE_RB_CCLASS
+static VALUE constants_spec_rb_cClass(VALUE self) {
+  return rb_cClass;
+}
+#endif
+
+#ifdef HAVE_RB_CDATA
+static VALUE constants_spec_rb_cData(VALUE self) {
+  return rb_cData;
+}
+#endif
+
+#ifdef HAVE_RB_CFALSECLASS
+static VALUE constants_spec_rb_cFalseClass(VALUE self) {
+  return rb_cFalseClass;
+}
+#endif
+
+#ifdef HAVE_RB_CFILE
+static VALUE constants_spec_rb_cFile(VALUE self) {
+  return rb_cFile;
+}
+#endif
+
+#ifdef HAVE_RB_CFIXNUM
+static VALUE constants_spec_rb_cFixnum(VALUE self) {
+  return rb_cFixnum;
+}
+#endif
+
+#ifdef HAVE_RB_CFLOAT
+static VALUE constants_spec_rb_cFloat(VALUE self) {
+  return rb_cFloat;
+}
+#endif
+
+#ifdef HAVE_RB_CHASH
+static VALUE constants_spec_rb_cHash(VALUE self) {
+  return rb_cHash;
+}
+#endif
+
+#ifdef HAVE_RB_CINTEGER
+static VALUE constants_spec_rb_cInteger(VALUE self) {
+  return rb_cInteger;
+}
+#endif
+
+#ifdef HAVE_RB_CIO
+static VALUE constants_spec_rb_cIO(VALUE self) {
+  return rb_cIO;
+}
+#endif
+
+#ifdef HAVE_RB_CMODULE
+static VALUE constants_spec_rb_cModule(VALUE self) {
+  return rb_cModule;
+}
+#endif
+
+#ifdef HAVE_RB_CMATCH
+static VALUE constants_spec_rb_cMatch(VALUE self) {
+  return rb_cMatch;
+}
+#endif
+
+#ifdef HAVE_RB_CNILCLASS
+static VALUE constants_spec_rb_cNilClass(VALUE self) {
+  return rb_cNilClass;
+}
+#endif
+
+#ifdef HAVE_RB_CNUMERIC
+static VALUE constants_spec_rb_cNumeric(VALUE self) {
+  return rb_cNumeric;
+}
+#endif
+
+#ifdef HAVE_RB_COBJECT
+static VALUE constants_spec_rb_cObject(VALUE self) {
+  return rb_cObject;
+}
+#endif
+
+#ifdef HAVE_RB_CRANGE
+static VALUE constants_spec_rb_cRange(VALUE self) {
+  return rb_cRange;
+}
+#endif
+
+#ifdef HAVE_RB_CREGEXP
+static VALUE constants_spec_rb_cRegexp(VALUE self) {
+  return rb_cRegexp;
+}
+#endif
+
+#ifdef HAVE_RB_CSTRING
+static VALUE constants_spec_rb_cString(VALUE self) {
+  return rb_cString;
+}
+#endif
+
+#ifdef HAVE_RB_CSTRUCT
+static VALUE constants_spec_rb_cStruct(VALUE self) {
+  return rb_cStruct;
+}
+#endif
+
+#ifdef HAVE_RB_CSYMBOL
+static VALUE constants_spec_rb_cSymbol(VALUE self) {
+  return rb_cSymbol;
+}
+#endif
+
+#ifdef HAVE_RB_CTHREAD
+static VALUE constants_spec_rb_cThread(VALUE self) {
+  return rb_cThread;
+}
+#endif
+
+#ifdef HAVE_RB_CTRUECLASS
+static VALUE constants_spec_rb_cTrueClass(VALUE self) {
+  return rb_cTrueClass;
+}
+#endif
+
+#ifdef HAVE_RB_CPROC
+static VALUE constants_spec_rb_cProc(VALUE self) {
+  return rb_cProc;
+}
+#endif
+
+#ifdef HAVE_RB_MCOMPARABLE
+static VALUE constants_spec_rb_mComparable(VALUE self) {
+  return rb_mComparable;
+}
+#endif
+
+#ifdef HAVE_RB_MENUMERABLE
+static VALUE constants_spec_rb_mEnumerable(VALUE self) {
+  return rb_mEnumerable;
+}
+#endif
+
+#ifdef HAVE_RB_MKERNEL
+static VALUE constants_spec_rb_mKernel(VALUE self) {
+  return rb_mKernel;
+}
+#endif
+
+#ifdef HAVE_RB_EARGERROR
+static VALUE constants_spec_rb_eArgError(VALUE self) {
+  return rb_eArgError;
+}
+#endif
+
+#ifdef HAVE_RB_EEOFERROR
+static VALUE constants_spec_rb_eEOFError(VALUE self) {
+  return rb_eEOFError;
+}
+#endif
+
+#ifdef HAVE_RB_MERRNO
+static VALUE constants_spec_rb_mErrno(VALUE self) {
+  return rb_mErrno;
+}
+#endif
+
+#ifdef HAVE_RB_EEXCEPTION
+static VALUE constants_spec_rb_eException(VALUE self) {
+  return rb_eException;
+}
+#endif
+
+#ifdef HAVE_RB_EFLOATDOMAINERROR
+static VALUE constants_spec_rb_eFloatDomainError(VALUE self) {
+  return rb_eFloatDomainError;
+}
+#endif
+
+#ifdef HAVE_RB_EINDEXERROR
+static VALUE constants_spec_rb_eIndexError(VALUE self) {
+  return rb_eIndexError;
+}
+#endif
+
+#ifdef HAVE_RB_EINTERRUPT
+static VALUE constants_spec_rb_eInterrupt(VALUE self) {
+  return rb_eInterrupt;
+}
+#endif
+
+#ifdef HAVE_RB_EIOERROR
+static VALUE constants_spec_rb_eIOError(VALUE self) {
+  return rb_eIOError;
+}
+#endif
+
+#ifdef HAVE_RB_ELOADERROR
+static VALUE constants_spec_rb_eLoadError(VALUE self) {
+  return rb_eLoadError;
+}
+#endif
+
+#ifdef HAVE_RB_ELOCALJUMPERROR
+static VALUE constants_spec_rb_eLocalJumpError(VALUE self) {
+  return rb_eLocalJumpError;
+}
+#endif
+
+#ifdef HAVE_RB_ENAMEERROR
+static VALUE constants_spec_rb_eNameError(VALUE self) {
+  return rb_eNameError;
+}
+#endif
+
+#ifdef HAVE_RB_ENOMEMERROR
+static VALUE constants_spec_rb_eNoMemError(VALUE self) {
+  return rb_eNoMemError;
+}
+#endif
+
+#ifdef HAVE_RB_ENOMETHODERROR
+static VALUE constants_spec_rb_eNoMethodError(VALUE self) {
+  return rb_eNoMethodError;
+}
+#endif
+
+#ifdef HAVE_RB_ENOTIMPERROR
+static VALUE constants_spec_rb_eNotImpError(VALUE self) {
+  return rb_eNotImpError;
+}
+#endif
+
+#ifdef HAVE_RB_ERANGEERROR
+static VALUE constants_spec_rb_eRangeError(VALUE self) {
+  return rb_eRangeError;
+}
+#endif
+
+#ifdef HAVE_RB_EREGEXPERROR
+static VALUE constants_spec_rb_eRegexpError(VALUE self) {
+  return rb_eRegexpError;
+}
+#endif
+
+#ifdef HAVE_RB_ERUNTIMEERROR
+static VALUE constants_spec_rb_eRuntimeError(VALUE self) {
+  return rb_eRuntimeError;
+}
+#endif
+
+#ifdef HAVE_RB_ESCRIPTERROR
+static VALUE constants_spec_rb_eScriptError(VALUE self) {
+  return rb_eScriptError;
+}
+#endif
+
+#ifdef HAVE_RB_ESECURITYERROR
+static VALUE constants_spec_rb_eSecurityError(VALUE self) {
+  return rb_eSecurityError;
+}
+#endif
+
+#ifdef HAVE_RB_ESIGNAL
+static VALUE constants_spec_rb_eSignal(VALUE self) {
+  return rb_eSignal;
+}
+#endif
+
+#ifdef HAVE_RB_ESTANDARDERROR
+static VALUE constants_spec_rb_eStandardError(VALUE self) {
+  return rb_eStandardError;
+}
+#endif
+
+#ifdef HAVE_RB_ESYNTAXERROR
+static VALUE constants_spec_rb_eSyntaxError(VALUE self) {
+  return rb_eSyntaxError;
+}
+#endif
+
+#ifdef HAVE_RB_ESYSTEMCALLERROR
+static VALUE constants_spec_rb_eSystemCallError(VALUE self) {
+  return rb_eSystemCallError;
+}
+#endif
+
+#ifdef HAVE_RB_ESYSTEMEXIT
+static VALUE constants_spec_rb_eSystemExit(VALUE self) {
+  return rb_eSystemExit;
+}
+#endif
+
+#ifdef HAVE_RB_ESYSSTACKERROR
+static VALUE constants_spec_rb_eSysStackError(VALUE self) {
+  return rb_eSysStackError;
+}
+#endif
+
+#ifdef HAVE_RB_ETYPEERROR
+static VALUE constants_spec_rb_eTypeError(VALUE self) {
+  return rb_eTypeError;
+}
+#endif
+
+#ifdef HAVE_RB_ETHREADERROR
+static VALUE constants_spec_rb_eThreadError(VALUE self) {
+  return rb_eThreadError;
+}
+#endif
+
+#ifdef HAVE_RB_EZERODIVERROR
+static VALUE constants_spec_rb_eZeroDivError(VALUE self) {
+  return rb_eZeroDivError;
+}
+#endif
+
+void Init_constants_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiConstantsSpecs", rb_cObject);
+
+#ifdef HAVE_RB_CARRAY
+  rb_define_method(cls, "rb_cArray", constants_spec_rb_cArray, 0);
+#endif
+
+#ifdef HAVE_RB_CBIGNUM
+  rb_define_method(cls, "rb_cBignum", constants_spec_rb_cBignum, 0);
+#endif
+
+#ifdef HAVE_RB_CCLASS
+  rb_define_method(cls, "rb_cClass", constants_spec_rb_cClass, 0);
+#endif
+
+#ifdef HAVE_RB_CDATA
+  rb_define_method(cls, "rb_cData", constants_spec_rb_cData, 0);
+#endif
+
+#ifdef HAVE_RB_CFALSECLASS
+  rb_define_method(cls, "rb_cFalseClass", constants_spec_rb_cFalseClass, 0);
+#endif
+
+#ifdef HAVE_RB_CFILE
+  rb_define_method(cls, "rb_cFile", constants_spec_rb_cFile, 0);
+#endif
+
+#ifdef HAVE_RB_CFIXNUM
+  rb_define_method(cls, "rb_cFixnum", constants_spec_rb_cFixnum, 0);
+#endif
+
+#ifdef HAVE_RB_CFLOAT
+  rb_define_method(cls, "rb_cFloat", constants_spec_rb_cFloat, 0);
+#endif
+
+#ifdef HAVE_RB_CHASH
+  rb_define_method(cls, "rb_cHash", constants_spec_rb_cHash, 0);
+#endif
+
+#ifdef HAVE_RB_CINTEGER
+  rb_define_method(cls, "rb_cInteger", constants_spec_rb_cInteger, 0);
+#endif
+
+#ifdef HAVE_RB_CIO
+  rb_define_method(cls, "rb_cIO", constants_spec_rb_cIO, 0);
+#endif
+
+#ifdef HAVE_RB_CMATCH
+  rb_define_method(cls, "rb_cMatch", constants_spec_rb_cMatch, 0);
+#endif
+
+#ifdef HAVE_RB_CMODULE
+  rb_define_method(cls, "rb_cModule", constants_spec_rb_cModule, 0);
+#endif
+
+#ifdef HAVE_RB_CNILCLASS
+  rb_define_method(cls, "rb_cNilClass", constants_spec_rb_cNilClass, 0);
+#endif
+
+#ifdef HAVE_RB_CNUMERIC
+  rb_define_method(cls, "rb_cNumeric", constants_spec_rb_cNumeric, 0);
+#endif
+
+#ifdef HAVE_RB_COBJECT
+  rb_define_method(cls, "rb_cObject", constants_spec_rb_cObject, 0);
+#endif
+
+#ifdef HAVE_RB_CRANGE
+  rb_define_method(cls, "rb_cRange", constants_spec_rb_cRange, 0);
+#endif
+
+#ifdef HAVE_RB_CREGEXP
+  rb_define_method(cls, "rb_cRegexp", constants_spec_rb_cRegexp, 0);
+#endif
+
+#ifdef HAVE_RB_CSTRING
+  rb_define_method(cls, "rb_cString", constants_spec_rb_cString, 0);
+#endif
+
+#ifdef HAVE_RB_CSTRUCT
+  rb_define_method(cls, "rb_cStruct", constants_spec_rb_cStruct, 0);
+#endif
+
+#ifdef HAVE_RB_CSYMBOL
+  rb_define_method(cls, "rb_cSymbol", constants_spec_rb_cSymbol, 0);
+#endif
+
+#ifdef HAVE_RB_CTHREAD
+  rb_define_method(cls, "rb_cThread", constants_spec_rb_cThread, 0);
+#endif
+
+#ifdef HAVE_RB_CTRUECLASS
+  rb_define_method(cls, "rb_cTrueClass", constants_spec_rb_cTrueClass, 0);
+#endif
+
+#ifdef HAVE_RB_CPROC
+  rb_define_method(cls, "rb_cProc", constants_spec_rb_cProc, 0);
+#endif
+
+
+#ifdef HAVE_RB_MCOMPARABLE
+  rb_define_method(cls, "rb_mComparable", constants_spec_rb_mComparable, 0);
+#endif
+
+#ifdef HAVE_RB_MENUMERABLE
+  rb_define_method(cls, "rb_mEnumerable", constants_spec_rb_mEnumerable, 0);
+#endif
+
+#ifdef HAVE_RB_MKERNEL
+  rb_define_method(cls, "rb_mKernel", constants_spec_rb_mKernel, 0);
+#endif
+
+
+#ifdef HAVE_RB_EARGERROR
+  rb_define_method(cls, "rb_eArgError", constants_spec_rb_eArgError, 0);
+#endif
+
+#ifdef HAVE_RB_EEOFERROR
+  rb_define_method(cls, "rb_eEOFError", constants_spec_rb_eEOFError, 0);
+#endif
+
+#ifdef HAVE_RB_MERRNO
+  rb_define_method(cls, "rb_mErrno", constants_spec_rb_mErrno, 0);
+#endif
+
+#ifdef HAVE_RB_EEXCEPTION
+  rb_define_method(cls, "rb_eException", constants_spec_rb_eException, 0);
+#endif
+
+#ifdef HAVE_RB_EFLOATDOMAINERROR
+  rb_define_method(cls, "rb_eFloatDomainError", constants_spec_rb_eFloatDomainError, 0);
+#endif
+
+#ifdef HAVE_RB_EINDEXERROR
+  rb_define_method(cls, "rb_eIndexError", constants_spec_rb_eIndexError, 0);
+#endif
+
+#ifdef HAVE_RB_EINTERRUPT
+  rb_define_method(cls, "rb_eInterrupt", constants_spec_rb_eInterrupt, 0);
+#endif
+
+#ifdef HAVE_RB_EIOERROR
+  rb_define_method(cls, "rb_eIOError", constants_spec_rb_eIOError, 0);
+#endif
+
+#ifdef HAVE_RB_ELOADERROR
+  rb_define_method(cls, "rb_eLoadError", constants_spec_rb_eLoadError, 0);
+#endif
+
+#ifdef HAVE_RB_ELOCALJUMPERROR
+  rb_define_method(cls, "rb_eLocalJumpError", constants_spec_rb_eLocalJumpError, 0);
+#endif
+
+#ifdef HAVE_RB_ENAMEERROR
+  rb_define_method(cls, "rb_eNameError", constants_spec_rb_eNameError, 0);
+#endif
+
+#ifdef HAVE_RB_ENOMEMERROR
+  rb_define_method(cls, "rb_eNoMemError", constants_spec_rb_eNoMemError, 0);
+#endif
+
+#ifdef HAVE_RB_ENOMETHODERROR
+  rb_define_method(cls, "rb_eNoMethodError", constants_spec_rb_eNoMethodError, 0);
+#endif
+
+#ifdef HAVE_RB_ENOTIMPERROR
+  rb_define_method(cls, "rb_eNotImpError", constants_spec_rb_eNotImpError, 0);
+#endif
+
+#ifdef HAVE_RB_ERANGEERROR
+  rb_define_method(cls, "rb_eRangeError", constants_spec_rb_eRangeError, 0);
+#endif
+
+#ifdef HAVE_RB_EREGEXPERROR
+  rb_define_method(cls, "rb_eRegexpError", constants_spec_rb_eRegexpError, 0);
+#endif
+
+#ifdef HAVE_RB_ERUNTIMEERROR
+  rb_define_method(cls, "rb_eRuntimeError", constants_spec_rb_eRuntimeError, 0);
+#endif
+
+#ifdef HAVE_RB_ESCRIPTERROR
+  rb_define_method(cls, "rb_eScriptError", constants_spec_rb_eScriptError, 0);
+#endif
+
+#ifdef HAVE_RB_ESECURITYERROR
+  rb_define_method(cls, "rb_eSecurityError", constants_spec_rb_eSecurityError, 0);
+#endif
+
+#ifdef HAVE_RB_ESIGNAL
+  rb_define_method(cls, "rb_eSignal", constants_spec_rb_eSignal, 0);
+#endif
+
+#ifdef HAVE_RB_ESTANDARDERROR
+  rb_define_method(cls, "rb_eStandardError", constants_spec_rb_eStandardError, 0);
+#endif
+
+#ifdef HAVE_RB_ESYNTAXERROR
+  rb_define_method(cls, "rb_eSyntaxError", constants_spec_rb_eSyntaxError, 0);
+#endif
+
+#ifdef HAVE_RB_ESYSTEMCALLERROR
+  rb_define_method(cls, "rb_eSystemCallError", constants_spec_rb_eSystemCallError, 0);
+#endif
+
+#ifdef HAVE_RB_ESYSTEMEXIT
+  rb_define_method(cls, "rb_eSystemExit", constants_spec_rb_eSystemExit, 0);
+#endif
+
+#ifdef HAVE_RB_ESYSSTACKERROR
+  rb_define_method(cls, "rb_eSysStackError", constants_spec_rb_eSysStackError, 0);
+#endif
+
+#ifdef HAVE_RB_ETYPEERROR
+  rb_define_method(cls, "rb_eTypeError", constants_spec_rb_eTypeError, 0);
+#endif
+
+#ifdef HAVE_RB_ETHREADERROR
+  rb_define_method(cls, "rb_eThreadError", constants_spec_rb_eThreadError, 0);
+#endif
+
+#ifdef HAVE_RB_EZERODIVERROR
+  rb_define_method(cls, "rb_eZeroDivError", constants_spec_rb_eZeroDivError, 0);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/data_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/data_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/data_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,71 @@
+#include <string.h>
+
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(HAVE_RDATA) && defined(HAVE_DATA_WRAP_STRUCT)
+struct sample_wrapped_struct {
+    int foo;
+};
+
+VALUE sdaf_alloc_func(VALUE klass) {
+    struct sample_wrapped_struct* bar = (struct sample_wrapped_struct *)malloc(sizeof(struct sample_wrapped_struct));
+    bar->foo = 42;
+    return Data_Wrap_Struct(klass, NULL, NULL, bar);
+}
+
+VALUE sdaf_get_struct(VALUE self) {
+    struct sample_wrapped_struct* bar;
+    Data_Get_Struct(self, struct sample_wrapped_struct, bar);
+
+    return INT2FIX((*bar).foo);
+}
+
+VALUE sws_wrap_struct(VALUE self, VALUE val) {
+    struct sample_wrapped_struct* bar = (struct sample_wrapped_struct *)malloc(sizeof(struct sample_wrapped_struct));
+    bar->foo = FIX2INT(val);
+    return Data_Wrap_Struct(rb_cObject, NULL, NULL, bar);
+}
+
+VALUE sws_get_struct(VALUE self, VALUE obj) {
+    struct sample_wrapped_struct* bar;
+    Data_Get_Struct(obj, struct sample_wrapped_struct, bar);
+
+    return INT2FIX((*bar).foo);
+}
+
+VALUE sws_get_struct_rdata(VALUE self, VALUE obj) {
+  struct sample_wrapped_struct* bar;
+  bar = (struct sample_wrapped_struct*) RDATA(obj)->data;
+  return INT2FIX(bar->foo);
+}
+
+VALUE sws_change_struct(VALUE self, VALUE obj, VALUE new_val) {
+  struct sample_wrapped_struct* new_struct = (struct sample_wrapped_struct *)malloc(sizeof(struct sample_wrapped_struct));
+  new_struct->foo = FIX2INT(new_val);
+  RDATA(obj)->data = new_struct;
+  return Qnil;
+}
+
+void Init_data_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiAllocSpecs", rb_cObject);
+
+  rb_define_alloc_func(cls, sdaf_alloc_func);
+  rb_define_method(cls, "wrapped_data", sdaf_get_struct, 0);
+
+  cls = rb_define_class("CApiWrappedStructSpecs", rb_cObject);
+  rb_define_method(cls, "wrap_struct", sws_wrap_struct, 1);
+  rb_define_method(cls, "get_struct", sws_get_struct, 1);
+  rb_define_method(cls, "get_struct_rdata", sws_get_struct_rdata, 1);
+  rb_define_method(cls, "change_struct", sws_change_struct, 2);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/exception_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/exception_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/exception_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,72 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_EXC_NEW
+VALUE exception_spec_rb_exc_new(VALUE self, VALUE str) {
+  char *cstr = StringValuePtr(str);
+  return rb_exc_new(rb_eException, cstr, strlen(cstr));
+}
+#endif
+
+#ifdef HAVE_RB_EXC_NEW2
+VALUE exception_spec_rb_exc_new2(VALUE self, VALUE str) {
+  char *cstr = StringValuePtr(str);
+  return rb_exc_new2(rb_eException, cstr);
+}
+#endif
+
+#ifdef HAVE_RB_EXC_NEW3
+VALUE exception_spec_rb_exc_new3(VALUE self, VALUE str) {
+  return rb_exc_new3(rb_eException, str);
+}
+#endif
+
+#ifdef HAVE_RB_EXC_RAISE
+VALUE exception_spec_rb_exc_raise(VALUE self, VALUE exc) {
+  rb_exc_raise(exc);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_SET_ERRINFO
+VALUE exception_spec_rb_set_errinfo(VALUE self, VALUE exc) {
+  rb_set_errinfo(exc);
+  return Qnil;
+}
+#endif
+
+void Init_exception_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiExceptionSpecs", rb_cObject);
+
+#ifdef HAVE_RB_EXC_NEW
+  rb_define_method(cls, "rb_exc_new", exception_spec_rb_exc_new, 1);
+#endif
+
+#ifdef HAVE_RB_EXC_NEW2
+  rb_define_method(cls, "rb_exc_new2", exception_spec_rb_exc_new2, 1);
+#endif
+
+#ifdef HAVE_RB_EXC_NEW3
+  rb_define_method(cls, "rb_exc_new3", exception_spec_rb_exc_new3, 1);
+#endif
+
+#ifdef HAVE_RB_EXC_RAISE
+  rb_define_method(cls, "rb_exc_raise", exception_spec_rb_exc_raise, 1);
+#endif
+
+#ifdef HAVE_RB_SET_ERRINFO
+  rb_define_method(cls, "rb_set_errinfo", exception_spec_rb_set_errinfo, 1);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/float_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/float_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/float_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,60 @@
+#include <math.h>
+
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_FLOAT_NEW
+static VALUE float_spec_new_zero(VALUE self) {
+  double flt = 0;
+  return rb_float_new(flt);
+}
+
+static VALUE float_spec_new_point_five(VALUE self) {
+  double flt = 0.555;
+  return rb_float_new(flt);
+}
+#endif
+
+#ifdef HAVE_RB_RFLOAT
+static VALUE float_spec_rb_Float(VALUE self, VALUE float_str) {
+  return rb_Float(float_str);
+}
+#endif
+
+#ifdef HAVE_RFLOAT
+static VALUE float_spec_RFLOAT_value_set(VALUE self, VALUE float_h, VALUE new_value) {
+  RFLOAT(float_h)->value = (double)NUM2INT(new_value);
+  return Qnil;
+}
+
+static VALUE float_spec_RFLOAT_value(VALUE self, VALUE float_h) {
+  return rb_float_new(RFLOAT(float_h)->value);
+}
+#endif
+
+void Init_float_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiFloatSpecs", rb_cObject);
+
+#ifdef HAVE_RB_FLOAT_NEW
+  rb_define_method(cls, "new_zero", float_spec_new_zero, 0);
+  rb_define_method(cls, "new_point_five", float_spec_new_point_five, 0);
+#endif
+
+#ifdef HAVE_RB_RFLOAT
+  rb_define_method(cls, "rb_Float", float_spec_rb_Float, 1);
+#endif
+
+#ifdef HAVE_RFLOAT
+  rb_define_method(cls, "RFLOAT_value", float_spec_RFLOAT_value, 1);
+  rb_define_method(cls, "RFLOAT_value_set", float_spec_RFLOAT_value_set, 2);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/gc_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/gc_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/gc_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,39 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_GC_REGISTER_ADDRESS
+VALUE registered_tagged_value;
+VALUE registered_reference_value;
+
+static VALUE registered_tagged_address(VALUE self) {
+  return registered_tagged_value;
+}
+
+static VALUE registered_reference_address(VALUE self) {
+  return registered_reference_value;
+}
+#endif
+
+void Init_gc_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiGCSpecs", rb_cObject);
+
+#ifdef HAVE_RB_GC_REGISTER_ADDRESS
+  registered_tagged_value    = INT2NUM(10);
+  registered_reference_value = rb_str_new2("Globally registered data");
+
+  rb_gc_register_address(&registered_tagged_value);
+  rb_gc_register_address(&registered_reference_value);
+
+  rb_define_method(cls, "registered_tagged_address", registered_tagged_address, 0);
+  rb_define_method(cls, "registered_reference_address", registered_reference_address, 0);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/globals_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/globals_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/globals_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,106 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_DEFINE_HOOKED_VARIABLE
+VALUE g_hooked_var = Qnil;
+
+void var_2x_setter(VALUE val, ID id, VALUE *var) {
+    *var = INT2NUM(NUM2INT(val) * 2);
+}
+
+static VALUE sb_define_hooked_variable(VALUE self, VALUE var_name) {
+  rb_define_hooked_variable(StringValuePtr(var_name), &g_hooked_var, 0, var_2x_setter);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_DEFINE_READONLY_VARIABLE
+VALUE g_ro_var = Qnil;
+
+static VALUE sb_define_readonly_variable(VALUE self, VALUE var_name, VALUE val) {
+  g_ro_var = val;
+  rb_define_readonly_variable(StringValuePtr(var_name), &g_ro_var);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_DEFINE_VARIABLE
+VALUE g_var = Qnil;
+
+static VALUE sb_get_global_value(VALUE self) {
+  return g_var;
+}
+
+static VALUE sb_define_variable(VALUE self, VALUE var_name, VALUE val) {
+  g_var = val;
+  rb_define_variable(StringValuePtr(var_name), &g_var);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_F_GLOBAL_VARIABLES
+static VALUE sb_f_global_variables(VALUE self) {
+  return rb_f_global_variables();
+}
+#endif
+
+#ifdef HAVE_RB_GV_GET
+static VALUE sb_gv_get(VALUE self, VALUE var) {
+  return rb_gv_get(StringValuePtr(var));
+}
+#endif
+
+#ifdef HAVE_RB_GV_SET
+static VALUE sb_gv_set(VALUE self, VALUE var, VALUE val) {
+  return rb_gv_set(StringValuePtr(var), val);
+}
+#endif
+
+#ifdef HAVE_RB_SET_KCODE
+static VALUE global_spec_rb_set_kcode(VALUE self, VALUE code) {
+  rb_set_kcode(RSTRING_PTR(code));
+  return Qnil;
+}
+#endif
+
+void Init_globals_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiGlobalSpecs", rb_cObject);
+
+#ifdef HAVE_RB_DEFINE_HOOKED_VARIABLE
+  rb_define_method(cls, "rb_define_hooked_variable_2x", sb_define_hooked_variable, 1);
+#endif
+
+#ifdef HAVE_RB_DEFINE_READONLY_VARIABLE
+  rb_define_method(cls, "rb_define_readonly_variable", sb_define_readonly_variable, 2);
+#endif
+
+#ifdef HAVE_RB_DEFINE_VARIABLE
+  rb_define_method(cls, "rb_define_variable", sb_define_variable, 2);
+  rb_define_method(cls, "sb_get_global_value", sb_get_global_value, 0);
+#endif
+
+#ifdef HAVE_RB_F_GLOBAL_VARIABLES
+  rb_define_method(cls, "rb_f_global_variables", sb_f_global_variables, 0);
+#endif
+
+#ifdef HAVE_RB_GV_GET
+  rb_define_method(cls, "sb_gv_get", sb_gv_get, 1);
+#endif
+
+#ifdef HAVE_RB_GV_SET
+  rb_define_method(cls, "sb_gv_set", sb_gv_set, 2);
+#endif
+
+#ifdef HAVE_RB_SET_KCODE
+  rb_define_method(cls, "rb_set_kcode", global_spec_rb_set_kcode, 1);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/hash_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/hash_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/hash_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,105 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_HASH_AREF
+VALUE hash_spec_rb_hash_aref(VALUE self, VALUE hash, VALUE key) {
+  return rb_hash_aref(hash, key);
+}
+
+VALUE hash_spec_rb_hash_aref_nil(VALUE self, VALUE hash, VALUE key) {
+  VALUE ret = rb_hash_aref(hash, key);
+  return ret == Qnil ? Qtrue : Qfalse;
+}
+#endif
+
+#ifdef HAVE_RB_HASH_ASET
+VALUE hash_spec_rb_hash_aset(VALUE self, VALUE hash, VALUE key, VALUE val) {
+  return rb_hash_aset(hash, key, val);
+}
+#endif
+
+#ifdef HAVE_RB_HASH_DELETE
+VALUE hash_spec_rb_hash_delete(VALUE self, VALUE hash, VALUE key) {
+  return rb_hash_delete(hash, key);
+}
+#endif
+
+#ifdef HAVE_RB_HASH_FOREACH
+static int foreach_i(VALUE key, VALUE val, VALUE other) {
+  rb_hash_aset(other, key, val);
+  return 0; /* ST_CONTINUE; */
+}
+
+VALUE hash_spec_rb_hash_foreach(VALUE self, VALUE hsh) {
+  VALUE other = rb_hash_new();
+  rb_hash_foreach(hsh, foreach_i, other);
+  return other;
+}
+#endif
+
+#ifdef HAVE_RB_HASH_LOOKUP
+VALUE hash_spec_rb_hash_lookup(VALUE self, VALUE hash, VALUE key) {
+  return rb_hash_lookup(hash, key);
+}
+
+VALUE hash_spec_rb_hash_lookup_nil(VALUE self, VALUE hash, VALUE key) {
+  VALUE ret = rb_hash_lookup(hash, key);
+  return ret == Qnil ? Qtrue : Qfalse;
+}
+#endif
+
+#ifdef HAVE_RB_HASH_NEW
+VALUE hash_spec_rb_hash_new(VALUE self) {
+  return rb_hash_new();
+}
+#endif
+
+#ifdef HAVE_RB_HASH_SIZE
+/* rb_hash_size is a static symbol in MRI */
+VALUE hash_spec_rb_hash_size(VALUE self, VALUE hash) {
+  return rb_hash_size(hash);
+}
+#endif
+
+void Init_hash_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiHashSpecs", rb_cObject);
+
+#ifdef HAVE_RB_HASH_AREF
+  rb_define_method(cls, "rb_hash_aref", hash_spec_rb_hash_aref, 2);
+  rb_define_method(cls, "rb_hash_aref_nil", hash_spec_rb_hash_aref_nil, 2);
+#endif
+
+#ifdef HAVE_RB_HASH_ASET
+  rb_define_method(cls, "rb_hash_aset", hash_spec_rb_hash_aset, 3);
+#endif
+
+#ifdef HAVE_RB_HASH_DELETE
+  rb_define_method(cls, "rb_hash_delete", hash_spec_rb_hash_delete, 2);
+#endif
+
+#ifdef HAVE_RB_HASH_FOREACH
+  rb_define_method(cls, "rb_hash_foreach", hash_spec_rb_hash_foreach, 1);
+#endif
+
+#ifdef HAVE_RB_HASH_LOOKUP
+  rb_define_method(cls, "rb_hash_lookup_nil", hash_spec_rb_hash_lookup_nil, 2);
+  rb_define_method(cls, "rb_hash_lookup", hash_spec_rb_hash_lookup, 2);
+#endif
+
+#ifdef HAVE_RB_HASH_NEW
+  rb_define_method(cls, "rb_hash_new", hash_spec_rb_hash_new, 0);
+#endif
+
+#ifdef HAVE_RB_HASH_SIZE
+  rb_define_method(cls, "rb_hash_size", hash_spec_rb_hash_size, 1);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/io_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/io_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/io_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,24 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_IO_WRITE
+VALUE io_spec_rb_io_write(VALUE self, VALUE io, VALUE str) {
+  return rb_io_write(io, str);
+}
+#endif
+
+void Init_io_spec() {
+  VALUE cls = rb_define_class("CApiIOSpecs", rb_cObject);
+
+#ifdef HAVE_RB_IO_WRITE
+  rb_define_method(cls, "rb_io_write", io_spec_rb_io_write, 2);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/jruby.h
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/jruby.h	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/jruby.h	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,6 @@
+#ifndef RUBYSPEC_CAPI_JRUBY_H
+#define RUBYSPEC_CAPI_JRUBY_H
+
+/* #undef any HAVE_ defines that JRuby does not have. */
+
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/kernel_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/kernel_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/kernel_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,185 @@
+#include <errno.h>
+
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+VALUE kernel_spec_call_proc(VALUE arg_array) {
+  VALUE arg = rb_ary_pop(arg_array);
+  VALUE proc = rb_ary_pop(arg_array);
+  return rb_funcall(proc, rb_intern("call"), 1, arg);
+}
+
+#ifdef HAVE_RB_BLOCK_GIVEN_P
+static VALUE kernel_spec_rb_block_given_p(VALUE self) {
+  return rb_block_given_p() ? Qtrue : Qfalse;
+}
+#endif
+
+#ifdef HAVE_RB_BLOCK_PROC
+VALUE kernel_spec_rb_block_proc(VALUE self) {
+  return rb_block_proc();
+}
+#endif
+
+#ifdef HAVE_RB_ENSURE
+VALUE kernel_spec_rb_ensure(VALUE self, VALUE main_proc, VALUE arg,
+                            VALUE ensure_proc, VALUE arg2) {
+  VALUE main_array, ensure_array;
+
+  main_array = rb_ary_new();
+  rb_ary_push(main_array, main_proc);
+  rb_ary_push(main_array, arg);
+
+  ensure_array = rb_ary_new();
+  rb_ary_push(ensure_array, ensure_proc);
+  rb_ary_push(ensure_array, arg2);
+
+  return rb_ensure(kernel_spec_call_proc, main_array,
+      kernel_spec_call_proc, ensure_array);
+}
+#endif
+
+#ifdef HAVE_RB_EVAL_STRING
+VALUE kernel_spec_rb_eval_string(VALUE self, VALUE str) {
+  return rb_eval_string(RSTRING_PTR(str));
+}
+#endif
+
+#ifdef HAVE_RB_RAISE
+VALUE kernel_spec_rb_raise(VALUE self, VALUE hash) {
+  rb_hash_aset(hash, ID2SYM(rb_intern("stage")), ID2SYM(rb_intern("before")));
+  rb_raise(rb_eTypeError, "Wrong argument type %s (expected %s)", "Integer", "String");
+  rb_hash_aset(hash, ID2SYM(rb_intern("stage")), ID2SYM(rb_intern("after")));
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_THROW
+VALUE kernel_spec_rb_throw(VALUE self, VALUE result) {
+  rb_throw("foo", result);
+  return ID2SYM(rb_intern("rb_throw_failed"));
+}
+#endif
+
+#ifdef HAVE_RB_RESCUE
+VALUE kernel_spec_rb_rescue(VALUE self, VALUE main_proc, VALUE arg,
+                            VALUE raise_proc, VALUE arg2) {
+  VALUE main_array, raise_array;
+
+  main_array = rb_ary_new();
+  rb_ary_push(main_array, main_proc);
+  rb_ary_push(main_array, arg);
+
+  raise_array = rb_ary_new();
+  rb_ary_push(raise_array, raise_proc);
+  rb_ary_push(raise_array, arg2);
+
+  return rb_rescue(kernel_spec_call_proc, main_array,
+      kernel_spec_call_proc, raise_array);
+}
+#endif
+
+#ifdef HAVE_RB_RESCUE2
+VALUE kernel_spec_rb_rescue2(int argc, VALUE *args, VALUE self) {
+  VALUE main_array, raise_array;
+
+  main_array = rb_ary_new();
+  rb_ary_push(main_array, args[0]);
+  rb_ary_push(main_array, args[1]);
+
+  raise_array = rb_ary_new();
+  rb_ary_push(raise_array, args[2]);
+  rb_ary_push(raise_array, args[3]);
+
+  return rb_rescue2(kernel_spec_call_proc, main_array,
+      kernel_spec_call_proc, raise_array, args[4], args[5], (VALUE)0);
+}
+#endif
+
+#ifdef HAVE_RB_SYS_FAIL
+VALUE kernel_spec_rb_sys_fail(VALUE self, VALUE msg) {
+  errno = 1;
+  rb_sys_fail(StringValuePtr(msg));
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_WARN
+VALUE kernel_spec_rb_warn(VALUE self, VALUE msg) {
+  rb_warn("%s", StringValuePtr(msg));
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_YIELD
+static VALUE kernel_spec_rb_yield(VALUE self, VALUE obj) {
+  return rb_yield(obj);
+}
+#endif
+
+#ifdef HAVE_RB_YIELD_VALUES
+static VALUE kernel_spec_rb_yield_values(VALUE self, VALUE obj1, VALUE obj2) {
+  return rb_yield_values(2, obj1, obj2);
+}
+#endif
+
+void Init_kernel_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiKernelSpecs", rb_cObject);
+
+#ifdef HAVE_RB_BLOCK_GIVEN_P
+  rb_define_method(cls, "rb_block_given_p", kernel_spec_rb_block_given_p, 0);
+#endif
+
+#ifdef HAVE_RB_BLOCK_PROC
+  rb_define_method(cls, "rb_block_proc", kernel_spec_rb_block_proc, 0);
+#endif
+
+#ifdef HAVE_RB_ENSURE
+  rb_define_method(cls, "rb_ensure", kernel_spec_rb_ensure, 4);
+#endif
+
+#ifdef HAVE_RB_EVAL_STRING
+  rb_define_method(cls, "rb_eval_string", kernel_spec_rb_eval_string, 1);
+#endif
+
+#ifdef HAVE_RB_RAISE
+  rb_define_method(cls, "rb_raise", kernel_spec_rb_raise, 1);
+#endif
+
+#ifdef HAVE_RB_THROW
+  rb_define_method(cls, "rb_throw", kernel_spec_rb_throw, 1);
+#endif
+
+#ifdef HAVE_RB_RESCUE
+  rb_define_method(cls, "rb_rescue", kernel_spec_rb_rescue, 4);
+#endif
+
+#ifdef HAVE_RB_RESCUE2
+  rb_define_method(cls, "rb_rescue2", kernel_spec_rb_rescue2, -1);
+#endif
+
+#ifdef HAVE_RB_SYS_FAIL
+  rb_define_method(cls, "rb_sys_fail", kernel_spec_rb_sys_fail, 1);
+#endif
+
+#ifdef HAVE_RB_WARN
+  rb_define_method(cls, "rb_warn", kernel_spec_rb_warn, 1);
+#endif
+
+#ifdef HAVE_RB_YIELD
+  rb_define_method(cls, "rb_yield", kernel_spec_rb_yield, 1);
+#endif
+
+#ifdef HAVE_RB_YIELD_VALUES
+  rb_define_method(cls, "rb_yield_values", kernel_spec_rb_yield_values, 2);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/module_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/module_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/module_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,230 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static VALUE module_specs_test_method(VALUE self) {
+  return ID2SYM(rb_intern("test_method"));
+}
+
+#ifdef HAVE_RB_CONST_DEFINED
+static VALUE module_specs_const_defined(VALUE self, VALUE klass, VALUE id) {
+  return rb_const_defined(klass, SYM2ID(id)) ? Qtrue : Qfalse;
+}
+#endif
+
+#ifdef HAVE_RB_CONST_DEFINED_AT
+static VALUE module_specs_const_defined_at(VALUE self, VALUE klass, VALUE id) {
+  return rb_const_defined_at(klass, SYM2ID(id)) ? Qtrue : Qfalse;
+}
+#endif
+
+#ifdef HAVE_RB_CONST_GET
+static VALUE module_specs_const_get(VALUE self, VALUE klass, VALUE val) {
+  return rb_const_get(klass, SYM2ID(val));
+}
+#endif
+
+#ifdef HAVE_RB_CONST_GET_AT
+static VALUE module_specs_const_get_at(VALUE self, VALUE klass, VALUE val) {
+  return rb_const_get_at(klass, SYM2ID(val));
+}
+#endif
+
+#ifdef HAVE_RB_CONST_GET_FROM
+static VALUE module_specs_const_get_from(VALUE self, VALUE klass, VALUE val) {
+  return rb_const_get_from(klass, SYM2ID(val));
+}
+#endif
+
+#ifdef HAVE_RB_CONST_SET
+static VALUE module_specs_const_set(VALUE self, VALUE klass, VALUE name, VALUE val) {
+  rb_const_set(klass, SYM2ID(name), val);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_DEFINE_ALIAS
+static VALUE module_specs_rb_define_alias(VALUE self, VALUE obj,
+  VALUE new_name, VALUE old_name) {
+
+  rb_define_alias(obj, RSTRING_PTR(new_name), RSTRING_PTR(old_name));
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_DEFINE_CLASS_UNDER
+static VALUE module_specs_rb_define_class_under(VALUE self, VALUE outer,
+                                                 VALUE name, VALUE super) {
+  if(NIL_P(super)) super = 0;
+  return rb_define_class_under(outer, RSTRING_PTR(name), super);
+}
+#endif
+
+#ifdef HAVE_RB_DEFINE_MODULE_UNDER
+static VALUE module_specs_rb_define_module_under(VALUE self, VALUE outer, VALUE name) {
+  return rb_define_module_under(outer, RSTRING_PTR(name));
+}
+#endif
+
+#ifdef HAVE_RB_DEFINE_CONST
+static VALUE module_specs_define_const(VALUE self, VALUE klass, VALUE str_name, VALUE val) {
+  rb_define_const(klass, RSTRING_PTR(str_name), val);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_DEFINE_GLOBAL_CONST
+static VALUE module_specs_define_global_const(VALUE self, VALUE str_name, VALUE obj) {
+  rb_define_global_const(RSTRING_PTR(str_name), obj);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_DEFINE_GLOBAL_FUNCTION
+static VALUE module_specs_rb_define_global_function(VALUE self, VALUE str_name) {
+  rb_define_global_function(RSTRING_PTR(str_name), module_specs_test_method, 0);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_DEFINE_METHOD
+static VALUE module_specs_rb_define_method(VALUE self, VALUE cls, VALUE str_name) {
+  rb_define_method(cls, RSTRING_PTR(str_name), module_specs_test_method, 0);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_DEFINE_MODULE_FUNCTION
+static VALUE module_specs_rb_define_module_function(VALUE self, VALUE cls, VALUE str_name) {
+  rb_define_module_function(cls, RSTRING_PTR(str_name), module_specs_test_method, 0);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_DEFINE_PRIVATE_METHOD
+static VALUE module_specs_rb_define_private_method(VALUE self, VALUE cls, VALUE str_name) {
+  rb_define_private_method(cls, RSTRING_PTR(str_name), module_specs_test_method, 0);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_DEFINE_PROTECTED_METHOD
+static VALUE module_specs_rb_define_protected_method(VALUE self, VALUE cls, VALUE str_name) {
+  rb_define_protected_method(cls, RSTRING_PTR(str_name), module_specs_test_method, 0);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_DEFINE_SINGLETON_METHOD
+static VALUE module_specs_rb_define_singleton_method(VALUE self, VALUE cls, VALUE str_name) {
+  rb_define_singleton_method(cls, RSTRING_PTR(str_name), module_specs_test_method, 0);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_UNDEF_METHOD
+static VALUE module_specs_rb_undef_method(VALUE self, VALUE cls, VALUE str_name) {
+  rb_undef_method(cls, RSTRING_PTR(str_name));
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_CLASS2NAME
+static VALUE module_specs_rbclass2name(VALUE self, VALUE klass) {
+  return rb_str_new2(rb_class2name(klass));
+}
+#endif
+
+void Init_module_spec() {
+  VALUE cls;
+
+  cls = rb_define_class("CApiModuleSpecs", rb_cObject);
+
+#ifdef HAVE_RB_CONST_DEFINED
+  rb_define_method(cls, "rb_const_defined", module_specs_const_defined, 2);
+#endif
+
+#ifdef HAVE_RB_CONST_DEFINED_AT
+  rb_define_method(cls, "rb_const_defined_at", module_specs_const_defined_at, 2);
+#endif
+
+#ifdef HAVE_RB_CONST_GET
+  rb_define_method(cls, "rb_const_get", module_specs_const_get, 2);
+#endif
+
+#ifdef HAVE_RB_CONST_GET_AT
+  rb_define_method(cls, "rb_const_get_at", module_specs_const_get_at, 2);
+#endif
+
+#ifdef HAVE_RB_CONST_GET_FROM
+  rb_define_method(cls, "rb_const_get_from", module_specs_const_get_from, 2);
+#endif
+
+#ifdef HAVE_RB_CONST_SET
+  rb_define_method(cls, "rb_const_set", module_specs_const_set, 3);
+#endif
+
+#ifdef HAVE_RB_DEFINE_ALIAS
+  rb_define_method(cls, "rb_define_alias", module_specs_rb_define_alias, 3);
+#endif
+
+#ifdef HAVE_RB_DEFINE_CLASS_UNDER
+  rb_define_method(cls, "rb_define_class_under", module_specs_rb_define_class_under, 3);
+#endif
+
+#ifdef HAVE_RB_DEFINE_MODULE_UNDER
+  rb_define_method(cls, "rb_define_module_under", module_specs_rb_define_module_under, 2);
+#endif
+
+#ifdef HAVE_RB_DEFINE_CONST
+  rb_define_method(cls, "rb_define_const", module_specs_define_const, 3);
+#endif
+
+#ifdef HAVE_RB_DEFINE_GLOBAL_CONST
+  rb_define_method(cls, "rb_define_global_const", module_specs_define_global_const, 2);
+#endif
+
+#ifdef HAVE_RB_DEFINE_GLOBAL_FUNCTION
+  rb_define_method(cls, "rb_define_global_function",
+      module_specs_rb_define_global_function, 1);
+#endif
+
+#ifdef HAVE_RB_DEFINE_METHOD
+  rb_define_method(cls, "rb_define_method", module_specs_rb_define_method, 2);
+#endif
+
+#ifdef HAVE_RB_DEFINE_MODULE_FUNCTION
+  rb_define_method(cls, "rb_define_module_function",
+      module_specs_rb_define_module_function, 2);
+#endif
+
+#ifdef HAVE_RB_DEFINE_PRIVATE_METHOD
+  rb_define_method(cls, "rb_define_private_method",
+      module_specs_rb_define_private_method, 2);
+#endif
+
+#ifdef HAVE_RB_DEFINE_PROTECTED_METHOD
+  rb_define_method(cls, "rb_define_protected_method",
+      module_specs_rb_define_protected_method, 2);
+#endif
+
+#ifdef HAVE_RB_DEFINE_SINGLETON_METHOD
+  rb_define_method(cls, "rb_define_singleton_method",
+      module_specs_rb_define_singleton_method, 2);
+#endif
+
+#ifdef HAVE_RB_UNDEF_METHOD
+  rb_define_method(cls, "rb_undef_method", module_specs_rb_undef_method, 2);
+#endif
+
+#ifdef HAVE_RB_CLASS2NAME
+  rb_define_method(cls, "rb_class2name", module_specs_rbclass2name, 1);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/mri.h
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/mri.h	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/mri.h	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,48 @@
+#ifndef RUBYSPEC_CAPI_MRI_H
+#define RUBYSPEC_CAPI_MRI_H
+
+/* #undef any HAVE_ defines that MRI does not have. */
+#undef HAVE_RB_HASH_LOOKUP
+#undef HAVE_RB_HASH_SIZE
+
+#undef HAVE_RB_OBJ_FROZEN_P
+
+#undef HAVE_RB_STR_PTR
+#undef HAVE_RB_STR_PTR_READONLY
+
+#undef HAVE_THREAD_BLOCKING_REGION
+
+#ifdef RUBY_VERSION_IS_1_9
+#undef HAVE_RARRAY
+#undef HAVE_RFLOAT
+#undef HAVE_RSTRING
+#undef HAVE_STR2CSTR
+#undef HAVE_RB_STR2CSTR
+#undef HAVE_RB_SET_KCODE
+#endif
+
+/* RubySpec assumes following are public API */
+#ifndef rb_proc_new
+VALUE rb_proc_new _((VALUE (*)(ANYARGS/* VALUE yieldarg[, VALUE procarg] */), VALUE));
+#endif
+#ifndef rb_str_len
+int rb_str_len(VALUE);
+#endif
+#ifndef rb_set_errinfo
+void rb_set_errinfo(VALUE);
+#endif
+
+/* Macros that may not be defined in old versions */
+#ifndef RARRAY_PTR
+#define RARRAY_PTR(s) (*(VALUE *const *)&RARRAY(s)->ptr)
+#endif
+
+#ifndef RARRAY_LEN
+#define RARRAY_LEN(s) (*(const long *)&RARRAY(s)->len)
+#endif
+
+#ifndef RFLOAT_VALUE
+#define RFLOAT_VALUE(v) (RFLOAT(v)->value)
+#endif
+
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/numeric_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/numeric_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/numeric_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,85 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_NUM2CHR
+static VALUE numeric_spec_NUM2CHR(VALUE self, VALUE value) {
+  return INT2FIX(NUM2CHR(value));
+}
+#endif
+
+#ifdef HAVE_RB_INT2INUM
+static VALUE numeric_spec_rb_int2inum_14(VALUE self) {
+  return rb_int2inum(14);
+}
+#endif
+
+#ifdef HAVE_RB_INTEGER
+static VALUE numeric_spec_rb_Integer(VALUE self, VALUE str) {
+  return rb_Integer(str);
+}
+#endif
+
+#ifdef HAVE_RB_LL2INUM
+static VALUE numeric_spec_rb_ll2inum_14(VALUE self) {
+  return rb_ll2inum(14);
+}
+#endif
+
+#ifdef HAVE_RB_NUM2DBL
+static VALUE numeric_spec_rb_num2dbl(VALUE self, VALUE num) {
+  return rb_float_new(rb_num2dbl(num));
+}
+#endif
+
+#ifdef HAVE_RB_NUM2LONG
+static VALUE numeric_spec_rb_num2long(VALUE self, VALUE num) {
+  return LONG2NUM(rb_num2long(num));
+}
+#endif
+
+#ifdef HAVE_RB_NUM2ULONG
+static VALUE numeric_spec_rb_num2ulong(VALUE self, VALUE num) {
+  return ULONG2NUM(rb_num2ulong(num));
+}
+#endif
+
+void Init_numeric_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiNumericSpecs", rb_cObject);
+
+#ifdef HAVE_NUM2CHR
+  rb_define_method(cls, "NUM2CHR", numeric_spec_NUM2CHR, 1);
+#endif
+
+#ifdef HAVE_RB_INT2INUM
+  rb_define_method(cls, "rb_int2inum_14", numeric_spec_rb_int2inum_14, 0);
+#endif
+
+#ifdef HAVE_RB_INTEGER
+  rb_define_method(cls, "rb_Integer", numeric_spec_rb_Integer, 1);
+#endif
+
+#ifdef HAVE_RB_LL2INUM
+  rb_define_method(cls, "rb_ll2inum_14", numeric_spec_rb_ll2inum_14, 0);
+#endif
+
+#ifdef HAVE_RB_NUM2DBL
+  rb_define_method(cls, "rb_num2dbl", numeric_spec_rb_num2dbl, 1);
+#endif
+
+#ifdef HAVE_RB_NUM2LONG
+  rb_define_method(cls, "rb_num2long", numeric_spec_rb_num2long, 1);
+#endif
+
+#ifdef HAVE_RB_NUM2ULONG
+  rb_define_method(cls, "rb_num2ulong", numeric_spec_rb_num2ulong, 1);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/object_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/object_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/object_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,356 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_OBJ_TAINT
+static VALUE object_spec_OBJ_TAINT(VALUE self, VALUE obj) {
+  OBJ_TAINT(obj);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_OBJ_TAINTED
+static VALUE object_spec_OBJ_TAINTED(VALUE self, VALUE obj) {
+  return OBJ_TAINTED(obj) ? Qtrue : Qfalse;
+}
+#endif
+
+#ifdef HAVE_RB_ANY_TO_S
+static VALUE object_spec_rb_any_to_s(VALUE self, VALUE obj) {
+  return rb_any_to_s(obj);
+}
+#endif
+
+#ifdef HAVE_RB_ATTR_GET
+static VALUE so_attr_get(VALUE self, VALUE obj, VALUE attr) {
+  return rb_attr_get(obj, SYM2ID(attr));
+}
+#endif
+
+#ifdef HAVE_RB_CHECK_ARRAY_TYPE
+static VALUE so_check_array_type(VALUE self, VALUE ary) {
+  return rb_check_array_type(ary);
+}
+#endif
+
+#ifdef HAVE_RB_CHECK_CONVERT_TYPE
+static VALUE so_check_convert_type(VALUE self, VALUE obj) {
+  return rb_check_convert_type(obj, T_ARRAY, "Array", "to_ary");
+}
+#endif
+
+#ifdef HAVE_RB_CHECK_FROZEN
+static VALUE object_spec_rb_check_frozen(VALUE self, VALUE obj) {
+  rb_check_frozen(obj);
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_CHECK_STRING_TYPE
+static VALUE so_check_string_type(VALUE self, VALUE str) {
+  return rb_check_string_type(str);
+}
+#endif
+
+#ifdef HAVE_RB_CLASS_OF
+static VALUE so_rbclassof(VALUE self, VALUE obj) {
+  return rb_class_of(obj);
+}
+#endif
+
+#ifdef HAVE_RB_CONVERT_TYPE
+static VALUE so_convert_type(VALUE self, VALUE obj) {
+  return rb_convert_type(obj, T_ARRAY, "Array", "to_ary");
+}
+#endif
+
+#ifdef HAVE_RB_EXTEND_OBJECT
+static VALUE object_spec_rb_extend_object(VALUE self, VALUE obj, VALUE mod) {
+  rb_extend_object(obj, mod);
+  return obj;
+}
+#endif
+
+#ifdef HAVE_RB_INSPECT
+static VALUE so_inspect(VALUE self, VALUE obj) {
+  return rb_inspect(obj);
+}
+#endif
+
+#ifdef HAVE_RB_OBJ_ALLOC
+static VALUE so_rb_obj_alloc(VALUE self, VALUE klass) {
+  return rb_obj_alloc(klass);
+}
+#endif
+
+#ifdef HAVE_RB_OBJ_CALL_INIT
+static VALUE so_rb_obj_call_init(VALUE self, VALUE object,
+                                 VALUE nargs, VALUE args) {
+  int c_nargs = FIX2INT(nargs);
+  VALUE c_args[c_nargs];
+  int i;
+
+  for (i = 0; i < c_nargs; i++)
+    c_args[i] = rb_ary_entry(args, i);
+
+  rb_obj_call_init(object, c_nargs, c_args);
+
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_OBJ_CLASSNAME
+static VALUE so_rbobjclassname(VALUE self, VALUE obj) {
+  return rb_str_new2(rb_obj_classname(obj));
+}
+
+#endif
+
+#ifdef HAVE_RB_OBJ_FREEZE
+static VALUE object_spec_rb_obj_freeze(VALUE self, VALUE obj) {
+  return rb_obj_freeze(obj);
+}
+#endif
+
+#ifdef HAVE_RB_OBJ_FROZEN_P
+static VALUE object_spec_rb_obj_frozen_p(VALUE self, VALUE obj) {
+  return rb_obj_frozen_p(obj);
+}
+#endif
+
+#ifdef HAVE_RB_OBJ_ID
+static VALUE object_spec_rb_obj_id(VALUE self, VALUE obj) {
+  return rb_obj_id(obj);
+}
+#endif
+
+#ifdef HAVE_RB_OBJ_IS_INSTANCE_OF
+static VALUE so_instance_of(VALUE self, VALUE obj, VALUE klass) {
+  return rb_obj_is_instance_of(obj, klass);
+}
+#endif
+
+#ifdef HAVE_RB_OBJ_IS_KIND_OF
+static VALUE so_kind_of(VALUE self, VALUE obj, VALUE klass) {
+  return rb_obj_is_kind_of(obj, klass);
+}
+#endif
+
+#ifdef HAVE_RB_OBJ_TAINT
+static VALUE object_spec_rb_obj_taint(VALUE self, VALUE obj) {
+  return rb_obj_taint(obj);
+}
+#endif
+
+#ifdef HAVE_RB_REQUIRE
+static VALUE so_require(VALUE self) {
+  rb_require("fixtures/foo");
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_RESPOND_TO
+static VALUE so_respond_to(VALUE self, VALUE obj, VALUE sym) {
+  return rb_respond_to(obj, SYM2ID(sym)) ? Qtrue : Qfalse;
+}
+#endif
+
+#ifdef HAVE_RB_SPECIAL_CONST_P
+static VALUE object_spec_rb_special_const_p(VALUE self, VALUE value) {
+  return rb_special_const_p(value);
+}
+#endif
+
+#ifdef HAVE_RB_TO_ID
+static VALUE so_to_id(VALUE self, VALUE obj) {
+  return ID2SYM(rb_to_id(obj));
+}
+#endif
+
+#ifdef HAVE_RTEST
+static VALUE object_spec_RTEST(VALUE self, VALUE value) {
+  return RTEST(value) ? Qtrue : Qfalse;
+}
+#endif
+
+#ifdef HAVE_TYPE
+static VALUE so_is_type_nil(VALUE self, VALUE obj) {
+  if(TYPE(obj) == T_NIL) {
+    return Qtrue;
+  }
+  return Qfalse;
+}
+
+static VALUE so_is_type_object(VALUE self, VALUE obj) {
+  if(TYPE(obj) == T_OBJECT) {
+    return Qtrue;
+  }
+  return Qfalse;
+}
+
+static VALUE so_is_type_array(VALUE self, VALUE obj) {
+  if(TYPE(obj) == T_ARRAY) {
+    return Qtrue;
+  }
+  return Qfalse;
+}
+
+static VALUE so_is_type_module(VALUE self, VALUE obj) {
+  if(TYPE(obj) == T_MODULE) {
+    return Qtrue;
+  }
+  return Qfalse;
+}
+
+static VALUE so_is_type_class(VALUE self, VALUE obj) {
+  if(TYPE(obj) == T_CLASS) {
+    return Qtrue;
+  }
+  return Qfalse;
+}
+
+static VALUE so_is_type_data(VALUE self, VALUE obj) {
+  if(TYPE(obj) == T_DATA) {
+    return Qtrue;
+  }
+  return Qfalse;
+}
+#endif
+
+#ifdef HAVE_RB_TO_INT
+static VALUE object_spec_rb_to_int(VALUE self, VALUE obj) {
+  return rb_to_int(obj);
+}
+#endif
+
+void Init_object_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiObjectSpecs", rb_cObject);
+
+#ifdef HAVE_OBJ_TAINT
+  rb_define_method(cls, "OBJ_TAINT", object_spec_OBJ_TAINT, 1);
+#endif
+
+#ifdef HAVE_OBJ_TAINTED
+  rb_define_method(cls, "OBJ_TAINTED", object_spec_OBJ_TAINTED, 1);
+#endif
+
+#ifdef HAVE_RB_ANY_TO_S
+  rb_define_method(cls, "rb_any_to_s", object_spec_rb_any_to_s, 1);
+#endif
+
+#ifdef HAVE_RB_ATTR_GET
+  rb_define_method(cls, "rb_attr_get", so_attr_get, 2);
+#endif
+
+#ifdef HAVE_RB_CHECK_ARRAY_TYPE
+  rb_define_method(cls, "rb_check_array_type", so_check_array_type, 1);
+#endif
+
+#ifdef HAVE_RB_CHECK_CONVERT_TYPE
+  rb_define_method(cls, "rb_check_convert_type", so_check_convert_type, 1);
+#endif
+
+#ifdef HAVE_RB_CHECK_FROZEN
+  rb_define_method(cls, "rb_check_frozen", object_spec_rb_check_frozen, 1);
+#endif
+
+#ifdef HAVE_RB_CHECK_STRING_TYPE
+  rb_define_method(cls, "rb_check_string_type", so_check_string_type, 1);
+#endif
+
+#ifdef HAVE_RB_CLASS_OF
+  rb_define_method(cls, "rb_class_of", so_rbclassof, 1);
+#endif
+
+#ifdef HAVE_RB_CONVERT_TYPE
+  rb_define_method(cls, "rb_convert_type", so_convert_type, 1);
+#endif
+
+#ifdef HAVE_RB_EXTEND_OBJECT
+  rb_define_method(cls, "rb_extend_object", object_spec_rb_extend_object, 2);
+#endif
+
+#ifdef HAVE_RB_INSPECT
+  rb_define_method(cls, "rb_inspect", so_inspect, 1);
+#endif
+
+#ifdef HAVE_RB_OBJ_ALLOC
+  rb_define_method(cls, "rb_obj_alloc", so_rb_obj_alloc, 1);
+#endif
+
+#ifdef HAVE_RB_OBJ_CALL_INIT
+  rb_define_method(cls, "rb_obj_call_init", so_rb_obj_call_init, 3);
+#endif
+
+#ifdef HAVE_RB_OBJ_CLASSNAME
+  rb_define_method(cls, "rb_obj_classname", so_rbobjclassname, 1);
+#endif
+
+#ifdef HAVE_RB_OBJ_FREEZE
+  rb_define_method(cls, "rb_obj_freeze", object_spec_rb_obj_freeze, 1);
+#endif
+
+#ifdef HAVE_RB_OBJ_FROZEN_P
+  rb_define_method(cls, "rb_obj_frozen_p", object_spec_rb_obj_frozen_p, 1);
+#endif
+
+#ifdef HAVE_RB_OBJ_ID
+  rb_define_method(cls, "rb_obj_id", object_spec_rb_obj_id, 1);
+#endif
+
+#ifdef HAVE_RB_OBJ_IS_INSTANCE_OF
+  rb_define_method(cls, "rb_obj_is_instance_of", so_instance_of, 2);
+#endif
+
+#ifdef HAVE_RB_OBJ_IS_KIND_OF
+  rb_define_method(cls, "rb_obj_is_kind_of", so_kind_of, 2);
+#endif
+
+#ifdef HAVE_RB_OBJ_TAINT
+  rb_define_method(cls, "rb_obj_taint", object_spec_rb_obj_taint, 1);
+#endif
+
+#ifdef HAVE_RB_REQUIRE
+  rb_define_method(cls, "rb_require", so_require, 0);
+#endif
+
+#ifdef HAVE_RB_RESPOND_TO
+  rb_define_method(cls, "rb_respond_to", so_respond_to, 2);
+#endif
+
+#ifdef HAVE_RB_SPECIAL_CONST_P
+  rb_define_method(cls, "rb_special_const_p", object_spec_rb_special_const_p, 1);
+#endif
+
+#ifdef HAVE_RB_STR_NEW2
+#endif
+
+#ifdef HAVE_RB_TO_ID
+  rb_define_method(cls, "rb_to_id", so_to_id, 1);
+#endif
+
+#ifdef HAVE_RTEST
+  rb_define_method(cls, "RTEST", object_spec_RTEST, 1);
+#endif
+
+#ifdef HAVE_TYPE
+  rb_define_method(cls, "rb_is_type_nil", so_is_type_nil, 1);
+  rb_define_method(cls, "rb_is_type_object", so_is_type_object, 1);
+  rb_define_method(cls, "rb_is_type_array", so_is_type_array, 1);
+  rb_define_method(cls, "rb_is_type_module", so_is_type_module, 1);
+  rb_define_method(cls, "rb_is_type_class", so_is_type_class, 1);
+  rb_define_method(cls, "rb_is_type_data", so_is_type_data, 1);
+#endif
+
+#ifdef HAVE_RB_TO_INT
+  rb_define_method(cls, "rb_to_int", object_spec_rb_to_int, 1);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/proc_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/proc_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/proc_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,62 @@
+#include <string.h>
+
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_PROC_NEW
+VALUE concat_func0(int argc, VALUE *argv) {
+#define BUFLEN 500
+  int i, len = 0;
+  char buffer[BUFLEN] = {0};
+
+  for (i = 0; i < argc; ++i) {
+    VALUE v = argv[i];
+    len += RSTRING_LEN(v) + 1;
+    if (len > BUFLEN - 1) return Qnil;
+    strcat(buffer, StringValuePtr(v));
+    strcat(buffer, "_");
+  }
+
+  buffer[len - 1] = 0;
+  return rb_str_new2(buffer);
+}
+#endif
+
+#ifdef HAVE_RB_PROC_NEW
+#ifdef RUBY_VERSION_IS_1_8
+VALUE concat_func(VALUE args) {
+  return concat_func0(RARRAY_LEN(args), RARRAY_PTR(args));
+}
+#endif
+#endif
+
+#ifdef HAVE_RB_PROC_NEW
+#ifdef RUBY_VERSION_IS_1_9
+VALUE concat_func(VALUE arg1, VALUE val, int argc, VALUE *argv, VALUE passed_proc) {
+  return concat_func0(argc, argv);
+}
+#endif
+#endif
+
+#ifdef HAVE_RB_PROC_NEW
+VALUE sp_underline_concat_proc(VALUE self) {
+  return rb_proc_new(concat_func, Qnil);
+}
+#endif
+
+void Init_proc_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiProcSpecs", rb_cObject);
+
+#ifdef HAVE_RB_PROC_NEW
+  rb_define_method(cls, "underline_concat_proc", sp_underline_concat_proc, 0);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/range_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/range_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/range_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,29 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_RANGE_NEW
+VALUE range_spec_rb_range_new(int argc, VALUE* argv, VALUE self) {
+  int exclude_end = 0;
+  if(argc == 3) {
+    exclude_end = RTEST(argv[2]);
+  }
+  return rb_range_new(argv[0], argv[1], exclude_end);
+}
+#endif
+
+void Init_range_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiRangeSpecs", rb_cObject);
+
+#ifdef HAVE_RB_RANGE_NEW
+  rb_define_method(cls, "rb_range_new", range_spec_rb_range_new, -1);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/rubinius.h
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/rubinius.h	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/rubinius.h	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,10 @@
+#ifndef RUBYSPEC_CAPI_RUBINIUS_H
+#define RUBYSPEC_CAPI_RUBINIUS_H
+
+/* #undef any HAVE_ defines that Rubinius does not have. */
+#undef HAVE_RB_DEFINE_HOOKED_VARIABLE
+#undef HAVE_RB_DEFINE_VARIABLE
+
+#undef HAVE_RB_PROC_NEW
+
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/rubyspec.h
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/rubyspec.h	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/rubyspec.h	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,313 @@
+#ifndef RUBYSPEC_H
+#define RUBYSPEC_H
+/* First define all function flags */
+
+/* Array */
+#define HAVE_RARRAY                        1
+#define HAVE_RARRAY_LEN                    1
+#define HAVE_RARRAY_PTR                    1
+#define HAVE_RB_ARY_AREF                   1
+#define HAVE_RB_ARY_CLEAR                  1
+#define HAVE_RB_ARY_DELETE                 1
+#define HAVE_RB_ARY_DUP                    1
+#define HAVE_RB_ARY_ENTRY                  1
+#define HAVE_RB_ARY_INCLUDES               1
+#define HAVE_RB_ARY_JOIN                   1
+#define HAVE_RB_ARY_NEW                    1
+#define HAVE_RB_ARY_NEW2                   1
+#define HAVE_RB_ARY_POP                    1
+#define HAVE_RB_ARY_PUSH                   1
+#define HAVE_RB_ARY_REVERSE                1
+#define HAVE_RB_ARY_SHIFT                  1
+#define HAVE_RB_ARY_STORE                  1
+#define HAVE_RB_ARY_UNSHIFT                1
+#define HAVE_RB_ASSOC_NEW                  1
+
+#define HAVE_RB_EACH                       1
+#define HAVE_RB_ITERATE                    1
+
+/* Bignum */
+#define HAVE_RB_BIG2DBL                    1
+#define HAVE_RB_BIG2LL                     1
+#define HAVE_RB_BIG2LONG                   1
+#define HAVE_RB_BIG2STR                    1
+#define HAVE_RB_BIG2ULONG                  1
+
+/* Class */
+#define HAVE_RB_CALL_SUPER                 1
+#define HAVE_RB_CLASS2NAME                 1
+#define HAVE_RB_CLASS_INHERITED            1
+#define HAVE_RB_CLASS_NEW                  1
+#define HAVE_RB_CLASS_NEW_INSTANCE         1
+#define HAVE_RB_CVAR_DEFINED               1
+#define HAVE_RB_CVAR_GET                   1
+#define HAVE_RB_CVAR_SET                   1
+#define HAVE_RB_CV_GET                     1
+#define HAVE_RB_CV_SET                     1
+#define HAVE_RB_DEFINE_ATTR                1
+#define HAVE_RB_DEFINE_CLASS_VARIABLE      1
+#define HAVE_RB_INCLUDE_MODULE             1
+
+/* Constants */
+#define HAVE_RB_CARRAY                     1
+#define HAVE_RB_CBIGNUM                    1
+#define HAVE_RB_CCLASS                     1
+#define HAVE_RB_CDATA                      1
+#define HAVE_RB_CFALSECLASS                1
+#define HAVE_RB_CFILE                      1
+#define HAVE_RB_CFIXNUM                    1
+#define HAVE_RB_CFLOAT                     1
+#define HAVE_RB_CHASH                      1
+#define HAVE_RB_CINTEGER                   1
+#define HAVE_RB_CIO                        1
+#define HAVE_RB_CMODULE                    1
+#define HAVE_RB_CMATCH                     1
+#define HAVE_RB_CNILCLASS                  1
+#define HAVE_RB_CNUMERIC                   1
+#define HAVE_RB_COBJECT                    1
+#define HAVE_RB_CRANGE                     1
+#define HAVE_RB_CREGEXP                    1
+#define HAVE_RB_CSTRING                    1
+#define HAVE_RB_CSTRUCT                    1
+#define HAVE_RB_CSYMBOL                    1
+#define HAVE_RB_CTHREAD                    1
+#define HAVE_RB_CTRUECLASS                 1
+#define HAVE_RB_CPROC                      1
+#define HAVE_RB_MCOMPARABLE                1
+#define HAVE_RB_MENUMERABLE                1
+#define HAVE_RB_MKERNEL                    1
+#define HAVE_RB_EARGERROR                  1
+#define HAVE_RB_EEOFERROR                  1
+#define HAVE_RB_MERRNO                     1
+#define HAVE_RB_EEXCEPTION                 1
+#define HAVE_RB_EFLOATDOMAINERROR          1
+#define HAVE_RB_EINDEXERROR                1
+#define HAVE_RB_EINTERRUPT                 1
+#define HAVE_RB_EIOERROR                   1
+#define HAVE_RB_ELOADERROR                 1
+#define HAVE_RB_ELOCALJUMPERROR            1
+#define HAVE_RB_ENAMEERROR                 1
+#define HAVE_RB_ENOMEMERROR                1
+#define HAVE_RB_ENOMETHODERROR             1
+#define HAVE_RB_ENOTIMPERROR               1
+#define HAVE_RB_ERANGEERROR                1
+#define HAVE_RB_EREGEXPERROR               1
+#define HAVE_RB_ERUNTIMEERROR              1
+#define HAVE_RB_ESCRIPTERROR               1
+#define HAVE_RB_ESECURITYERROR             1
+#define HAVE_RB_ESIGNAL                    1
+#define HAVE_RB_ESTANDARDERROR             1
+#define HAVE_RB_ESYNTAXERROR               1
+#define HAVE_RB_ESYSTEMCALLERROR           1
+#define HAVE_RB_ESYSTEMEXIT                1
+#define HAVE_RB_ESYSSTACKERROR             1
+#define HAVE_RB_ETYPEERROR                 1
+#define HAVE_RB_ETHREADERROR               1
+#define HAVE_RB_EZERODIVERROR              1
+
+/* Data */
+#define HAVE_DATA_WRAP_STRUCT              1
+#define HAVE_RDATA                         1
+
+/* Exception */
+#define HAVE_RB_EXC_NEW                    1
+#define HAVE_RB_EXC_NEW2                   1
+#define HAVE_RB_EXC_NEW3                   1
+#define HAVE_RB_EXC_RAISE                  1
+#define HAVE_RB_SET_ERRINFO                1
+
+/* Float */
+#define HAVE_RB_FLOAT_NEW                  1
+#define HAVE_RB_RFLOAT                     1
+#define HAVE_RFLOAT                        1
+
+/* Globals */
+#define HAVE_RB_DEFINE_HOOKED_VARIABLE     1
+#define HAVE_RB_DEFINE_READONLY_VARIABLE   1
+#define HAVE_RB_DEFINE_VARIABLE            1
+#define HAVE_RB_F_GLOBAL_VARIABLES         1
+#define HAVE_RB_GV_GET                     1
+#define HAVE_RB_GV_SET                     1
+#define HAVE_RB_SET_KCODE                  1
+
+/* Hash */
+#define HAVE_RB_HASH_AREF                  1
+#define HAVE_RB_HASH_ASET                  1
+#define HAVE_RB_HASH_DELETE                1
+#define HAVE_RB_HASH_FOREACH               1
+#define HAVE_RB_HASH_LOOKUP                1
+#define HAVE_RB_HASH_NEW                   1
+#define HAVE_RB_HASH_SIZE                  1
+
+/* IO */
+#define HAVE_RB_IO_WRITE                   1
+
+/* Kernel */
+#define HAVE_RB_BLOCK_GIVEN_P              1
+#define HAVE_RB_BLOCK_PROC                 1
+#define HAVE_RB_ENSURE                     1
+#define HAVE_RB_EVAL_STRING                1
+#define HAVE_RB_RAISE                      1
+#define HAVE_RB_THROW                      1
+#define HAVE_RB_RESCUE                     1
+#define HAVE_RB_RESCUE2                    1
+#define HAVE_RB_SYS_FAIL                   1
+#define HAVE_RB_WARN                       1
+#define HAVE_RB_YIELD                      1
+#define HAVE_RB_YIELD_VALUES               1
+/* GC */
+#define HAVE_RB_GC_REGISTER_ADDRESS        1
+
+/* Module */
+#define HAVE_RB_CONST_DEFINED              1
+#define HAVE_RB_CONST_DEFINED_AT           1
+#define HAVE_RB_CONST_GET                  1
+#define HAVE_RB_CONST_GET_AT               1
+#define HAVE_RB_CONST_GET_FROM             1
+#define HAVE_RB_CONST_SET                  1
+#define HAVE_RB_DEFINE_ALIAS               1
+#define HAVE_RB_DEFINE_CLASS_UNDER         1
+#define HAVE_RB_DEFINE_MODULE_UNDER        1
+#define HAVE_RB_DEFINE_CONST               1
+#define HAVE_RB_DEFINE_GLOBAL_CONST        1
+#define HAVE_RB_DEFINE_GLOBAL_FUNCTION     1
+#define HAVE_RB_DEFINE_METHOD              1
+#define HAVE_RB_DEFINE_MODULE_FUNCTION     1
+#define HAVE_RB_DEFINE_PRIVATE_METHOD      1
+#define HAVE_RB_DEFINE_PROTECTED_METHOD    1
+#define HAVE_RB_DEFINE_SINGLETON_METHOD    1
+#define HAVE_RB_UNDEF_METHOD               1
+
+/* Numeric */
+#define HAVE_NUM2CHR                       1
+#define HAVE_RB_INT2INUM                   1
+#define HAVE_RB_INTEGER                    1
+#define HAVE_RB_LL2INUM                    1
+#define HAVE_RB_NUM2DBL                    1
+#define HAVE_RB_NUM2LONG                   1
+#define HAVE_RB_NUM2ULONG                  1
+
+/* Object */
+#define HAVE_OBJ_TAINT                     1
+#define HAVE_OBJ_TAINTED                   1
+#define HAVE_RB_ANY_TO_S                   1
+#define HAVE_RB_ATTR_GET                   1
+#define HAVE_RB_CHECK_ARRAY_TYPE           1
+#define HAVE_RB_CHECK_CONVERT_TYPE         1
+#define HAVE_RB_CHECK_FROZEN               1
+#define HAVE_RB_CHECK_STRING_TYPE          1
+#define HAVE_RB_CLASS_OF                   1
+#define HAVE_RB_CONVERT_TYPE               1
+#define HAVE_RB_EXTEND_OBJECT              1
+#define HAVE_RB_INSPECT                    1
+#define HAVE_RB_OBJ_ALLOC                  1
+#define HAVE_RB_OBJ_CALL_INIT              1
+#define HAVE_RB_OBJ_CLASSNAME              1
+#define HAVE_RB_OBJ_FREEZE                 1
+#define HAVE_RB_OBJ_FROZEN_P               1
+#define HAVE_RB_OBJ_ID                     1
+#define HAVE_RB_OBJ_IS_INSTANCE_OF         1
+#define HAVE_RB_OBJ_IS_KIND_OF             1
+#define HAVE_RB_OBJ_TAINT                  1
+#define HAVE_RB_REQUIRE                    1
+#define HAVE_RB_RESPOND_TO                 1
+#define HAVE_RB_SPECIAL_CONST_P            1
+#define HAVE_RB_TO_ID                      1
+#define HAVE_RB_TO_INT                     1
+#define HAVE_RTEST                         1
+#define HAVE_TYPE                          1
+
+/* Proc */
+#define HAVE_RB_PROC_NEW                   1
+
+/* Range */
+#define HAVE_RB_RANGE_NEW                  1
+
+/* Safe */
+#define HAVE_RB_SAFE_LEVEL                 1
+#define HAVE_RB_SECURE                     1
+
+/* String */
+#define HAVE_RB_CSTR2INUM                  1
+#define HAVE_RB_STR2CSTR                   1
+#define HAVE_RB_STR2INUM                   1
+#define HAVE_RB_STR_APPEND                 1
+#define HAVE_RB_STR_BUF_CAT                1
+#define HAVE_RB_STR_CAT                    1
+#define HAVE_RB_STR_CAT2                   1
+#define HAVE_RB_STR_CMP                    1
+#define HAVE_RB_STR_DUP                    1
+#define HAVE_RB_STR_FLUSH                  1
+#define HAVE_RB_STR_FREEZE                 1
+#define HAVE_RB_STR_INTERN                 1
+#define HAVE_RB_STR_LEN                    1
+#define HAVE_RB_STR_NEW                    1
+#define HAVE_RB_STR_NEW2                   1
+#define HAVE_RB_STR_NEW3                   1
+#define HAVE_RB_STR_PLUS                   1
+#define HAVE_RB_STR_PTR                    1
+#define HAVE_RB_STR_PTR_READONLY           1
+#define HAVE_RB_STR_RESIZE                 1
+#define HAVE_RB_STR_SPLIT                  1
+#define HAVE_RB_STR_SUBSTR                 1
+#define HAVE_RB_STR_TO_STR                 1
+#define HAVE_RSTRING                       1
+#define HAVE_RSTRING_LEN                   1
+#define HAVE_RSTRING_PTR                   1
+#define HAVE_STR2CSTR                      1
+#define HAVE_STRINGVALUE                   1
+
+/* Struct */
+#define HAVE_RB_STRUCT_DEFINE              1
+
+/* Symbol */
+#define HAVE_RB_IS_CLASS_ID                1
+#define HAVE_RB_IS_CONST_ID                1
+#define HAVE_RB_IS_INSTANCE_ID             1
+
+/* Thread */
+#define HAVE_RB_THREAD_ALONE               1
+#define HAVE_RB_THREAD_BLOCKING_REGION     1
+#define HAVE_RB_THREAD_CURRENT             1
+#define HAVE_RB_THREAD_LOCAL_AREF          1
+#define HAVE_RB_THREAD_LOCAL_ASET          1
+#define HAVE_RB_THREAD_SELECT              1
+
+/* Time */
+#define HAVE_RB_TIME_NEW                   1
+
+/* Define convenience macros similar to the RubySpec guards to assist
+ * with version incompatibilities.
+ */
+
+#include "rubyspec_version.h"
+
+#if RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 8
+#define RUBY_VERSION_IS_1_8
+#endif
+
+#if RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 8 && RUBY_VERSION_TEENY < 7
+#define RUBY_VERSION_IS_LT_1_8_7
+#endif
+
+#if RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 9
+#define RUBY_VERSION_IS_1_9
+#endif
+
+/* Now, create the differential set. The format of the preprocessor directives
+ * is significant. The alternative implementations should define RUBY because
+ * some extensions depend on that. But only one alternative implementation
+ * macro should be defined at a time. The conditional is structured so that if
+ * no alternative implementation is defined then MRI is assumed and "mri.h"
+ * will be included.
+ */
+
+#if defined(RUBINIUS)
+#include "rubinius.h"
+#elif defined(JRUBY)
+#include "jruby.h"
+#else /* MRI */
+#include "mri.h"
+#endif
+
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/safe_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/safe_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/safe_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,37 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_SAFE_LEVEL
+static VALUE safe_specs_safe_level(VALUE self) {
+  int sl = rb_safe_level();
+  return INT2FIX(sl);
+}
+#endif
+
+#ifdef HAVE_RB_SECURE
+static VALUE safe_specs_secure(VALUE self, VALUE arg) {
+  rb_secure(FIX2INT(arg));
+  return Qnil;
+}
+#endif
+
+void Init_safe_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiSafeSpecs", rb_cObject);
+
+#ifdef HAVE_RB_SAFE_LEVEL
+  rb_define_method(cls, "rb_safe_level", safe_specs_safe_level, 0);
+#endif
+
+#ifdef HAVE_RB_SECURE
+  rb_define_method(cls, "rb_secure", safe_specs_secure, 1);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/string_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/string_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/string_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,484 @@
+#include <string.h>
+
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_CSTR2INUM
+VALUE string_spec_rb_cstr2inum(VALUE self, VALUE str, VALUE inum) {
+  int num = FIX2INT(inum);
+  return rb_cstr2inum(RSTRING_PTR(str), num);
+}
+#endif
+
+#ifdef HAVE_RB_STR2CSTR
+VALUE string_spec_rb_str2cstr(VALUE self, VALUE str, VALUE return_length) {
+  if(return_length == Qtrue) {
+    long len = 0;
+    char* ptr = rb_str2cstr(str, &len);
+    VALUE ary = rb_ary_new();
+    rb_ary_push(ary, rb_str_new2(ptr));
+    rb_ary_push(ary, INT2FIX(len));
+    return ary;
+  } else {
+    return rb_str_new2(rb_str2cstr(str, NULL));
+  }
+}
+
+VALUE string_spec_rb_str2cstr_replace(VALUE self, VALUE str) {
+  char* ptr = rb_str2cstr(str, NULL);
+  ptr[0] = 'f'; ptr[1] = 'o'; ptr[2] = 'o'; ptr[3] = 0;
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_RB_STR2INUM
+VALUE string_spec_rb_str2inum(VALUE self, VALUE str, VALUE inum) {
+  int num = FIX2INT(inum);
+  return rb_str2inum(str, num);
+}
+#endif
+
+#ifdef HAVE_RB_STR_APPEND
+VALUE string_spec_rb_str_append(VALUE self, VALUE str, VALUE str2) {
+  return rb_str_append(str, str2);
+}
+#endif
+
+#ifdef HAVE_RB_STR_BUF_CAT
+VALUE string_spec_rb_str_buf_cat(VALUE self, VALUE str) {
+  const char *question_mark = "?";
+  rb_str_buf_cat(str, question_mark, strlen(question_mark));
+  return str;
+}
+#endif
+
+#ifdef HAVE_RB_STR_CAT
+VALUE string_spec_rb_str_cat(VALUE self, VALUE str) {
+  return rb_str_cat(str, "?", 1);
+}
+#endif
+
+#ifdef HAVE_RB_STR_CAT2
+VALUE string_spec_rb_str_cat2(VALUE self, VALUE str) {
+  return rb_str_cat2(str, "?");
+}
+#endif
+
+#ifdef HAVE_RB_STR_CMP
+VALUE string_spec_rb_str_cmp(VALUE self, VALUE str1, VALUE str2) {
+  return INT2NUM(rb_str_cmp(str1, str2));
+}
+#endif
+
+#ifdef HAVE_RB_STR_DUP
+VALUE string_spec_rb_str_dup(VALUE self, VALUE str) {
+  return rb_str_dup(str);
+}
+#endif
+
+#ifdef HAVE_RB_STR_FREEZE
+VALUE string_spec_rb_str_freeze(VALUE self, VALUE str) {
+  return rb_str_freeze(str);
+}
+#endif
+
+#ifdef HAVE_RB_STR_INTERN
+VALUE string_spec_rb_str_intern(VALUE self, VALUE str) {
+  return rb_str_intern(str);
+}
+#endif
+
+#ifdef HAVE_RB_STR_LEN
+VALUE string_spec_rb_str_len(VALUE self, VALUE str) {
+  return INT2FIX(rb_str_len(str));
+}
+#endif
+
+#ifdef HAVE_RB_STR_NEW
+VALUE string_spec_rb_str_new(VALUE self, VALUE str, VALUE len) {
+  return rb_str_new(RSTRING_PTR(str), FIX2INT(len));
+}
+#endif
+
+#ifdef HAVE_RB_STR_NEW2
+VALUE string_spec_rb_str_new2(VALUE self) {
+  return rb_str_new2("hello\0invisible");
+}
+
+VALUE string_spec_rb_str_new2_with_null(VALUE self) {
+  return rb_str_new2(NULL);
+}
+#endif
+
+#ifdef HAVE_RB_STR_NEW3
+VALUE string_spec_rb_str_new3(VALUE self, VALUE str) {
+  return rb_str_new3(str);
+}
+#endif
+
+#ifdef HAVE_RB_STR_PLUS
+VALUE string_spec_rb_str_plus(VALUE self, VALUE str1, VALUE str2) {
+  return rb_str_plus(str1, str2);
+}
+#endif
+
+#ifdef HAVE_RB_STR_PTR
+VALUE string_spec_rb_str_ptr_iterate(VALUE self, VALUE str) {
+  int i;
+  char* ptr;
+
+  ptr = rb_str_ptr(str);
+  for(i = 0; i < RSTRING_LEN(str); i++) {
+    rb_yield(INT2FIX(ptr[i]));
+  }
+  return Qnil;
+}
+
+VALUE string_spec_rb_str_ptr_assign(VALUE self, VALUE str, VALUE chr) {
+  int i;
+  char c;
+  char* ptr;
+
+  ptr = rb_str_ptr(str);
+  c = FIX2INT(chr);
+
+  for(i = 0; i < RSTRING_LEN(str); i++) {
+    ptr[i] = c;
+  }
+  return Qnil;
+}
+
+VALUE string_spec_rb_str_ptr_assign_call(VALUE self, VALUE str) {
+  char *ptr = rb_str_ptr(str);
+
+  ptr[1] = 'x';
+  rb_str_concat(str, rb_str_new2("d"));
+  return str;
+}
+
+VALUE string_spec_rb_str_ptr_assign_funcall(VALUE self, VALUE str) {
+  char *ptr = rb_str_ptr(str);
+
+  ptr[1] = 'x';
+  rb_str_flush(str);
+  rb_funcall(str, rb_intern("<<"), 1, rb_str_new2("e"));
+  return str;
+}
+#endif
+
+#ifdef HAVE_RB_STR_PTR_READONLY
+VALUE string_spec_rb_str_ptr_readonly_iterate(VALUE self, VALUE str) {
+  int i;
+  char* ptr;
+
+  ptr = rb_str_ptr_readonly(str);
+  for(i = 0; i < RSTRING_LEN(str); i++) {
+    rb_yield(INT2FIX(ptr[i]));
+  }
+  return Qnil;
+}
+
+VALUE string_spec_rb_str_ptr_readonly_assign(VALUE self, VALUE str, VALUE chr) {
+  int i;
+  char c;
+  char* ptr;
+
+  ptr = rb_str_ptr_readonly(str);
+  c = FIX2INT(chr);
+
+  for(i = 0; i < RSTRING_LEN(str); i++) {
+    ptr[i] = c;
+  }
+  return Qnil;
+}
+
+VALUE string_spec_rb_str_ptr_readonly_append(VALUE self, VALUE str, VALUE more) {
+  char *ptr = rb_str_ptr_readonly(str);
+
+  rb_str_concat(str, more);
+
+  return rb_str_new2(ptr);
+}
+#endif
+
+#ifdef HAVE_RB_STR_RESIZE
+VALUE string_spec_rb_str_resize(VALUE self, VALUE str, VALUE size) {
+  return rb_str_resize(str, FIX2INT(size));
+}
+
+VALUE string_spec_rb_str_resize_RSTRING_LEN(VALUE self, VALUE str, VALUE size) {
+  VALUE modified = rb_str_resize(str, FIX2INT(size));
+  return INT2FIX(RSTRING_LEN(modified));
+}
+#endif
+
+#ifdef HAVE_RB_STR_SPLIT
+VALUE string_spec_rb_str_split(VALUE self, VALUE str) {
+  return rb_str_split(str, ",");
+}
+#endif
+
+#ifdef HAVE_RB_STR_SUBSTR
+VALUE string_spec_rb_str_substr(VALUE self, VALUE str, VALUE beg, VALUE len) {
+  return rb_str_substr(str, FIX2INT(beg), FIX2INT(len));
+}
+#endif
+
+#ifdef HAVE_RB_STR_TO_STR
+VALUE string_spec_rb_str_to_str(VALUE self, VALUE arg) {
+  return rb_str_to_str(arg);
+}
+#endif
+
+#ifdef HAVE_RSTRING
+VALUE string_spec_RSTRING_len(VALUE self, VALUE str) {
+  return INT2FIX(RSTRING(str)->len);
+}
+
+VALUE string_spec_RSTRING_ptr_iterate(VALUE self, VALUE str) {
+  int i;
+  char* ptr;
+
+  ptr = RSTRING(str)->ptr;
+  for(i = 0; i < RSTRING_LEN(str); i++) {
+    rb_yield(INT2FIX(ptr[i]));
+  }
+  return Qnil;
+}
+
+VALUE string_spec_RSTRING_ptr_assign(VALUE self, VALUE str, VALUE chr) {
+  int i;
+  char c;
+  char* ptr;
+
+  ptr = RSTRING(str)->ptr;
+  c = FIX2INT(chr);
+
+  for(i = 0; i < RSTRING_LEN(str); i++) {
+    ptr[i] = c;
+  }
+  return Qnil;
+}
+
+VALUE string_spec_RSTRING_ptr_assign_call(VALUE self, VALUE str) {
+  char *ptr = RSTRING(str)->ptr;
+
+  ptr[1] = 'x';
+  rb_str_concat(str, rb_str_new2("d"));
+  return str;
+}
+
+VALUE string_spec_RSTRING_ptr_assign_funcall(VALUE self, VALUE str) {
+  char *ptr = RSTRING(str)->ptr;
+
+  ptr[1] = 'x';
+  rb_funcall(str, rb_intern("<<"), 1, rb_str_new2("e"));
+  return str;
+}
+#endif
+
+#ifdef HAVE_RSTRING_LEN
+VALUE string_spec_RSTRING_LEN(VALUE self, VALUE str) {
+  return INT2FIX(RSTRING_LEN(str));
+}
+#endif
+
+#ifdef HAVE_RSTRING_PTR
+VALUE string_spec_RSTRING_PTR_iterate(VALUE self, VALUE str) {
+  int i;
+  char* ptr;
+
+  ptr = RSTRING_PTR(str);
+  for(i = 0; i < RSTRING_LEN(str); i++) {
+    rb_yield(INT2FIX(ptr[i]));
+  }
+  return Qnil;
+}
+
+VALUE string_spec_RSTRING_PTR_assign(VALUE self, VALUE str, VALUE chr) {
+  int i;
+  char c;
+  char* ptr;
+
+  ptr = RSTRING_PTR(str);
+  c = FIX2INT(chr);
+
+  for(i = 0; i < RSTRING_LEN(str); i++) {
+    ptr[i] = c;
+  }
+  return Qnil;
+}
+
+VALUE string_spec_RSTRING_PTR_after_funcall(VALUE self, VALUE str, VALUE cb) {
+  /* Silence gcc 4.3.2 warning about computed value not used */
+  if(RSTRING_PTR(str)) { /* force it out */
+    rb_funcall(cb, rb_intern("call"), 1, str);
+  }
+
+  return rb_str_new2(RSTRING_PTR(str));
+}
+#endif
+
+#ifdef HAVE_STR2CSTR
+VALUE string_spec_STR2CSTR(VALUE self, VALUE str) {
+  return rb_str_new2(STR2CSTR(str));
+}
+
+VALUE string_spec_STR2CSTR_replace(VALUE self, VALUE str) {
+  char* ptr = STR2CSTR(str);
+  ptr[0] = 'f'; ptr[1] = 'o'; ptr[2] = 'o'; ptr[3] = 0;
+  return Qnil;
+}
+#endif
+
+#ifdef HAVE_STRINGVALUE
+VALUE string_spec_StringValue(VALUE self, VALUE str) {
+  return StringValue(str);
+}
+#endif
+
+void Init_string_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiStringSpecs", rb_cObject);
+
+#ifdef HAVE_RB_CSTR2INUM
+  rb_define_method(cls, "rb_cstr2inum", string_spec_rb_cstr2inum, 2);
+#endif
+
+#ifdef HAVE_RB_STR2CSTR
+  rb_define_method(cls, "rb_str2cstr", string_spec_rb_str2cstr, 2);
+  rb_define_method(cls, "rb_str2cstr_replace", string_spec_rb_str2cstr_replace, 1);
+#endif
+
+#ifdef HAVE_RB_STR2INUM
+  rb_define_method(cls, "rb_str2inum", string_spec_rb_str2inum, 2);
+#endif
+
+#ifdef HAVE_RB_STR_APPEND
+  rb_define_method(cls, "rb_str_append", string_spec_rb_str_append, 2);
+#endif
+
+#ifdef HAVE_RB_STR_BUF_CAT
+  rb_define_method(cls, "rb_str_buf_cat", string_spec_rb_str_buf_cat, 1);
+#endif
+
+#ifdef HAVE_RB_STR_CAT
+  rb_define_method(cls, "rb_str_cat", string_spec_rb_str_cat, 1);
+#endif
+
+#ifdef HAVE_RB_STR_CAT2
+  rb_define_method(cls, "rb_str_cat2", string_spec_rb_str_cat2, 1);
+#endif
+
+#ifdef HAVE_RB_STR_CMP
+  rb_define_method(cls, "rb_str_cmp", string_spec_rb_str_cmp, 2);
+#endif
+
+#ifdef HAVE_RB_STR_DUP
+  rb_define_method(cls, "rb_str_dup", string_spec_rb_str_dup, 1);
+#endif
+
+#ifdef HAVE_RB_STR_FLUSH
+#endif
+
+#ifdef HAVE_RB_STR_FREEZE
+  rb_define_method(cls, "rb_str_freeze", string_spec_rb_str_freeze, 1);
+#endif
+
+#ifdef HAVE_RB_STR_INTERN
+  rb_define_method(cls, "rb_str_intern", string_spec_rb_str_intern, 1);
+#endif
+
+#ifdef HAVE_RB_STR_LEN
+  rb_define_method(cls, "rb_str_len", string_spec_rb_str_len, 1);
+#endif
+
+#ifdef HAVE_RB_STR_NEW
+  rb_define_method(cls, "rb_str_new", string_spec_rb_str_new, 2);
+#endif
+
+#ifdef HAVE_RB_STR_NEW2
+  rb_define_method(cls, "rb_str_new2", string_spec_rb_str_new2, 0);
+  rb_define_method(cls, "rb_str_new2_with_null", string_spec_rb_str_new2_with_null, 0);
+#endif
+
+#ifdef HAVE_RB_STR_NEW3
+  rb_define_method(cls, "rb_str_new3", string_spec_rb_str_new3, 1);
+#endif
+
+#ifdef HAVE_RB_STR_PLUS
+  rb_define_method(cls, "rb_str_plus", string_spec_rb_str_plus, 2);
+#endif
+
+#ifdef HAVE_RB_STR_PTR
+  rb_define_method(cls, "rb_str_ptr_iterate", string_spec_rb_str_ptr_iterate, 1);
+  rb_define_method(cls, "rb_str_ptr_assign", string_spec_rb_str_ptr_assign, 2);
+  rb_define_method(cls, "rb_str_ptr_assign_call", string_spec_rb_str_ptr_assign_call, 1);
+  rb_define_method(cls, "rb_str_ptr_assign_funcall",
+      string_spec_rb_str_ptr_assign_funcall, 1);
+#endif
+
+#ifdef HAVE_RB_STR_PTR_READONLY
+  rb_define_method(cls, "rb_str_ptr_readonly_iterate",
+      string_spec_rb_str_ptr_readonly_iterate, 1);
+  rb_define_method(cls, "rb_str_ptr_readonly_assign",
+      string_spec_rb_str_ptr_readonly_assign, 2);
+  rb_define_method(cls, "rb_str_ptr_readonly_append",
+      string_spec_rb_str_ptr_readonly_append, 2);
+#endif
+
+#ifdef HAVE_RB_STR_RESIZE
+  rb_define_method(cls, "rb_str_resize", string_spec_rb_str_resize, 2);
+  rb_define_method(cls, "rb_str_resize_RSTRING_LEN",
+      string_spec_rb_str_resize_RSTRING_LEN, 2);
+#endif
+
+#ifdef HAVE_RB_STR_SPLIT
+  rb_define_method(cls, "rb_str_split", string_spec_rb_str_split, 1);
+#endif
+
+#ifdef HAVE_RB_STR_SUBSTR
+  rb_define_method(cls, "rb_str_substr", string_spec_rb_str_substr, 3);
+#endif
+
+#ifdef HAVE_RB_STR_TO_STR
+  rb_define_method(cls, "rb_str_to_str", string_spec_rb_str_to_str, 1);
+#endif
+
+#ifdef HAVE_RSTRING
+  rb_define_method(cls, "RSTRING_ptr_iterate", string_spec_RSTRING_ptr_iterate, 1);
+  rb_define_method(cls, "RSTRING_ptr_assign", string_spec_RSTRING_ptr_assign, 2);
+  rb_define_method(cls, "RSTRING_ptr_assign_call", string_spec_RSTRING_ptr_assign_call, 1);
+  rb_define_method(cls, "RSTRING_ptr_assign_funcall",
+      string_spec_RSTRING_ptr_assign_funcall, 1);
+  rb_define_method(cls, "RSTRING_len", string_spec_RSTRING_len, 1);
+#endif
+
+#ifdef HAVE_RSTRING_LEN
+  rb_define_method(cls, "RSTRING_LEN", string_spec_RSTRING_LEN, 1);
+#endif
+
+#ifdef HAVE_RSTRING_PTR
+  rb_define_method(cls, "RSTRING_PTR_iterate", string_spec_RSTRING_PTR_iterate, 1);
+  rb_define_method(cls, "RSTRING_PTR_assign", string_spec_RSTRING_PTR_assign, 2);
+  rb_define_method(cls, "RSTRING_PTR_after_funcall",
+      string_spec_RSTRING_PTR_after_funcall, 2);
+#endif
+
+#ifdef HAVE_STR2CSTR
+  rb_define_method(cls, "STR2CSTR", string_spec_STR2CSTR, 1);
+  rb_define_method(cls, "STR2CSTR_replace", string_spec_STR2CSTR_replace, 1);
+#endif
+
+#ifdef HAVE_STRINGVALUE
+  rb_define_method(cls, "StringValue", string_spec_StringValue, 1);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/struct_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/struct_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/struct_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,36 @@
+#include "ruby.h"
+#include "intern.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_STRUCT_DEFINE
+/* Only allow setting three attributes, should be sufficient for testing. */
+static VALUE sa_struct_define(VALUE self, VALUE name,
+  VALUE attr1, VALUE attr2, VALUE attr3) {
+
+  const char *a1 = StringValuePtr(attr1);
+  const char *a2 = StringValuePtr(attr2);
+  const char *a3 = StringValuePtr(attr3);
+  char *nm = NULL;
+
+  if (name != Qnil) nm = StringValuePtr(name);
+
+  return rb_struct_define(nm, a1, a2, a3, NULL);
+}
+#endif
+
+void Init_struct_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiStructSpecs", rb_cObject);
+
+#ifdef HAVE_RB_STRUCT_DEFINE
+  rb_define_method(cls, "rb_struct_define", sa_struct_define, 4);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/symbol_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/symbol_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/symbol_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,45 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_IS_CLASS_ID
+VALUE symbol_spec_rb_is_class_id(VALUE self, VALUE sym) {
+  return rb_is_class_id(SYM2ID(sym)) ? Qtrue : Qfalse;
+}
+#endif
+
+#ifdef HAVE_RB_IS_CONST_ID
+VALUE symbol_spec_rb_is_const_id(VALUE self, VALUE sym) {
+  return rb_is_const_id(SYM2ID(sym)) ? Qtrue : Qfalse;
+}
+#endif
+
+#ifdef HAVE_RB_IS_INSTANCE_ID
+VALUE symbol_spec_rb_is_instance_id(VALUE self, VALUE sym) {
+  return rb_is_instance_id(SYM2ID(sym)) ? Qtrue : Qfalse;
+}
+#endif
+
+void Init_symbol_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiSymbolSpecs", rb_cObject);
+
+#ifdef HAVE_RB_IS_CLASS_ID
+  rb_define_method(cls, "rb_is_class_id", symbol_spec_rb_is_class_id, 1);
+#endif
+
+#ifdef HAVE_RB_IS_CONST_ID
+  rb_define_method(cls, "rb_is_const_id", symbol_spec_rb_is_const_id, 1);
+#endif
+
+#ifdef HAVE_RB_IS_INSTANCE_ID
+  rb_define_method(cls, "rb_is_instance_id", symbol_spec_rb_is_instance_id, 1);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/thread_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/thread_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/thread_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,103 @@
+#include <math.h>
+
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_THREAD_ALONE
+static VALUE thread_spec_rb_thread_alone() {
+  return rb_thread_alone() ? Qtrue : Qfalse;
+}
+#endif
+
+#ifdef HAVE_RB_THREAD_BLOCKING_REGION
+static VALUE do_unlocked(void* data) {
+  if(data == (void*)1) return (VALUE)1;
+  return (VALUE)0;
+}
+
+/* There is really no way to know we're unlocked. So just make sure the arguments */
+/* go through fine. */
+static VALUE thread_spec_rb_thread_blocking_region() {
+  VALUE ret = rb_thread_blocking_region(do_unlocked, (void*)1, 0, 0);
+  if(ret == (VALUE)1) return Qtrue;
+  return Qfalse;
+}
+#endif
+
+#ifdef HAVE_RB_THREAD_CURRENT
+static VALUE thread_spec_rb_thread_current() {
+  return rb_thread_current();
+}
+#endif
+
+#ifdef HAVE_RB_THREAD_LOCAL_AREF
+static VALUE thread_spec_rb_thread_local_aref(VALUE self, VALUE thr, VALUE sym) {
+  return rb_thread_local_aref(thr, SYM2ID(sym));
+}
+#endif
+
+#ifdef HAVE_RB_THREAD_LOCAL_ASET
+static VALUE thread_spec_rb_thread_local_aset(VALUE self, VALUE thr, VALUE sym, VALUE value) {
+  return rb_thread_local_aset(thr, SYM2ID(sym), value);
+}
+#endif
+
+#ifdef HAVE_RB_THREAD_SELECT
+static VALUE thread_spec_rb_thread_select_fd(VALUE self, VALUE fd_num, VALUE msec) {
+  int fd = NUM2INT(fd_num);
+  struct timeval tv = {0, NUM2INT(msec)};
+  int n;
+
+  fd_set read;
+  FD_ZERO(&read);
+  FD_SET(fd, &read);
+
+  n = rb_thread_select(fd + 1, &read, NULL, NULL, &tv);
+  if(n == 1 && FD_ISSET(fd, &read)) return Qtrue;
+  return Qfalse;
+}
+
+static VALUE thread_spec_rb_thread_select(VALUE self, VALUE msec) {
+  struct timeval tv = {0, NUM2INT(msec)};
+  rb_thread_select(0, NULL, NULL, NULL, &tv);
+  return Qnil;
+}
+#endif
+
+void Init_thread_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiThreadSpecs", rb_cObject);
+
+#ifdef HAVE_RB_THREAD_ALONE
+  rb_define_method(cls, "rb_thread_alone", thread_spec_rb_thread_alone, 0);
+#endif
+
+#ifdef HAVE_RB_THREAD_BLOCKING_REGION
+  rb_define_method(cls, "rb_thread_blocking_region", thread_spec_rb_thread_blocking_region, 0);
+#endif
+
+#ifdef HAVE_RB_THREAD_CURRENT
+  rb_define_method(cls, "rb_thread_current", thread_spec_rb_thread_current, 0);
+#endif
+
+#ifdef HAVE_RB_THREAD_LOCAL_AREF
+  rb_define_method(cls, "rb_thread_local_aref", thread_spec_rb_thread_local_aref, 2);
+#endif
+
+#ifdef HAVE_RB_THREAD_LOCAL_ASET
+  rb_define_method(cls, "rb_thread_local_aset", thread_spec_rb_thread_local_aset, 3);
+#endif
+
+#ifdef HAVE_RB_THREAD_SELECT
+  rb_define_method(cls, "rb_thread_select_fd", thread_spec_rb_thread_select_fd, 2);
+  rb_define_method(cls, "rb_thread_select", thread_spec_rb_thread_select, 1);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/ext/time_spec.c
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/ext/time_spec.c	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/ext/time_spec.c	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,25 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_RB_TIME_NEW
+static VALUE time_spec_rb_time_new(VALUE self, VALUE sec, VALUE usec) {
+  return rb_time_new(NUM2INT(sec), NUM2INT(usec));
+}
+#endif
+
+void Init_time_spec() {
+  VALUE cls;
+  cls = rb_define_class("CApiTimeSpecs", rb_cObject);
+
+#ifdef HAVE_RB_TIME_NEW
+  rb_define_method(cls, "rb_time_new", time_spec_rb_time_new, 2);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif

Added: MacRuby/trunk/spec/frozen/optional/capi/fixtures/foo.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/fixtures/foo.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/fixtures/foo.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1 @@
+$foo = 7
\ No newline at end of file

Added: MacRuby/trunk/spec/frozen/optional/capi/float_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/float_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/float_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,42 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("float")
+
+describe "CApiFloatSpecs" do
+  before :each do
+    @f = CApiFloatSpecs.new
+  end
+
+  describe "rb_float_new" do
+    it "should create a new float" do
+      ((@f.new_zero - 0).abs < 0.000001).should == true
+      ((@f.new_point_five - 0.555).abs < 0.000001).should == true
+    end
+  end
+
+  ruby_version_is ""..."1.9" do
+    describe "RFLOAT" do
+      it "returns a struct with the Float value" do
+        f = @f.RFLOAT_value(1.0)
+        f.should eql(1.0)
+
+        f = @f.RFLOAT_value(-10.5)
+        f.should eql(-10.5)
+      end
+
+      it "allows changing the Float value" do
+        f = 3.14
+        @f.RFLOAT_value_set(f, 4)
+        f.should eql(4.0)
+      end
+    end
+  end
+
+  describe "rb_Float" do
+    it "should create a new Float from a String" do
+      f = @f.rb_Float("101.99")
+      f.should be_kind_of(Float)
+      f.should eql(101.99)
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/gc_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/gc_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/gc_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,16 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("gc")
+
+describe "CApiGCSpecs" do
+  before :each do
+    @f = CApiGCSpecs.new
+  end
+
+  it "correctly gets the value from a registered address" do
+    @f.registered_tagged_address.should == 10
+    @f.registered_tagged_address.object_id.should == @f.registered_tagged_address.object_id
+    @f.registered_reference_address.should == "Globally registered data"
+    @f.registered_reference_address.object_id.should == @f.registered_reference_address.object_id
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/globals_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/globals_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/globals_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,65 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("globals")
+
+describe "CApiGlobalSpecs" do
+  before :each do
+    @f = CApiGlobalSpecs.new
+  end
+  
+  it "correctly gets global values" do
+    @f.sb_gv_get("$BLAH").should == nil
+    @f.sb_gv_get("$SAFE").should == 0
+    @f.sb_gv_get("SAFE").should == 0 # rb_gv_get should change SAFE to $SAFE
+  end
+
+  it "correctly sets global values" do
+    @f.sb_gv_get("$BLAH").should == nil
+    @f.sb_gv_set("$BLAH", 10)
+    @f.sb_gv_get("$BLAH").should == 10
+  end
+
+  it "lists all global variables" do
+    @f.rb_f_global_variables.should == Kernel.global_variables
+  end
+
+  not_supported_on :rubinius do
+    it "rb_define_variable should define a new global variable" do
+      @f.rb_define_variable("my_gvar", "ABC")
+      $my_gvar.should == "ABC"
+      $my_gvar = "XYZ"
+      @f.sb_get_global_value.should == "XYZ"
+    end
+  end
+
+  it "rb_define_readonly_variable should define a new readonly global variable" do
+    @f.rb_define_readonly_variable("ro_gvar", 15)
+    $ro_gvar.should == 15
+    lambda { $ro_gvar = 10 }.should raise_error(NameError)
+  end
+
+  not_supported_on :rubinius do
+    it "rb_define_hooked_variable should define a C hooked global variable" do
+      @f.rb_define_hooked_variable_2x("$hooked_gvar")
+      $hooked_gvar = 2
+      $hooked_gvar.should == 4
+    end
+  end
+
+  ruby_version_is ""..."1.9" do
+    describe "rb_set_kcode" do
+      before :each do
+        @kcode = $KCODE
+      end
+
+      after :each do
+        $KCODE = @kcode
+      end
+
+      it "sets the value of $KCODE" do
+        @f.rb_set_kcode("U")
+        $KCODE.should == "UTF8"
+      end
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/hash_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/hash_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/hash_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,94 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("hash")
+
+describe "C-API Hash function" do
+  before :each do
+    @s = CApiHashSpecs.new
+  end
+
+  describe "rb_hash_new" do
+    it "returns a new hash" do
+      @s.rb_hash_new.should == {}
+    end
+  end
+
+  describe "rb_hash_aref" do
+    it "returns the value associated with the key" do
+      hsh = {:chunky => 'bacon'}
+      @s.rb_hash_aref(hsh, :chunky).should == 'bacon'
+    end
+
+    it "returns the default value if it exists" do
+      hsh = Hash.new(0)
+      @s.rb_hash_aref(hsh, :chunky).should == 0
+      @s.rb_hash_aref_nil(hsh, :chunky).should be_false
+    end
+
+    it "returns nil if the key does not exist" do
+      hsh = { }
+      @s.rb_hash_aref(hsh, :chunky).should be_nil
+      @s.rb_hash_aref_nil(hsh, :chunky).should be_true
+    end
+  end
+
+  describe "rb_hash_aset" do
+    it "adds the key/value pair and returns the value" do
+      hsh = {}
+      @s.rb_hash_aset(hsh, :chunky, 'bacon').should == 'bacon'
+      hsh.should == {:chunky => 'bacon'}
+    end
+  end
+
+  describe "rb_hash_delete" do
+    it "removes the key and returns the value" do
+      hsh = {:chunky => 'bacon'}
+      @s.rb_hash_delete(hsh, :chunky).should == 'bacon'
+      hsh.should == {}
+    end
+  end
+
+  describe "rb_hash_foreach" do
+    it "iterates over the hash" do
+      hsh = {:name => "Evan", :sign => :libra}
+
+      out = @s.rb_hash_foreach(hsh)
+      out.equal?(hsh).should == false
+      out.should == hsh
+    end
+  end
+
+  # rb_hash_size is a static symbol in MRI
+  extended_on :rubinius do
+    describe "rb_hash_size" do
+      it "returns the size of the hash" do
+        hsh = {:fast => 'car', :good => 'music'}
+        @s.rb_hash_size(hsh).should == 2
+      end
+
+      it "returns zero for an empty hash" do
+        @s.rb_hash_size({}).should == 0
+      end
+    end
+
+    # TODO: make this shared so it runs on 1.8.7
+    describe "rb_hash_lookup" do
+      it "returns the value associated with the key" do
+        hsh = {:chunky => 'bacon'}
+        @s.rb_hash_lookup(hsh, :chunky).should == 'bacon'
+      end
+
+      it "does not return the default value if it exists" do
+        hsh = Hash.new(0)
+        @s.rb_hash_lookup(hsh, :chunky).should be_nil
+        @s.rb_hash_lookup_nil(hsh, :chunky).should be_true
+      end
+
+      it "returns nil if the key does not exist" do
+        hsh = { }
+        @s.rb_hash_lookup(hsh, :chunky).should be_nil
+        @s.rb_hash_lookup_nil(hsh, :chunky).should be_true
+      end
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/io_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/io_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/io_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,17 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension('io')
+
+describe "C-API IO function" do
+  before :each do
+    @o = CApiIOSpecs.new
+  end
+
+  describe "rb_io_write" do
+    it "sends #write to the object passing the object to be written" do
+      io = mock("IO")
+      io.should_receive(:write).with("test").and_return(:written)
+      @o.rb_io_write(io, "test").should == :written
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/kernel_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/kernel_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/kernel_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,218 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("kernel")
+
+describe "C-API Kernel function" do
+  before :each do
+    @s = CApiKernelSpecs.new
+  end
+
+  describe "rb_block_given_p" do
+    it "returns false if no block is passed" do
+      @s.rb_block_given_p.should == false
+    end
+
+    it "returns true if a block is passed" do
+      (@s.rb_block_given_p { puts "FOO" } ).should == true
+    end
+  end
+
+  describe "rb_raise" do
+    it "raises an exception" do
+      lambda { @s.rb_raise({}) }.should raise_error(TypeError)
+    end
+
+    it "terminates the function at the point it was called" do
+      h = {}
+      lambda { @s.rb_raise(h) }.should raise_error(TypeError)
+      h[:stage].should == :before
+    end
+  end
+
+  describe "rb_throw" do
+    before :each do
+      ScratchPad.record []
+    end
+
+    it "sets the return value of the catch block to the specified value" do
+      catch(:foo) do
+        @s.rb_throw(:return_value)
+      end.should == :return_value
+    end
+
+    it "terminates the function at the point it was called" do
+      catch(:foo) do
+        ScratchPad << :before_throw
+        @s.rb_throw(:thrown_value)
+        ScratchPad << :after_throw
+      end.should == :thrown_value
+      ScratchPad.recorded.should == [:before_throw]
+    end
+
+    ruby_version_is ""..."1.9" do
+      it "raises a NameError if there is no catch block for the symbol" do
+        lambda { @s.rb_throw(nil) }.should raise_error(NameError)
+      end
+    end
+
+    ruby_version_is "1.9" do
+      it "raises an ArgumentError if there is no catch block for the symbol" do
+        lambda { @s.rb_throw(nil) }.should raise_error(ArgumentError)
+      end
+    end
+  end
+
+  describe "rb_warn" do
+    before :each do
+      @stderr, $stderr = $stderr, IOStub.new
+      @verbose = $VERBOSE
+    end
+
+    after :each do
+      $stderr = @stderr
+      $VERBOSE = @verbose
+    end
+
+    it "prints a message to $stderr if $VERBOSE evaluates to true" do
+      $VERBOSE = true
+      @s.rb_warn("This is a warning")
+      $stderr.should =~ /This is a warning/
+    end
+
+    it "prints a message to $stderr if $VERBOSE evaluates to false" do
+      $VERBOSE = false
+      @s.rb_warn("This is a warning")
+      $stderr.should =~ /This is a warning/
+    end
+  end
+
+  describe "rb_sys_fail" do
+    it "raises an exception from the value of errno" do
+      # If errno = 1 is no EPERM on a platform, we can change the
+      # expected exception class to be more generic
+      lambda do
+        @s.rb_sys_fail("additional info")
+      end.should raise_error(Errno::EPERM, /additional info/)
+    end
+  end
+
+  describe "rb_yield" do
+    it "yields passed argument" do
+      ret = nil
+      @s.rb_yield(1) { |z| ret = z }
+      ret.should == 1
+    end
+
+    it "returns the result from block evaluation" do
+      @s.rb_yield(1) { |z| z * 1000 }.should == 1000
+    end
+
+    it "raises LocalJumpError when no block is given" do
+      lambda { @s.rb_yield(1) }.should raise_error(LocalJumpError)
+    end
+  end
+
+  describe "rb_yield_values" do
+    it "yields passed arguments" do
+      ret = nil
+      @s.rb_yield_values(1, 2) { |x, y| ret = x + y }
+      ret.should == 3
+    end
+
+    it "returns the result from block evaluation" do
+      @s.rb_yield_values(1, 2) { |x, y| x + y }.should == 3
+    end
+
+    it "raises LocalJumpError when no block is given" do
+      lambda { @s.rb_yield_values(1, 2) }.should raise_error(LocalJumpError)
+    end
+  end
+
+  describe "rb_rescue" do
+    before :each do
+      @proc = lambda { |x| x }
+      @arg_error_proc = lambda { |*_| raise ArgumentError, '' }
+      @std_error_proc = lambda { |*_| raise StandardError, '' }
+      @exc_error_proc = lambda { |*_| raise Exception, '' }
+    end
+
+    it "executes passed function" do
+      @s.rb_rescue(@proc, :no_exc, @proc, :exc).should == :no_exc
+    end
+
+    it "executes passed 'raise function' if a StardardError exception is raised" do
+      @s.rb_rescue(@arg_error_proc, nil, @proc, :exc).should == :exc
+      @s.rb_rescue(@std_error_proc, nil, @proc, :exc).should == :exc
+    end
+
+    it "raises an exception if passed function raises an exception other than StardardError" do
+      lambda { @s.rb_rescue(@exc_error_proc, nil, @proc, nil) }.should raise_error(Exception)
+    end
+
+    it "raises an exception if any exception is raised inside 'raise function'" do
+      lambda { @s.rb_rescue(@std_error_proc, nil, @std_error_proc, nil) }.should raise_error(StandardError)
+    end
+
+    it "makes $! available only during 'raise function' execution" do
+      @s.rb_rescue(@std_error_proc, nil, lambda { |*_| $! }, nil).class.should == StandardError
+      $!.should == nil
+    end
+  end
+
+  describe "rb_rescue2" do
+    it "only rescues if one of the passed exceptions is raised" do
+      proc = lambda { |x| x }
+      arg_error_proc = lambda { |*_| raise ArgumentError, '' }
+      run_error_proc = lambda { |*_| raise RuntimeError, '' }
+      type_error_proc = lambda { |*_| raise TypeError, '' }
+      @s.rb_rescue2(arg_error_proc, :no_exc, proc, :exc, ArgumentError, RuntimeError).should == :exc
+      @s.rb_rescue2(run_error_proc, :no_exc, proc, :exc, ArgumentError, RuntimeError).should == :exc
+      lambda {
+        @s.rb_rescue2(type_error_proc, :no_exc, proc, :exc, ArgumentError, RuntimeError)
+      }.should raise_error(TypeError)
+    end
+  end
+
+  describe "rb_ensure" do
+    it "executes passed function and returns its value" do
+      proc = lambda { |x| x }
+      @s.rb_ensure(proc, :proc, proc, :ensure_proc).should == :proc
+    end
+
+    it "executes passed 'ensure function' when no exception is raised" do
+      foo = nil
+      proc = lambda { |*_| }
+      ensure_proc = lambda { |x| foo = x }
+      @s.rb_ensure(proc, nil, ensure_proc, :foo)
+      foo.should == :foo
+    end
+
+    it "executes passed 'ensure function' when an exception is raised" do
+      foo = nil
+      raise_proc = lambda { raise '' }
+      ensure_proc = lambda { |x| foo = x }
+      @s.rb_ensure(raise_proc, nil, ensure_proc, :foo) rescue nil
+      foo.should == :foo
+    end
+
+    it "raises the same exception raised inside passed function" do
+      raise_proc = lambda { |*_| raise RuntimeError, 'foo' }
+      proc = lambda { |*_| }
+      lambda { @s.rb_ensure(raise_proc, nil, proc, nil) }.should raise_error(RuntimeError, 'foo')
+    end
+  end
+
+  describe "rb_eval_string" do
+    it "evaluates a string of ruby code" do
+      @s.rb_eval_string("1+1").should == 2
+    end
+  end
+
+  describe "rb_block_proc" do
+    it "converts the implicit block into a proc" do
+      proc = @s.rb_block_proc() { 1+1 }
+      proc.should be_kind_of Proc
+      proc.call.should == 2
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/module_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/module_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/module_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,285 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension('module')
+
+class CApiModuleSpecs
+  class A
+    X = 1
+  end
+
+  class B < A
+    Y = 2
+  end
+
+  class C
+    Z = 3
+  end
+
+  module M
+  end
+
+  class Super
+  end
+end
+
+describe "CApiModule" do
+
+  before :each do
+    @m = CApiModuleSpecs.new
+  end
+
+  describe "rb_define_global_const" do
+    it "defines a constant on Object" do
+      @m.rb_define_global_const("CApiModuleSpecsGlobalConst", 7)
+      ::CApiModuleSpecsGlobalConst.should == 7
+      Object.send :remove_const, :CApiModuleSpecsGlobalConst
+    end
+  end
+
+  describe "rb_const_set given a symbol name and a value" do
+    it "sets a new constant on a module" do
+      @m.rb_const_set(CApiModuleSpecs::C, :W, 7)
+      CApiModuleSpecs::C::W.should == 7
+    end
+
+    it "sets an existing constant's value" do
+      @m.rb_const_set(CApiModuleSpecs::C, :Z, 8)
+      CApiModuleSpecs::C::Z.should == 8
+    end
+  end
+
+  describe "rb_define_class_under" do
+    it "creates a subclass of the superclass contained in a module" do
+      cls = @m.rb_define_class_under(CApiModuleSpecs,
+                                     "ModuleSpecsClassUnder1",
+                                     CApiModuleSpecs::Super)
+      cls.should be_kind_of(Class)
+      CApiModuleSpecs::Super.should be_ancestor_of(CApiModuleSpecs::ModuleSpecsClassUnder1)
+    end
+
+    it "uses Object as the superclass if NULL is passed" do
+      @m.rb_define_class_under(CApiModuleSpecs, "ModuleSpecsClassUnder2", nil)
+      Object.should be_ancestor_of(CApiModuleSpecs::ModuleSpecsClassUnder2)
+    end
+
+    it "sets the class name" do
+      cls = @m.rb_define_class_under(CApiModuleSpecs, "ModuleSpecsClassUnder3", nil)
+      cls.name.should == "CApiModuleSpecs::ModuleSpecsClassUnder3"
+    end
+
+    it "call #inherited on the superclass" do
+      CApiModuleSpecs::Super.should_receive(:inherited)
+      cls = @m.rb_define_class_under(CApiModuleSpecs,
+                                     "ModuleSpecsClassUnder4", CApiModuleSpecs::Super)
+    end
+  end
+
+  describe "rb_define_module_under" do
+    it "creates a new module inside the inner class" do
+      mod = @m.rb_define_module_under(CApiModuleSpecs, "ModuleSpecsModuleUnder1")
+      mod.should be_kind_of(Module)
+    end
+
+    it "sets the module name" do
+      mod = @m.rb_define_module_under(CApiModuleSpecs, "ModuleSpecsModuleUnder2")
+      mod.name.should == "CApiModuleSpecs::ModuleSpecsModuleUnder2"
+    end
+  end
+
+  describe "rb_define_const given a String name and a value" do
+    it "defines a new constant on a module" do
+      @m.rb_define_const(CApiModuleSpecs::C, "V", 7)
+      CApiModuleSpecs::C::V.should == 7
+    end
+
+    it "sets an existing constant's value" do
+      @m.rb_define_const(CApiModuleSpecs::C, "Z", 9)
+      CApiModuleSpecs::C::Z.should == 9
+    end
+  end
+
+  describe "rb_const_defined" do
+    # The fixture converts C boolean test to Ruby 'true' / 'false'
+    it "returns C non-zero if a constant is defined" do
+      @m.rb_const_defined(CApiModuleSpecs::A, :X).should be_true
+    end
+
+    it "returns C non-zero if a constant is defined in Object" do
+      @m.rb_const_defined(CApiModuleSpecs::A, :Module).should be_true
+    end
+  end
+
+  describe "rb_const_defined_at" do
+    # The fixture converts C boolean test to Ruby 'true' / 'false'
+    it "returns C non-zero if a constant is defined" do
+      @m.rb_const_defined_at(CApiModuleSpecs::A, :X).should be_true
+    end
+
+    it "does not search in ancestors for the constant" do
+      @m.rb_const_defined_at(CApiModuleSpecs::B, :X).should be_false
+    end
+
+    it "does not search in Object" do
+      @m.rb_const_defined_at(CApiModuleSpecs::A, :Module).should be_false
+    end
+  end
+
+  describe "rb_const_get" do
+    it "returns a constant defined in the module" do
+      @m.rb_const_get(CApiModuleSpecs::A, :X).should == 1
+    end
+
+    it "returns a constant defined at toplevel" do
+      @m.rb_const_get(CApiModuleSpecs::A, :Fixnum).should == Fixnum
+    end
+
+    it "returns a constant defined in a superclass" do
+      @m.rb_const_get_from(CApiModuleSpecs::B, :X).should == 1
+    end
+
+    it "calls #const_missing if the constant is not defined in the class or ancestors" do
+      CApiModuleSpecs::A.should_receive(:const_missing).with(:CApiModuleSpecsUndefined)
+      @m.rb_const_get_from(CApiModuleSpecs::A, :CApiModuleSpecsUndefined)
+    end
+  end
+
+  describe "rb_const_get_from" do
+    it "returns a constant defined in the module" do
+      @m.rb_const_get_from(CApiModuleSpecs::B, :Y).should == 2
+    end
+
+    it "returns a constant defined in a superclass" do
+      @m.rb_const_get_from(CApiModuleSpecs::B, :X).should == 1
+    end
+
+    it "calls #const_missing if the constant is not defined in the class or ancestors" do
+      CApiModuleSpecs::M.should_receive(:const_missing).with(:Fixnum)
+      @m.rb_const_get_from(CApiModuleSpecs::M, :Fixnum)
+    end
+  end
+
+  describe "rb_const_get_at" do
+    it "returns a constant defined in the module" do
+      @m.rb_const_get_at(CApiModuleSpecs::B, :Y).should == 2
+    end
+
+    it "calls #const_missing if the constant is not defined in the module" do
+      CApiModuleSpecs::B.should_receive(:const_missing).with(:X)
+      @m.rb_const_get_at(CApiModuleSpecs::B, :X)
+    end
+  end
+
+  describe "rb_define_alias" do
+    it "defines an alias for an existing method" do
+      cls = Class.new do
+        def method_to_be_aliased
+          :method_to_be_aliased
+        end
+      end
+
+      @m.rb_define_alias cls, "method_alias", "method_to_be_aliased"
+      cls.new.method_alias.should == :method_to_be_aliased
+    end
+  end
+
+  describe "rb_define_global_function" do
+    it "defines a method on Object" do
+      @m.rb_define_global_function("module_specs_global_function")
+      Kernel.should have_method(:module_specs_global_function)
+      module_specs_global_function.should == :test_method
+    end
+  end
+
+  describe "rb_define_method" do
+    it "defines a method on a class" do
+      cls = Class.new
+      @m.rb_define_method(cls, "test_method")
+      cls.should have_instance_method(:test_method)
+      cls.new.test_method.should == :test_method
+    end
+
+    it "defines a method on a module" do
+      mod = Module.new
+      @m.rb_define_method(mod, "test_method")
+      mod.should have_instance_method(:test_method)
+    end
+  end
+
+  describe "rb_define_module_function" do
+    before :each do
+      @mod = Module.new
+      @m.rb_define_module_function @mod, "test_module_function"
+    end
+
+    it "defines a module function" do
+      @mod.test_module_function.should == :test_method
+    end
+
+    it "defines a private instance method" do
+      cls = Class.new
+      cls.send :include, @mod
+
+      cls.should have_private_instance_method(:test_module_function)
+    end
+  end
+
+  describe "rb_define_private_method" do
+    it "defines a private method on a class" do
+      cls = Class.new
+      @m.rb_define_private_method(cls, "test_method")
+      cls.should have_private_instance_method(:test_method)
+      cls.new.send(:test_method).should == :test_method
+    end
+
+    it "defines a private method on a module" do
+      mod = Module.new
+      @m.rb_define_private_method(mod, "test_method")
+      mod.should have_private_instance_method(:test_method)
+    end
+  end
+
+  describe "rb_define_protected_method" do
+    it "defines a protected method on a class" do
+      cls = Class.new
+      @m.rb_define_protected_method(cls, "test_method")
+      cls.should have_protected_instance_method(:test_method)
+      cls.new.send(:test_method).should == :test_method
+    end
+
+    it "defines a protected method on a module" do
+      mod = Module.new
+      @m.rb_define_protected_method(mod, "test_method")
+      mod.should have_protected_instance_method(:test_method)
+    end
+  end
+
+  describe "rb_define_singleton_method" do
+    it "defines a method on the singleton class" do
+      cls = Class.new
+      a = cls.new
+      @m.rb_define_singleton_method a, "module_specs_singleton_method"
+      a.module_specs_singleton_method.should == :test_method
+      lambda { cls.new.module_specs_singleton_method }.should raise_error(NoMethodError)
+    end
+  end
+
+  describe "rb_undef_method" do
+    it "undef'ines a method on a class" do
+      cls = Class.new do
+        def ruby_test_method
+          :ruby_test_method
+        end
+      end
+
+      cls.new.ruby_test_method.should == :ruby_test_method
+      @m.rb_undef_method cls, "ruby_test_method"
+      cls.should_not have_instance_method(:ruby_test_method)
+    end
+  end
+
+  describe "rb_class2name" do
+    it "returns the module name" do
+      @m.rb_class2name(CApiModuleSpecs::M).should == "CApiModuleSpecs::M"
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/numeric_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/numeric_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/numeric_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,127 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("numeric")
+
+describe "CApiNumericSpecs" do
+  before :each do
+    @s = CApiNumericSpecs.new
+  end
+
+  describe "rb_num2long" do
+    it "raises an TypeError if passed nil" do
+      lambda { @s.rb_num2long(nil) }.should raise_error(TypeError)
+    end
+
+    it "converts a Float" do
+      @s.rb_num2long(4.2).should == 4
+    end
+
+    it "converts a Bignum" do
+      @s.rb_num2long(0x7fff_ffff).should == 0x7fff_ffff
+    end
+
+    it "converts a Fixnum" do
+      @s.rb_num2long(5).should == 5
+    end
+
+    it "calls #to_int to coerce the value" do
+      obj = mock("number")
+      obj.should_receive(:to_int).and_return(2)
+      @s.rb_num2long(obj).should == 2
+    end
+  end
+
+  describe "rb_num2ulong" do
+    it "raises an TypeError if passed nil" do
+      lambda { @s.rb_num2ulong(nil) }.should raise_error(TypeError)
+    end
+
+    it "converts a Float" do
+      @s.rb_num2ulong(4.2).should == 4
+    end
+
+    it "converts a Bignum" do
+      @s.rb_num2ulong(0xffff_ffff).should == 0xffff_ffff
+    end
+
+    it "converts a Fixnum" do
+      @s.rb_num2ulong(5).should == 5
+    end
+
+    it "calls #to_int to coerce the value" do
+      obj = mock("number")
+      obj.should_receive(:to_int).and_return(2)
+      @s.rb_num2ulong(obj).should == 2
+    end
+  end
+
+  describe "rb_Integer" do
+    it "should create a new Integer from a String" do
+      i = @s.rb_Integer("8675309")
+      i.should be_kind_of(Integer)
+      i.should eql(8675309)
+    end
+  end
+
+  describe "rb_ll2inum" do
+    it "should create a new Fixnum from a small signed long long" do
+      i = @s.rb_ll2inum_14()
+      i.should be_kind_of(Fixnum)
+      i.should eql(14)
+    end
+  end
+
+  describe "rb_int2inum" do
+    it "should create a new Fixnum from a long" do
+      i = @s.rb_int2inum_14()
+      i.should be_kind_of(Fixnum)
+      i.should eql(14)
+    end
+  end
+
+  describe "rb_num2dbl" do
+    it "raises an TypeError if passed nil" do
+      lambda { @s.rb_num2dbl(nil) }.should raise_error(TypeError)
+    end
+
+    it "raises an TypeError if passed a String" do
+      lambda { @s.rb_num2dbl("1.2") }.should raise_error(TypeError)
+    end
+
+    it "converts a Float" do
+      @s.rb_num2dbl(4.2).should == 4.2
+    end
+
+    it "converts a Bignum" do
+      @s.rb_num2dbl(2**70).should == (2**70).to_f
+    end
+
+    it "converts a Fixnum" do
+      @s.rb_num2dbl(5).should == 5.0
+    end
+
+    it "calls #to_f to coerce the value" do
+      obj = mock("number")
+      obj.should_receive(:to_f).and_return(2.0)
+      @s.rb_num2dbl(obj).should == 2.0
+    end
+  end
+
+  describe "NUM2CHR" do
+    it "returns the first character of a String" do
+      @s.NUM2CHR("Abc").should == 65
+    end
+
+    it "returns the least significant byte of an Integer" do
+      @s.NUM2CHR(0xa7c).should == 0x07c
+    end
+
+    it "returns the least significant byte of a Float converted to an Integer" do
+      @s.NUM2CHR(0xa7c.to_f).should == 0x07c
+    end
+
+    it "raises a TypeError when passed an empty String" do
+      lambda { @s.NUM2CHR("") }.should raise_error(TypeError)
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/object_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/object_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/object_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,357 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("object")
+
+# TODO: fix all these specs
+
+class CApiObjectSpecs
+  class Alloc
+    attr_reader :initialized, :arguments
+
+    def initialize(*args)
+      @initialized = true
+      @arguments   = args
+    end
+  end
+end
+
+describe "CApiObject" do
+
+  before do
+    @o = CApiObjectSpecs.new
+  end
+
+  class ObjectTest
+    def initialize
+      @foo = 7
+    end
+
+    def foo
+    end
+  end
+
+  class AryChild < Array
+  end
+
+  class StrChild < String
+  end
+
+  class DescObjectTest < ObjectTest
+  end
+
+  it "rb_obj_alloc should allocate a new uninitialized object" do
+    o = @o.rb_obj_alloc(CApiObjectSpecs::Alloc)
+    o.class.should == CApiObjectSpecs::Alloc
+    o.initialized.should be_nil
+  end
+
+  it "rb_obj_call_init should send #initialize" do
+    o = @o.rb_obj_alloc(CApiObjectSpecs::Alloc)
+    o.initialized.should be_nil
+
+    @o.rb_obj_call_init(o, 2, [:one, :two])
+    o.initialized.should be_true
+    o.arguments.should == [:one, :two]
+  end
+
+  it "rb_is_instance_of should return true if an object is an instance" do
+    @o.rb_obj_is_instance_of(ObjectTest.new, ObjectTest).should == true
+    @o.rb_obj_is_instance_of(DescObjectTest.new, ObjectTest).should == false
+  end
+
+  it "rb_is_kind_of should return true if an object is an instance or descendent" do
+    @o.rb_obj_is_kind_of(ObjectTest.new, ObjectTest).should == true
+    @o.rb_obj_is_kind_of(DescObjectTest.new, ObjectTest).should == true
+    @o.rb_obj_is_kind_of(Object.new, ObjectTest).should == false
+  end
+
+  it "rb_respond_to should return 1 if respond_to? is true and 0 if respond_to? is false" do
+    @o.rb_respond_to(ObjectTest.new, :foo).should == true
+    @o.rb_respond_to(ObjectTest.new, :bar).should == false
+  end
+
+  it "rb_to_id should return a symbol representation of the object" do
+    @o.rb_to_id("foo").should == :foo
+    @o.rb_to_id(:foo).should == :foo
+  end
+
+  it "rb_require should require a ruby file" do
+    $foo.should == nil
+    $:.unshift File.dirname(__FILE__)
+    @o.rb_require()
+    $foo.should == 7
+  end
+
+  it "rb_attr_get should get an instance variable" do
+    o = ObjectTest.new
+    @o.rb_attr_get(o, :@foo).should == 7
+  end
+
+  it "rb_check_array_type should try to coerce to array, otherwise return nil" do
+    ac = AryChild.new
+    ao = Array.new
+    h = Hash.new
+    @o.rb_check_array_type(ac).should == []
+    @o.rb_check_array_type(ao).should == []
+    @o.rb_check_array_type(h).should == nil
+  end
+
+  it "rb_check_convert_type should try to coerce to a type, otherwise return nil" do
+    ac = AryChild.new
+    ao = Array.new
+    h = Hash.new
+    # note that I force the ary information in the spec extension
+    @o.rb_check_convert_type(ac).should == []
+    @o.rb_check_convert_type(ao).should == []
+    @o.rb_check_convert_type(h).should == nil
+  end
+
+  it "rb_check_string_type should try to coerce to a string, otherwise return nil" do
+    sc = "Hello"
+    so = StrChild.new("Hello")
+    h = {:hello => :goodbye}
+    @o.rb_check_string_type(sc).should == "Hello"
+    @o.rb_check_string_type(so).should == "Hello"
+    @o.rb_check_string_type(h).should == nil
+  end
+
+  it "rb_convert_type should try to coerce to a type, otherwise raise a TypeError" do
+    ac = AryChild.new
+    ao = Array.new
+    h = Hash.new
+    # note that the ary information is forced in the spec extension
+    @o.rb_convert_type(ac).should == []
+    @o.rb_convert_type(ao).should == []
+    lambda { @o.rb_convert_type(h) }.should raise_error(TypeError)
+  end
+
+  it "rb_inspect should return a string with the inspect representation" do
+    @o.rb_inspect(nil).should == "nil"
+    @o.rb_inspect(0).should == '0'
+    @o.rb_inspect([1,2,3]).should == '[1, 2, 3]'
+    @o.rb_inspect("0").should == '"0"'
+  end
+
+  it "rb_class_of should return the class of a object" do
+    @o.rb_class_of(nil).should == NilClass
+    @o.rb_class_of(0).should == Fixnum
+    @o.rb_class_of(0.1).should == Float
+    @o.rb_class_of(ObjectTest.new).should == ObjectTest
+  end
+
+  it "rb_obj_classname should return the class name of a object" do
+    @o.rb_obj_classname(nil).should == 'NilClass'
+    @o.rb_obj_classname(0).should == 'Fixnum'
+    @o.rb_obj_classname(0.1).should == 'Float'
+    @o.rb_obj_classname(ObjectTest.new).should == 'ObjectTest'
+  end
+
+  it "rb_type should return the type constant for the object" do
+    class DescArray < Array
+    end
+    @o.rb_is_type_nil(nil).should == true
+    @o.rb_is_type_object([]).should == false
+    @o.rb_is_type_object(ObjectTest.new).should == true
+    @o.rb_is_type_array([]).should == true
+    @o.rb_is_type_array(DescArray.new).should == true
+    @o.rb_is_type_module(ObjectTest).should == false
+    @o.rb_is_type_class(ObjectTest).should == true
+    @o.rb_is_type_data(Time.now).should == true
+  end
+
+  describe "RTEST" do
+    it "returns C false if passed Qfalse" do
+      @o.RTEST(false).should be_false
+    end
+
+    it "returns C false if passed Qnil" do
+      @o.RTEST(nil).should be_false
+    end
+
+    it "returns C true if passed Qtrue" do
+      @o.RTEST(true).should be_true
+    end
+
+    it "returns C true if passed a Symbol" do
+      @o.RTEST(:test).should be_true
+    end
+
+    it "returns C true if passed an Object" do
+      @o.RTEST(Object.new).should be_true
+    end
+  end
+
+  describe "rb_special_const_p" do
+    it "returns true if passed Qfalse" do
+      @o.rb_special_const_p(false).should be_true
+    end
+
+    it "returns true if passed Qtrue" do
+      @o.rb_special_const_p(true).should be_true
+    end
+
+    it "returns true if passed Qnil" do
+      @o.rb_special_const_p(nil).should be_true
+    end
+
+    it "returns true if passed a Symbol" do
+      @o.rb_special_const_p(:test).should be_true
+    end
+
+    it "returns true if passed a Fixnum" do
+      @o.rb_special_const_p(10).should be_true
+    end
+
+    it "returns false if passed an Object" do
+      @o.rb_special_const_p(Object.new).should be_false
+    end
+  end
+
+  describe "rb_extend_object" do
+    it "add the module's instance methods to the object" do
+      module CApiObjectSpecs::Extend
+        def reach
+          :extended
+        end
+      end
+
+      obj = mock("extended object")
+      @o.rb_extend_object(obj, CApiObjectSpecs::Extend)
+      obj.reach.should == :extended
+    end
+  end
+
+  describe "OBJ_TAINT" do
+    it "taints the object" do
+      obj = mock("tainted")
+      @o.OBJ_TAINT(obj)
+      obj.tainted?.should be_true
+    end
+  end
+
+  describe "OBJ_TAINTED" do
+    it "returns C true if the object is tainted" do
+      obj = mock("tainted")
+      obj.taint
+      @o.OBJ_TAINTED(obj).should be_true
+    end
+
+    it "returns C false if the object is not tainted" do
+      obj = mock("untainted")
+      @o.OBJ_TAINTED(obj).should be_false
+    end
+  end
+
+  describe "rb_obj_freeze" do
+    it "freezes the object passed to it" do
+      obj = ""
+      @o.rb_obj_freeze(obj).should == obj
+      obj.frozen?.should be_true
+    end
+  end
+
+  extended_on :rubinius do
+    describe "rb_obj_frozen_p" do
+      it "returns true if object passed to it is frozen" do
+        obj = ""
+        obj.freeze
+        @o.rb_obj_frozen_p(obj).should == true
+      end
+
+      it "returns false if object passed to it is not frozen" do
+        obj = ""
+        @o.rb_obj_frozen_p(obj).should == false
+      end
+    end
+  end
+
+  describe "rb_obj_taint" do
+    it "marks the object passed as tainted" do
+      obj = ""
+      obj.tainted?.should == false
+      @o.rb_obj_taint(obj)
+      obj.tainted?.should == true
+    end
+
+    ruby_version_is ""..."1.9" do
+      it "raises a TypeError if the object passed is frozen" do
+        lambda { @o.rb_obj_taint("".freeze) }.should raise_error(TypeError)
+      end
+    end
+
+    ruby_version_is "1.9" do
+      it "raises a RuntimeError if the object passed is frozen" do
+        lambda { @o.rb_obj_taint("".freeze) }.should raise_error(RuntimeError)
+      end
+    end
+  end
+
+  describe "rb_check_frozen" do
+    ruby_version_is ""..."1.9" do
+      it "raises a TypeError if the obj is frozen" do
+        lambda { @o.rb_check_frozen("".freeze) }.should raise_error(TypeError)
+      end
+    end
+
+    ruby_version_is "1.9" do
+      it "raises a RuntimeError if the obj is frozen" do
+        lambda { @o.rb_check_frozen("".freeze) }.should raise_error(RuntimeError)
+      end
+    end
+
+    it "does nothing when object isn't frozen" do
+      obj = ""
+      lambda { @o.rb_check_frozen(obj) }.should_not raise_error(TypeError)
+    end
+  end
+
+  describe "rb_any_to_s" do
+    it "converts obj to string" do
+      obj = 1
+      i = @o.rb_any_to_s(obj)
+      i.should be_kind_of(String)
+    end
+  end
+
+  describe "rb_to_int" do
+    it "returns self when called on an Integer" do
+      @o.rb_to_int(5).should == 5
+    end
+
+    it "returns self when called on a Bignum" do
+      @o.rb_to_int(bignum_value()).should == bignum_value()
+    end
+
+    it "calls #to_int to convert and object to an integer" do
+      x = mock("to_int")
+      x.should_receive(:to_int).and_return(5)
+      @o.rb_to_int(x).should == 5
+    end
+
+    it "converts a Float to an Integer by truncation" do
+      @o.rb_to_int(1.35).should == 1
+    end
+
+    it "raises a TypeError if #to_int does not return an Integer" do
+      x = mock("to_int")
+      x.should_receive(:to_int).and_return("5")
+      lambda { @o.rb_to_int(x) }.should raise_error(TypeError)
+    end
+
+    it "raises a TypeError if called with nil" do
+      lambda { @o.rb_to_int(nil) }.should raise_error(TypeError)
+    end
+
+    it "raises a TypeError if called with true" do
+      lambda { @o.rb_to_int(true) }.should raise_error(TypeError)
+    end
+
+    it "raises a TypeError if called with false" do
+      lambda { @o.rb_to_int(false) }.should raise_error(TypeError)
+    end
+
+    it "raises a TypeError if called with a String" do
+      lambda { @o.rb_to_int("1") }.should raise_error(TypeError)
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/proc_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/proc_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/proc_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,21 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("proc")
+
+describe "CApiProc" do
+  before :each do
+    @p = CApiProcSpecs.new
+  end
+
+  it "rb_proc_new should return a new valid Proc" do
+    my_proc = @p.underline_concat_proc()
+    my_proc.kind_of?(Proc).should == true
+    my_proc.call('foo', 'bar').should == 'foo_bar'
+    my_proc['foo', 'bar'].should == 'foo_bar'
+  end
+
+  it "rb_proc_new returned proc should have arity -1" do
+    my_proc = @p.underline_concat_proc()
+    my_proc.arity.should == -1
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/rake_helper.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/rake_helper.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/rake_helper.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,23 @@
+require 'rake'
+require 'rake/clean'
+
+input = "#{$cwd}/#{$ext_name}.c"
+common = "-I shotgun/lib/subtend -g #{input}"
+
+case PLATFORM
+when /darwin/
+  output = "#{$cwd}/#{$ext_name}.bundle"
+  build_cmd = "cc -dynamic -bundle -undefined suppress -flat_namespace #{common} -o #{output}"
+else
+  output = "#{$cwd}/#{$ext_name}.so"
+  build_cmd = "cc -shared #{common} -o #{output}"
+end
+
+CLOBBER.include(output)
+
+task :default => [output]
+
+file output => [input] do
+  sh build_cmd
+end
+

Added: MacRuby/trunk/spec/frozen/optional/capi/range_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/range_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/range_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,42 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("range")
+
+describe "C-API Range function" do
+  before :each do
+    @s = CApiRangeSpecs.new
+  end
+
+  describe "rb_range_new" do
+    it "constructs a range using the given start and end" do
+      range = @s.rb_range_new('a', 'c')
+      range.should == ('a'..'c')
+
+      range.first.should == 'a'
+      range.last.should == 'c'
+    end
+
+    it "includes the end object when the third parameter is omitted or false" do
+      @s.rb_range_new('a', 'c').to_a.should == ['a', 'b', 'c']
+      @s.rb_range_new(1, 3).to_a.should == [1, 2, 3]
+
+      @s.rb_range_new('a', 'c', false).to_a.should == ['a', 'b', 'c']
+      @s.rb_range_new(1, 3, false).to_a.should == [1, 2, 3]
+
+      @s.rb_range_new('a', 'c', true).to_a.should == ['a', 'b']
+      @s.rb_range_new(1, 3, 1).to_a.should == [1, 2]
+
+      @s.rb_range_new(1, 3, mock('[1,2]')).to_a.should == [1, 2]
+      @s.rb_range_new(1, 3, :test).to_a.should == [1, 2]
+    end
+
+    it "raises an ArgumentError when the given start and end can't be compared by using #<=>" do
+      lambda { @s.rb_range_new(1, mock('x'))         }.should raise_error(ArgumentError)
+      lambda { @s.rb_range_new(mock('x'), mock('y')) }.should raise_error(ArgumentError)
+
+      b = mock('x')
+      (a = mock('nil')).should_receive(:method_missing).with(:<=>, b).and_return(nil)
+      lambda { @s.rb_range_new(a, b) }.should raise_error(ArgumentError)
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/safe_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/safe_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/safe_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,18 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("safe")
+
+describe "CApiSafeSpecs" do
+  before :each do
+    @f = CApiSafeSpecs.new
+  end
+
+  it "has a default safe level of 0" do
+    @f.rb_safe_level.should == 0
+  end
+
+  it "throws an error when rb_secure is called with argument >= SAFE" do
+    lambda { @f.rb_secure(0) }.should raise_error(SecurityError)
+  end
+
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/spec_helper.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/spec_helper.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/spec_helper.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,84 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+require 'rbconfig'
+
+# Generate a version.h file for specs to use
+File.open File.expand_path("../ext/rubyspec_version.h", __FILE__), "w" do |f|
+  # Yes, I know CONFIG variables exist for these, but
+  # who knows when those could be removed without warning.
+  major, minor, teeny = RUBY_VERSION.split(".")
+  f.puts "#define RUBY_VERSION_MAJOR  #{major}"
+  f.puts "#define RUBY_VERSION_MINOR  #{minor}"
+  f.puts "#define RUBY_VERSION_TEENY  #{teeny}"
+end
+
+CAPI_RUBY_SIGNATURE = "#{RUBY_NAME}-#{RUBY_VERSION}"
+
+def compile_extension(path, name)
+  ext       = File.join(path, "#{name}_spec")
+  source    = "#{ext}.c"
+  obj       = "#{ext}.o"
+  lib       = "#{ext}.#{RbConfig::CONFIG['DLEXT']}"
+  signature = "#{ext}.sig"
+
+  # TODO use rakelib/ext_helper.rb?
+  arch_hdrdir = nil
+  ruby_hdrdir = nil
+
+  if RUBY_NAME == 'rbx'
+    hdrdir = Rubinius::HDR_PATH
+  elsif RUBY_NAME =~ /^ruby/
+    if hdrdir = RbConfig::CONFIG["rubyhdrdir"]
+      arch_hdrdir = File.join hdrdir, RbConfig::CONFIG["arch"]
+      ruby_hdrdir = File.join hdrdir, "ruby"
+    else
+      hdrdir = RbConfig::CONFIG["archdir"]
+    end
+  else
+    raise "Don't know how to build C extensions with #{RUBY_NAME}"
+  end
+
+  ruby_header     = File.join(hdrdir, "ruby.h")
+  rubyspec_header = File.join(path, "rubyspec.h")
+  mri_header      = File.join(path, "mri.h")
+
+  return lib if File.exists?(signature) and
+                IO.read(signature).chomp == CAPI_RUBY_SIGNATURE and
+                File.exists?(lib) and File.mtime(lib) > File.mtime(source) and
+                File.mtime(lib) > File.mtime(ruby_header) and
+                File.mtime(lib) > File.mtime(rubyspec_header) and
+                File.mtime(lib) > File.mtime(mri_header)
+
+  # avoid problems where compilation failed but previous shlib exists
+  File.delete lib if File.exists? lib
+
+  cc        = RbConfig::CONFIG["CC"]
+  cflags    = (ENV["CFLAGS"] || RbConfig::CONFIG["CFLAGS"]).dup
+  cflags   += " -fPIC" unless cflags.include?("-fPIC")
+  incflags  = "-I#{path} -I#{hdrdir}"
+  incflags << " -I#{arch_hdrdir}" if arch_hdrdir
+  incflags << " -I#{ruby_hdrdir}" if ruby_hdrdir
+
+  `#{cc} #{incflags} #{cflags} -c #{source} -o #{obj}`
+
+  ldshared  = RbConfig::CONFIG["LDSHARED"]
+  libpath   = "-L#{path}"
+  libs      = RbConfig::CONFIG["LIBS"]
+  dldflags  = RbConfig::CONFIG["DLDFLAGS"]
+
+  `#{ldshared} #{obj} #{libpath} #{dldflags} #{libs} -o #{lib}`
+
+  # we don't need to leave the object file around
+  File.delete obj if File.exists? obj
+
+  File.open(signature, "w") { |f| f.puts CAPI_RUBY_SIGNATURE }
+
+  lib
+end
+
+def load_extension(name)
+  path = File.join(File.dirname(__FILE__), 'ext')
+
+  ext = compile_extension path, name
+  require ext
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/string_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/string_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/string_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,421 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension('string')
+
+describe "C-API String function" do
+  before :each do
+    @s = CApiStringSpecs.new
+  end
+
+  class ValidTostrTest
+    def to_str
+      "ruby"
+    end
+  end
+
+  class InvalidTostrTest
+    def to_str
+      []
+    end
+  end
+
+  describe "rb_str_new" do
+    it "returns a new string object from a char buffer of len characters" do
+      @s.rb_str_new("hello", 3).should == "hel"
+    end
+
+    it "returns an empty string if len is 0" do
+      @s.rb_str_new("hello", 0).should == ""
+    end
+  end
+
+  describe "rb_str_new2" do
+    it "returns a new string object calling strlen on the passed C string" do
+      # Hardcoded to pass const char * = "hello\0invisible"
+      @s.rb_str_new2.should == "hello"
+    end
+
+    ruby_version_is ""..."1.9" do
+      it "rb_str_new2 should raise ArgumentError if passed NULL" do
+        lambda { @s.rb_str_new2_with_null }.should raise_error(ArgumentError)
+      end
+    end
+  end
+
+  describe "rb_str_new3" do
+    it "returns a copy of the string" do
+      str1 = "hi"
+      str2 = @s.rb_str_new3 str1
+      str1.should == str2
+      str1.object_id.should_not == str2.object_id
+    end
+  end
+
+  describe "rb_str_dup" do
+    it "returns a copy of the string" do
+      str1 = "hi"
+      str2 = @s.rb_str_dup str1
+      str1.should == str2
+      str1.object_id.should_not == str2.object_id
+    end
+  end
+
+  describe "rb_str_append" do
+    it "appends a string to another string" do
+      @s.rb_str_append("Hello", " Goodbye").should == "Hello Goodbye"
+    end
+  end
+
+  describe "rb_str_plus" do
+    it "returns a new string from concatenating two other strings" do
+      @s.rb_str_plus("Hello", " Goodbye").should == "Hello Goodbye"
+    end
+  end
+
+  describe "rb_str_buf_cat" do
+    it "concatenates a C string to a ruby string" do
+      @s.rb_str_buf_cat("Your house is on fire").should == "Your house is on fire?"
+    end
+  end
+
+  describe "rb_str_cat" do
+    it "concatenates a C string to ruby string" do
+      @s.rb_str_cat("Your house is on fire").should == "Your house is on fire?"
+    end
+  end
+
+  describe "rb_str_cat2" do
+    it "concatenates a C string to a ruby string" do
+      @s.rb_str_cat2("Your house is on fire").should == "Your house is on fire?"
+    end
+  end
+
+  describe "rb_str_cmp" do
+    it "returns 0 if two strings are identical" do
+      @s.rb_str_cmp("ppp", "ppp").should == 0
+    end
+
+    it "returns -1 if the first string is shorter than the second" do
+      @s.rb_str_cmp("xxx", "xxxx").should == -1
+    end
+
+    it "returns -1 if the first string is lexically less than the second" do
+      @s.rb_str_cmp("xxx", "yyy").should == -1
+    end
+
+    it "returns 1 if the first string is longer than the second" do
+      @s.rb_str_cmp("xxxx", "xxx").should == 1
+    end
+
+    it "returns 1 if the first string is lexically greater than the second" do
+      @s.rb_str_cmp("yyy", "xxx").should == 1
+    end
+  end
+
+  describe "rb_str_split" do
+    it "splits strings over a splitter" do
+      @s.rb_str_split("Hello,Goodbye").should == ["Hello", "Goodbye"]
+    end
+  end
+
+  describe "rb_str2inum" do
+    it "converts a string to a number given a base" do
+      @s.rb_str2inum("10", 10).should == 10
+      @s.rb_str2inum("A", 16).should == 10
+    end
+  end
+
+  describe "rb_cstr2inum" do
+    it "converts a C string to a number given a base" do
+      @s.rb_cstr2inum("10", 10).should == 10
+      @s.rb_cstr2inum("10", 16).should == 16
+    end
+  end
+
+  describe "rb_str_substr" do
+    it "returns a substring" do
+      "hello".length.times do |time|
+        @s.rb_str_substr("hello", 0, time + 1).should == "hello"[0..time]
+      end
+    end
+  end
+
+  describe "rb_str_to_str" do
+    it "calls #to_str to coerce the value to a String" do
+      @s.rb_str_to_str("foo").should == "foo"
+      @s.rb_str_to_str(ValidTostrTest.new).should == "ruby"
+    end
+
+    it "raises a TypeError if coercion fails" do
+      lambda { @s.rb_str_to_str(0) }.should raise_error(TypeError)
+      lambda { @s.rb_str_to_str(InvalidTostrTest.new) }.should raise_error(TypeError)
+    end
+  end
+
+  ruby_version_is ""..."1.9" do
+    describe "RSTRING" do
+      it "returns struct with a pointer to the string's contents" do
+        str = "xyz"
+        chars = []
+        @s.RSTRING_ptr_iterate(str) do |c|
+          chars << c
+        end
+        chars.should == [120, 121, 122]
+      end
+
+      it "allows changing the characters in the string" do
+        str = "abc"
+        @s.RSTRING_ptr_assign(str, 70)
+        str.should == "FFF"
+      end
+
+      it "allows changing the string and calling a rb_str_xxx function" do
+        str = "abc"
+        @s.RSTRING_ptr_assign_call(str)
+        str.should == "axcd"
+      end
+
+      it "allows changing the string and calling a method via rb_funcall" do
+        str = "abc"
+        @s.RSTRING_ptr_assign_funcall(str)
+        str.should == "axce"
+      end
+
+      it "returns a struct with the string's length" do
+        @s.RSTRING_len("dewdrops").should == 8
+      end
+    end
+  end
+
+  describe "RSTRING_PTR" do
+    it "returns a pointer to the string's contents" do
+      str = "abc"
+      chars = []
+      @s.RSTRING_PTR_iterate(str) do |c|
+        chars << c
+      end
+      chars.should == [97, 98, 99]
+    end
+
+    it "allows changing the characters in the string" do
+      str = "abc"
+      @s.RSTRING_PTR_assign(str, 65)
+      str.should == "AAA"
+    end
+
+    it "reflects changes after a rb_funcall" do
+      lamb = proc { |s| s.replace "NEW CONTENT" }
+
+      str = "beforebefore"
+
+      ret = @s.RSTRING_PTR_after_funcall(str, lamb)
+
+      str.should == "NEW CONTENT"
+      ret.should == str
+    end
+  end
+
+  describe "RSTRING_LEN" do
+    it "returns the size of the string" do
+      @s.RSTRING_LEN("gumdrops").should == 8
+    end
+  end
+
+  describe "StringValue" do
+    it "does not call #to_str on a String" do
+      str = "genuine"
+      str.should_not_receive(:to_str)
+      @s.StringValue(str)
+    end
+
+    it "does not call #to_s on a String" do
+      str = "genuine"
+      str.should_not_receive(:to_str)
+      @s.StringValue(str)
+    end
+
+    it "calls #to_str on non-String objects" do
+      str = mock("fake")
+      str.should_receive(:to_str).and_return("wannabe")
+      @s.StringValue(str)
+    end
+
+    it "does not call #to_s on non-String objects" do
+      str = mock("fake")
+      str.should_not_receive(:to_s)
+      lambda { @s.StringValue(str) }.should raise_error(TypeError)
+    end
+  end
+
+  describe "rb_str_resize" do
+    it "reduces the size of the string" do
+      str = @s.rb_str_resize("test", 2)
+      str.size.should == 2
+      @s.RSTRING_LEN(str).should == 2
+      str.should == "te"
+    end
+
+    it "updates the string's attributes visible in C code" do
+      @s.rb_str_resize_RSTRING_LEN("test", 2).should == 2
+    end
+
+    it "increases the size of the string" do
+      str = @s.rb_str_resize("test", 12)
+      str.size.should == 12
+      @s.RSTRING_LEN(str).should == 12
+      str[0, 5].should == "test\x00"
+    end
+  end
+
+  describe "rb_str_intern" do
+    it "returns a symbol created from the string" do
+      @s.rb_str_intern("symbol").should == :symbol
+    end
+
+    ruby_version_is ""..."1.9" do
+      it "raises an ArgumentError if passed an empty string" do
+        lambda { @s.rb_str_intern("") }.should raise_error(ArgumentError)
+      end
+
+      it "raises an ArgumentError if the passed string contains NULL characters" do
+        lambda { @s.rb_str_intern("no\0no") }.should raise_error(ArgumentError)
+      end
+    end
+
+    ruby_version_is "1.9" do
+      it "returns a symbol even if passed an empty string" do
+        @s.rb_str_intern("").should == "".to_sym
+      end
+
+      it "returns a symbol even if the passed string contains NULL characters" do
+        @s.rb_str_intern("no\0no").should == "no\0no".to_sym
+      end
+    end
+  end
+
+  ruby_version_is ""..."1.9" do
+    describe "rb_str2cstr" do
+      before :each do
+        @verbose = $VERBOSE
+        @stderr, $stderr = $stderr, IOStub.new
+      end
+
+      after :each do
+        $stderr = @stderr
+        $VERBOSE = @verbose
+      end
+
+      it "returns a pointer to the string's content and its length" do
+        str, len = @s.rb_str2cstr('any str', true)
+        str.should == 'any str'
+        len.should == 7
+      end
+
+      it "allows changing the characters in the string" do
+        str = 'any str'
+        # Hardcoded to set "foo\0"
+        @s.rb_str2cstr_replace(str)
+        str.should == "foo\0str"
+      end
+
+      it "issues a warning iff passed string contains a NULL character, $VERBOSE = true and len parameter is NULL" do
+        $VERBOSE = false
+        @s.rb_str2cstr('any str', true)
+        $stderr.should == ''
+
+        @s.rb_str2cstr('any str', false)
+        $stderr.should == ''
+
+        $VERBOSE = true
+        @s.rb_str2cstr('any str', true)
+        $stderr.should == ''
+
+        @s.rb_str2cstr('any str', false)
+        $stderr.should == ''
+
+        $VERBOSE = false
+        @s.rb_str2cstr("any\0str", true)
+        $stderr.should == ''
+
+        @s.rb_str2cstr("any\0str", false)
+        $stderr.should == ''
+
+        $VERBOSE = true
+        @s.rb_str2cstr("any\0str", true)
+        $stderr.should == ''
+
+        @s.rb_str2cstr("any\0str", false)
+        $stderr.should =~ /string contains \\0 character/
+      end
+    end
+
+    describe "STR2CSTR" do
+      it "returns a pointer to the string's content" do
+        @s.STR2CSTR('any str').should == 'any str'
+      end
+
+      it "allows changing the characters in the string" do
+        str = 'any str'
+        # Hardcoded to set "foo\0"
+        @s.STR2CSTR_replace(str)
+        str.should == "foo\0str"
+      end
+    end
+  end
+
+  describe "rb_str_freeze" do
+    it "freezes the string" do
+      s = ""
+      @s.rb_str_freeze(s).should == s
+      s.frozen?.should be_true
+    end
+  end
+
+  extended_on :rubinius do
+    describe "rb_str_ptr" do
+      it "returns struct with a pointer to the string's contents" do
+        str = "xyz"
+        chars = []
+        @s.rb_str_ptr_iterate(str) do |c|
+          chars << c
+        end
+        chars.should == [120, 121, 122]
+      end
+
+      it "allows changing the characters in the string" do
+        str = "abc"
+        @s.rb_str_ptr_assign(str, 70)
+        str.should == "FFF"
+      end
+
+      it "allows changing the string and calling a rb_str_xxx function" do
+        str = "abc"
+        @s.rb_str_ptr_assign_call(str)
+        str.should == "axcd"
+      end
+
+      it "allows changing the string and calling a method via rb_funcall" do
+        str = "abc"
+        @s.rb_str_ptr_assign_funcall(str)
+        str.should == "axce"
+      end
+    end
+
+    describe "rb_str_ptr_readonly" do
+      it "returns struct with a pointer to the string's contents" do
+        str = "xyz"
+        chars = []
+        @s.rb_str_ptr_readonly_iterate(str) do |c|
+          chars << c
+        end
+        chars.should == [120, 121, 122]
+      end
+    end
+
+    describe "rb_str_len" do
+      it "returns the string's length" do
+        @s.rb_str_len("dewdrops").should == 8
+      end
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/struct_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/struct_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/struct_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,55 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("struct")
+
+describe "CApiStruct" do
+  before :each do
+    @s = CApiStructSpecs.new
+  end
+
+  it "rb_struct_define defines a structure" do
+    @s.rb_struct_define("MyStruct", "attr1", "attr2", "attr3")
+    instance = Struct::MyStruct.new
+    (instance.attr1 = 1).should == 1
+    (instance.attr2 = 2).should == 2
+    (instance.attr3 = 3).should == 3
+    # Verify that attributes are on an instance basis
+    Struct::MyStruct.new.attr1.should == nil
+  end
+
+  it "rb_struct_define allows for anonymous structures" do
+    klass = @s.rb_struct_define(nil, "attr1", "attr2", "attr3")
+    instance = klass.new()
+    (instance.attr1 = 1).should == 1
+    (instance.attr2 = 2).should == 2
+    (instance.attr3 = 3).should == 3
+  end
+
+  ruby_version_is ""..."1.9" do
+    it "rb_struct_define defines a structure and returns members as string" do
+      @s.rb_struct_define("MyStruct", "attr1", "attr2", "attr3")
+      instance = Struct::MyStruct.new
+      instance.members.sort.should == ["attr1", "attr2", "attr3"].sort
+    end
+
+    it "rb_struct_define allows for anonymous structures" do
+      klass = @s.rb_struct_define(nil, "attr1", "attr2", "attr3")
+      instance = klass.new()
+      instance.members.sort.should == ["attr1", "attr2", "attr3"].sort
+    end
+  end
+
+  ruby_version_is "1.9" do
+    it "rb_struct_define defines a structure and returns members as symbol" do
+      @s.rb_struct_define("MyStruct", "attr1", "attr2", "attr3")
+      instance = Struct::MyStruct.new
+      instance.members.sort.should == [:attr1, :attr2, :attr3].sort
+    end
+
+    it "rb_struct_define allows for anonymous structures" do
+      klass = @s.rb_struct_define(nil, "attr1", "attr2", "attr3")
+      instance = klass.new()
+      instance.members.sort.should == [:attr1, :attr2, :attr3].sort
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/symbol_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/symbol_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/symbol_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,63 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension('symbol')
+
+describe "C-API Symbol function" do
+  before :each do
+    @s = CApiSymbolSpecs.new
+  end
+
+  describe "rb_is_const_id" do
+    it "returns true given a const-like symbol" do
+      @s.rb_is_const_id(:Foo).should == true
+    end
+
+    it "returns false given an ivar-like symbol" do
+      @s.rb_is_const_id(:@foo).should == false
+    end
+
+    it "returns false given a cvar-like symbol" do
+      @s.rb_is_const_id(:@@foo).should == false
+    end
+
+    it "returns false given an undecorated symbol" do
+      @s.rb_is_const_id(:foo).should == false
+    end
+  end
+
+  describe "rb_is_instance_id" do
+    it "returns false given a const-like symbol" do
+      @s.rb_is_instance_id(:Foo).should == false
+    end
+
+    it "returns true given an ivar-like symbol" do
+      @s.rb_is_instance_id(:@foo).should == true
+    end
+
+    it "returns false given a cvar-like symbol" do
+      @s.rb_is_instance_id(:@@foo).should == false
+    end
+
+    it "returns false given an undecorated symbol" do
+      @s.rb_is_instance_id(:foo).should == false
+    end
+  end
+
+  describe "rb_is_class_id" do
+    it "returns false given a const-like symbol" do
+      @s.rb_is_class_id(:Foo).should == false
+    end
+
+    it "returns false given an ivar-like symbol" do
+      @s.rb_is_class_id(:@foo).should == false
+    end
+
+    it "returns true given a cvar-like symbol" do
+      @s.rb_is_class_id(:@@foo).should == true
+    end
+
+    it "returns false given an undecorated symbol" do
+      @s.rb_is_class_id(:foo).should == false
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/thread_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/thread_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/thread_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,78 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("thread")
+
+describe "CApiThreadSpecs" do
+  before :each do
+    @t = CApiThreadSpecs.new
+    ScratchPad.clear
+  end
+
+  describe "rb_thread_select" do
+    it "returns true if an fd is ready to read" do
+      read, write = IO.pipe
+
+      @t.rb_thread_select_fd(read.to_i, 0).should == false
+      write << "1"
+      @t.rb_thread_select_fd(read.to_i, 0).should == true
+    end
+
+    it "does not block all threads" do
+      t = Thread.new do
+        sleep 0.25
+        ScratchPad.record :inner
+      end
+      Thread.pass while t.status and t.status != "sleep"
+
+      @t.rb_thread_select(500_000)
+
+      t.alive?.should be_false
+      ScratchPad.recorded.should == :inner
+
+      t.join
+    end
+  end
+
+  describe "rb_thread_alone" do
+    it "returns true if there is only one thread" do
+      pred = Thread.list.size == 1
+      @t.rb_thread_alone.should == pred
+    end
+  end
+
+  describe "rb_thread_current" do
+    it "equals Thread.current" do
+      @t.rb_thread_current.should == Thread.current
+    end
+  end
+
+  describe "rb_thread_local_aref" do
+    it "returns the value of a thread-local variable" do
+      thr = Thread.current
+      sym = :thread_capi_specs_aref
+      thr[sym] = 1
+      @t.rb_thread_local_aref(thr, sym).should == 1
+    end
+
+    it "returns nil if the value has not been set" do
+      @t.rb_thread_local_aref(Thread.current, :thread_capi_specs_undefined).should be_nil
+    end
+  end
+
+  describe "rb_thread_local_aset" do
+    it "sets the value of a thread-local variable" do
+      thr = Thread.current
+      sym = :thread_capi_specs_aset
+      @t.rb_thread_local_aset(thr, sym, 2).should == 2
+      thr[sym].should == 2
+    end
+  end
+
+  extended_on :rubinius do
+    describe "rb_thread_blocking_region" do
+      it "runs a C function with the global lock unlocked" do
+        @t.rb_thread_blocking_region.should be_true
+      end
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/optional/capi/time_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/optional/capi/time_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/optional/capi/time_spec.rb	2010-08-22 13:17:27 UTC (rev 4441)
@@ -0,0 +1,15 @@
+require File.expand_path('../spec_helper', __FILE__)
+
+load_extension("time")
+
+describe "CApiTimeSpecs" do
+  before :each do
+    @s = CApiTimeSpecs.new
+  end
+
+  describe "rb_time_new" do
+    it "creates a Time from the sec and usec" do
+      @s.rb_time_new(1232141421, 1413123123).should == Time.at(1232141421, 1413123123)
+    end
+  end
+end
\ No newline at end of file
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100822/a81ce753/attachment-0001.html>


More information about the macruby-changes mailing list