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

source_changes at macosforge.org source_changes at macosforge.org
Fri Aug 28 16:39:33 PDT 2009


Revision: 2412
          http://trac.macosforge.org/projects/ruby/changeset/2412
Author:   eloy.de.enige at gmail.com
Date:     2009-08-28 16:39:32 -0700 (Fri, 28 Aug 2009)
Log Message:
-----------
Updated RubySpec to 16a88a4e3061edfae4d74def378e97bf2533e825

Modified Paths:
--------------
    MacRuby/trunk/spec/frozen/command_line/dash_r_spec.rb
    MacRuby/trunk/spec/frozen/command_line/fixtures/verbose.rb
    MacRuby/trunk/spec/frozen/command_line/shared/verbose.rb
    MacRuby/trunk/spec/frozen/core/dir/getwd_spec.rb
    MacRuby/trunk/spec/frozen/core/dir/shared/exists.rb
    MacRuby/trunk/spec/frozen/core/encoding/converter/asciicompat_encoding_spec.rb
    MacRuby/trunk/spec/frozen/core/enumerable/sort_by_spec.rb
    MacRuby/trunk/spec/frozen/core/io/foreach_spec.rb
    MacRuby/trunk/spec/frozen/core/io/puts_spec_disabled.rb
    MacRuby/trunk/spec/frozen/core/io/read_spec.rb
    MacRuby/trunk/spec/frozen/core/kernel/eval_spec.rb
    MacRuby/trunk/spec/frozen/core/kernel/fixtures/classes.rb
    MacRuby/trunk/spec/frozen/core/kernel/method_spec.rb
    MacRuby/trunk/spec/frozen/core/kernel/respond_to_spec.rb
    MacRuby/trunk/spec/frozen/core/kernel/singleton_methods_spec.rb
    MacRuby/trunk/spec/frozen/core/matchdata/element_reference_spec.rb
    MacRuby/trunk/spec/frozen/core/method/equal_value_spec.rb
    MacRuby/trunk/spec/frozen/core/method/fixtures/classes.rb
    MacRuby/trunk/spec/frozen/core/random/int_spec.rb
    MacRuby/trunk/spec/frozen/core/regexp/last_match_spec.rb
    MacRuby/trunk/spec/frozen/core/regexp/quote_spec.rb
    MacRuby/trunk/spec/frozen/core/string/ascii_only_spec_disabled.rb
    MacRuby/trunk/spec/frozen/core/string/element_reference_spec_disabled.rb
    MacRuby/trunk/spec/frozen/core/string/gsub_spec.rb
    MacRuby/trunk/spec/frozen/core/string/scan_spec.rb
    MacRuby/trunk/spec/frozen/core/string/shared/slice.rb
    MacRuby/trunk/spec/frozen/core/string/slice_spec_disabled.rb
    MacRuby/trunk/spec/frozen/core/time/at_spec.rb
    MacRuby/trunk/spec/frozen/language/not_spec.rb
    MacRuby/trunk/spec/frozen/language/predefined_spec.rb
    MacRuby/trunk/spec/frozen/language/regexp_spec.rb
    MacRuby/trunk/spec/frozen/language/rescue_spec.rb
    MacRuby/trunk/spec/frozen/language/versions/retry_1.8.rb
    MacRuby/trunk/spec/frozen/language/versions/symbol_1.9.rb
    MacRuby/trunk/spec/frozen/library/enumerator/enum_cons_spec.rb
    MacRuby/trunk/spec/frozen/library/enumerator/enum_for_spec.rb
    MacRuby/trunk/spec/frozen/library/enumerator/enum_slice_spec.rb
    MacRuby/trunk/spec/frozen/library/enumerator/enum_with_index_spec.rb
    MacRuby/trunk/spec/frozen/library/enumerator/new_spec.rb
    MacRuby/trunk/spec/frozen/library/enumerator/next_spec.rb
    MacRuby/trunk/spec/frozen/library/enumerator/rewind_spec.rb
    MacRuby/trunk/spec/frozen/library/enumerator/to_enum_spec.rb
    MacRuby/trunk/spec/frozen/library/tempfile/open_spec.rb
    MacRuby/trunk/spec/frozen/shared/complex/divide.rb
    MacRuby/trunk/spec/frozen/upstream

Added Paths:
-----------
    MacRuby/trunk/spec/frozen/core/bignum/even_spec.rb
    MacRuby/trunk/spec/frozen/core/bignum/odd_spec.rb
    MacRuby/trunk/spec/frozen/core/complex/integer_spec.rb
    MacRuby/trunk/spec/frozen/core/dir/inspect_spec.rb
    MacRuby/trunk/spec/frozen/core/encoding/ascii_compatible_spec.rb
    MacRuby/trunk/spec/frozen/core/enumerable/find_index_spec.rb
    MacRuby/trunk/spec/frozen/core/enumerable/none_spec.rb
    MacRuby/trunk/spec/frozen/core/enumerable/one_spec.rb
    MacRuby/trunk/spec/frozen/core/enumerator/
    MacRuby/trunk/spec/frozen/core/enumerator/each_spec.rb
    MacRuby/trunk/spec/frozen/core/enumerator/each_with_index_spec.rb
    MacRuby/trunk/spec/frozen/core/enumerator/enum_for_spec.rb
    MacRuby/trunk/spec/frozen/core/enumerator/new_spec.rb
    MacRuby/trunk/spec/frozen/core/enumerator/next_spec.rb
    MacRuby/trunk/spec/frozen/core/enumerator/peek_spec.rb
    MacRuby/trunk/spec/frozen/core/enumerator/rewind_spec.rb
    MacRuby/trunk/spec/frozen/core/enumerator/to_enum_spec.rb
    MacRuby/trunk/spec/frozen/core/enumerator/with_index_spec.rb
    MacRuby/trunk/spec/frozen/core/file/absolute_path_spec.rb
    MacRuby/trunk/spec/frozen/core/file/stat/world_readable_spec.rb
    MacRuby/trunk/spec/frozen/core/file/stat/world_writable_spec.rb
    MacRuby/trunk/spec/frozen/core/file/to_path_spec.rb
    MacRuby/trunk/spec/frozen/core/file/world_readable_spec.rb
    MacRuby/trunk/spec/frozen/core/file/world_writable_spec.rb
    MacRuby/trunk/spec/frozen/core/float/rationalize_spec.rb
    MacRuby/trunk/spec/frozen/core/hash/assoc_spec.rb
    MacRuby/trunk/spec/frozen/core/hash/compare_by_identity_spec.rb
    MacRuby/trunk/spec/frozen/core/hash/flatten_spec.rb
    MacRuby/trunk/spec/frozen/core/hash/rassoc_spec.rb
    MacRuby/trunk/spec/frozen/core/hash/try_convert_spec.rb
    MacRuby/trunk/spec/frozen/core/kernel/define_singleton_method_spec.rb
    MacRuby/trunk/spec/frozen/core/kernel/public_method_spec.rb
    MacRuby/trunk/spec/frozen/core/kernel/shared/method.rb
    MacRuby/trunk/spec/frozen/core/kernel/spawn_spec.rb
    MacRuby/trunk/spec/frozen/core/matchdata/versions/
    MacRuby/trunk/spec/frozen/core/matchdata/versions/element_reference_1.9.rb
    MacRuby/trunk/spec/frozen/core/method/eql_spec.rb
    MacRuby/trunk/spec/frozen/core/method/fixtures/classes_1.9.rb
    MacRuby/trunk/spec/frozen/core/method/parameters_spec.rb
    MacRuby/trunk/spec/frozen/core/method/shared/eql.rb
    MacRuby/trunk/spec/frozen/core/method/versions/
    MacRuby/trunk/spec/frozen/core/method/versions/parameters_1.9.rb
    MacRuby/trunk/spec/frozen/core/nil/rationalize_spec.rb
    MacRuby/trunk/spec/frozen/core/nil/to_r_spec.rb
    MacRuby/trunk/spec/frozen/core/numeric/i_spec.rb
    MacRuby/trunk/spec/frozen/core/numeric/rationalize_spec.rb
    MacRuby/trunk/spec/frozen/core/range/max_spec.rb
    MacRuby/trunk/spec/frozen/core/range/min_spec.rb
    MacRuby/trunk/spec/frozen/core/rational/integer_spec.rb
    MacRuby/trunk/spec/frozen/core/rational/rationalize_spec.rb
    MacRuby/trunk/spec/frozen/core/rational/zero_spec.rb
    MacRuby/trunk/spec/frozen/core/regexp/encoding_spec.rb
    MacRuby/trunk/spec/frozen/core/regexp/fixed_encoding_spec.rb
    MacRuby/trunk/spec/frozen/core/regexp/named_captures_spec.rb
    MacRuby/trunk/spec/frozen/core/regexp/names_spec.rb
    MacRuby/trunk/spec/frozen/core/regexp/try_convert_spec.rb
    MacRuby/trunk/spec/frozen/core/regexp/versions/
    MacRuby/trunk/spec/frozen/core/regexp/versions/named_captures_1.9.rb
    MacRuby/trunk/spec/frozen/core/regexp/versions/names_1.9.rb
    MacRuby/trunk/spec/frozen/core/string/shared/versions/
    MacRuby/trunk/spec/frozen/core/string/shared/versions/slice_1.9.rb
    MacRuby/trunk/spec/frozen/core/symbol/capitalize_spec.rb
    MacRuby/trunk/spec/frozen/core/symbol/downcase_spec.rb
    MacRuby/trunk/spec/frozen/core/symbol/empty_spec.rb
    MacRuby/trunk/spec/frozen/core/symbol/swapcase_spec.rb
    MacRuby/trunk/spec/frozen/core/symbol/upcase_spec.rb
    MacRuby/trunk/spec/frozen/fixtures/enumerator/
    MacRuby/trunk/spec/frozen/fixtures/enumerator/classes.rb
    MacRuby/trunk/spec/frozen/language/predefined_spec.rb.orig
    MacRuby/trunk/spec/frozen/language/regexp/
    MacRuby/trunk/spec/frozen/language/regexp/anchors_spec.rb
    MacRuby/trunk/spec/frozen/language/regexp/back-references_spec.rb
    MacRuby/trunk/spec/frozen/language/regexp/character_classes_spec.rb
    MacRuby/trunk/spec/frozen/language/regexp/encoding_spec.rb
    MacRuby/trunk/spec/frozen/language/regexp/escapes_spec.rb
    MacRuby/trunk/spec/frozen/language/regexp/grouping_spec.rb
    MacRuby/trunk/spec/frozen/language/regexp/interpolation_spec.rb
    MacRuby/trunk/spec/frozen/language/regexp/modifiers_spec.rb
    MacRuby/trunk/spec/frozen/language/regexp/repetition_spec.rb
    MacRuby/trunk/spec/frozen/language/regexp/versions/
    MacRuby/trunk/spec/frozen/language/regexp/versions/character_classes_1.9.rb
    MacRuby/trunk/spec/frozen/language/versions/not_1.9.rb
    MacRuby/trunk/spec/frozen/library/enumerator/each_spec.rb
    MacRuby/trunk/spec/frozen/library/enumerator/each_with_index_spec.rb
    MacRuby/trunk/spec/frozen/library/enumerator/with_index_spec.rb
    MacRuby/trunk/spec/frozen/shared/enumerator/
    MacRuby/trunk/spec/frozen/shared/enumerator/each.rb
    MacRuby/trunk/spec/frozen/shared/enumerator/enum_cons.rb
    MacRuby/trunk/spec/frozen/shared/enumerator/enum_for.rb
    MacRuby/trunk/spec/frozen/shared/enumerator/new.rb
    MacRuby/trunk/spec/frozen/shared/enumerator/next.rb
    MacRuby/trunk/spec/frozen/shared/enumerator/rewind.rb
    MacRuby/trunk/spec/frozen/shared/enumerator/with_index.rb
    MacRuby/trunk/spec/frozen/shared/file/world_readable.rb
    MacRuby/trunk/spec/frozen/shared/file/world_writable.rb

Removed Paths:
-------------
    MacRuby/trunk/spec/frozen/core/enumerable/each_spec.rb
    MacRuby/trunk/spec/frozen/core/enumerable/find_index.rb
    MacRuby/trunk/spec/frozen/core/kernel/define_singleton_method.rb
    MacRuby/trunk/spec/frozen/library/enumerator/fixtures/classes.rb
    MacRuby/trunk/spec/frozen/library/enumerator/shared/enum_for.rb

Modified: MacRuby/trunk/spec/frozen/command_line/dash_r_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/command_line/dash_r_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/command_line/dash_r_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -2,6 +2,6 @@
 
 describe "The -r command line option" do
   it "requires the specified file" do
-    ruby_exe("fixtures/require.rb", :options => "-r fixtures/test_file", :dir => File.dirname(__FILE__)).chomp.should include("fixtures/test_file.rb")
+    ruby_exe("fixtures/require.rb", :options => "-r ./fixtures/test_file", :dir => File.dirname(__FILE__)).chomp.should include("fixtures/test_file.rb")
   end
 end

Modified: MacRuby/trunk/spec/frozen/command_line/fixtures/verbose.rb
===================================================================
--- MacRuby/trunk/spec/frozen/command_line/fixtures/verbose.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/command_line/fixtures/verbose.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1 +1 @@
-puts $VERBOSE
+puts $VERBOSE.inspect

Modified: MacRuby/trunk/spec/frozen/command_line/shared/verbose.rb
===================================================================
--- MacRuby/trunk/spec/frozen/command_line/shared/verbose.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/command_line/shared/verbose.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,5 +1,5 @@
 describe "sets $VERBOSE to true", :shared => true do
   it "sets $VERBOSE to true" do
-    ruby_exe("fixtures/verbose.rb", :options => @method, :dir => "#{File.dirname(__FILE__)}\\..").chomp.match(/true$/).should_not == nil
+    ruby_exe("fixtures/verbose.rb", :options => @method, :dir => "#{File.dirname(__FILE__)}/..").chomp.match(/true$/).should_not == nil
   end
 end

Added: MacRuby/trunk/spec/frozen/core/bignum/even_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/bignum/even_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/bignum/even_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,21 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.8.7" do
+  describe "Bignum#even?" do
+    it "returns true if self is even and positive" do
+      (10000**10).even?.should be_true
+    end
+
+    it "returns true if self is even and negative" do
+      (-10000**10).even?.should be_true
+    end
+
+    it "returns false if self is odd and positive" do
+      (9879**976).even?.should be_false
+    end
+
+    it "returns false if self is odd and negative" do
+      (-9879**976).even?.should be_false
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/bignum/odd_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/bignum/odd_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/bignum/odd_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,21 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.8.7" do
+  describe "Bignum#odd?" do
+    it "returns true if self is odd and positive" do
+      (987279**19).odd?.should be_true
+    end
+
+    it "returns true if self is odd and negative" do
+      (-9873389**97).odd?.should be_true
+    end
+
+    it "returns false if self is even and positive" do
+      (10000000**10).odd?.should be_false
+    end
+
+    it "returns false if self is even and negative" do
+      (-1000000**100).odd?.should be_false
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/complex/integer_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/complex/integer_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/complex/integer_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,13 @@
+ruby_version_is "1.9" do
+  describe "Complex#integer?" do
+
+    it "returns false for a Complex with no imaginary part" do
+      Complex(20).integer?.should be_false
+    end 
+
+    it "returns false for a Complex with an imaginary part" do
+      Complex(20,3).integer?.should be_false
+    end 
+
+  end
+end

Modified: MacRuby/trunk/spec/frozen/core/dir/getwd_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/dir/getwd_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/dir/getwd_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -2,6 +2,6 @@
 require File.dirname(__FILE__) + '/fixtures/common'
 require File.dirname(__FILE__) + '/shared/pwd'
 
-describe "Dir.pwd" do
+describe "Dir.getwd" do
   it_behaves_like :dir_pwd, :getwd
 end

Added: MacRuby/trunk/spec/frozen/core/dir/inspect_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/dir/inspect_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/dir/inspect_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,17 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.8.7" do
+  describe "Dir#inspect" do
+    it "returns a String" do
+      Dir.new(Dir.getwd).inspect.should be_an_instance_of(String)
+    end
+
+    it "includes the class name" do
+      Dir.new(Dir.getwd).inspect.should =~ /Dir/
+    end
+
+    it "includes the directory name" do
+      Dir.new(Dir.getwd).inspect.should include(Dir.getwd)
+    end
+  end
+end

Modified: MacRuby/trunk/spec/frozen/core/dir/shared/exists.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/dir/shared/exists.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/dir/shared/exists.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -33,9 +33,9 @@
     Dir.send(@method, dir).should be_true
   end
 
-  it "expands paths" do
+  it "doesn't expand paths" do
     Dir.send(@method, File.expand_path('~')).should be_true
-    Dir.send(@method, '~').should be_true
+    Dir.send(@method, '~').should be_false
   end
 
   it "returns false if the argument exists but is a file" do

Added: MacRuby/trunk/spec/frozen/core/encoding/ascii_compatible_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/encoding/ascii_compatible_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/encoding/ascii_compatible_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,13 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "Encoding#ascii_compatible?" do
+    it "returns true if self represents an ASCII-compatible encoding" do
+      Encoding::UTF_8.ascii_compatible?.should be_true
+    end
+
+    it "returns false if self does not represent an ASCII-compatible encoding" do
+      Encoding::UTF_16LE.ascii_compatible?.should be_false
+    end
+  end
+end

Modified: MacRuby/trunk/spec/frozen/core/encoding/converter/asciicompat_encoding_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/encoding/converter/asciicompat_encoding_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/encoding/converter/asciicompat_encoding_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -29,27 +29,20 @@
       Encoding::Converter.asciicompat_encoding('UTF-8').should be_nil
     end
 
-    quarantine! do
-      # Reported as bug #1659
-      it "handles encoding names who resolve to nil encodings" do
-        internal = Encoding.default_internal
-        Encoding.default_internal = nil
-        Encoding::Converter.asciicompat_encoding('internal')
-        Encoding.default_internal = internal
-      end
+    it "handles encoding names who resolve to nil encodings" do
+      internal = Encoding.default_internal
+      Encoding.default_internal = nil
+      Encoding::Converter.asciicompat_encoding('internal').should be_nil
+      Encoding.default_internal = internal
     end
 
     it "returns nil if called with an encoding it returned previously" do
       internal = Encoding.default_internal
-      # We set the default_internal encoding explicitly because otherwise we
-      # trigger bug #1659
-      Encoding.default_internal = 'UTF-8'
       Encoding.name_list.each do |name|
         asciicompat = Encoding::Converter.asciicompat_encoding(name)
         next if asciicompat.nil?
         Encoding::Converter.asciicompat_encoding(asciicompat).should be_nil
       end
-      Encoding.default_internal = internal
     end
   end
 end

Deleted: MacRuby/trunk/spec/frozen/core/enumerable/each_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/enumerable/each_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/enumerable/each_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,14 +0,0 @@
-require File.dirname(__FILE__) + '/../../spec_helper'
-require File.dirname(__FILE__) + '/fixtures/classes'
-
-describe "Enumerable.each" do    
-  it "is provided" do
-    EnumerableSpecs::Numerous.new.respond_to?(:each).should == true
-  end
-  
-  it "provides each element to the block" do 
-    @b=[]
-    EnumerableSpecs::Numerous.new.each { |i| @b << i }
-    @b.should == [2, 5, 3, 6, 1, 4]
-  end 
-end

Deleted: MacRuby/trunk/spec/frozen/core/enumerable/find_index.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/enumerable/find_index.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/enumerable/find_index.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,54 +0,0 @@
-require File.dirname(__FILE__) + '/../../spec_helper'
-require File.dirname(__FILE__) + '/fixtures/classes'
-
-describe "Enumerable#find_index" do  
-  ruby_version_is "1.8.7" do
-    before :each do
-      @elements = [2, 4, 6, 8, 10]
-      @numerous = EnumerableSpecs::Numerous.new(*@elements)
-    end
-
-    it "passes each entry in enum to block while block when block is false" do
-      visited_elements = []
-      @numerous.find_index do |element|
-        visited_elements << element
-        false
-      end
-      visited_elements.should == @elements
-    end
-
-    it "returns nil when the block is false" do
-      @numerous.find_index {|e| false }.should == nil
-    end
-
-    it "returns the first index for which the block is not false" do
-      @elements.each_with_index do |element, index|
-        @numerous.find_index {|e| e > element - 1 }.should == index
-      end
-    end
-
-    it "returns the first index found" do
-      repeated = [10, 11, 11, 13, 11, 13, 10, 10, 13, 11]
-      numerous_repeat = EnumerableSpecs::Numerous.new(*repeated)
-      repeated.each do |element|
-        numerous_repeat.find_index(element).should == element - 10
-      end
-    end
-
-    it "returns nil when the element not found" do
-      @numerous.find_index(-1).should == nil
-    end
-
-    it "ignores the block if an argument is given" do
-      @numerous.find_index(-1) {|e| true }.should == nil
-    end
-    
-    ruby_version_is '1.8.7' do
-      it 'returns an Enumerator if no block given' do
-        @numerous.find_index.should be_kind_of(enumerator_class)
-      end
-    end
-
-  end
-
-end

Copied: MacRuby/trunk/spec/frozen/core/enumerable/find_index_spec.rb (from rev 2411, MacRuby/trunk/spec/frozen/core/enumerable/find_index.rb)
===================================================================
--- MacRuby/trunk/spec/frozen/core/enumerable/find_index_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/enumerable/find_index_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,54 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+describe "Enumerable#find_index" do  
+  ruby_version_is "1.8.7" do
+    before :each do
+      @elements = [2, 4, 6, 8, 10]
+      @numerous = EnumerableSpecs::Numerous.new(*@elements)
+    end
+
+    it "passes each entry in enum to block while block when block is false" do
+      visited_elements = []
+      @numerous.find_index do |element|
+        visited_elements << element
+        false
+      end
+      visited_elements.should == @elements
+    end
+
+    it "returns nil when the block is false" do
+      @numerous.find_index {|e| false }.should == nil
+    end
+
+    it "returns the first index for which the block is not false" do
+      @elements.each_with_index do |element, index|
+        @numerous.find_index {|e| e > element - 1 }.should == index
+      end
+    end
+
+    it "returns the first index found" do
+      repeated = [10, 11, 11, 13, 11, 13, 10, 10, 13, 11]
+      numerous_repeat = EnumerableSpecs::Numerous.new(*repeated)
+      repeated.each do |element|
+        numerous_repeat.find_index(element).should == element - 10
+      end
+    end
+
+    it "returns nil when the element not found" do
+      @numerous.find_index(-1).should == nil
+    end
+
+    it "ignores the block if an argument is given" do
+      @numerous.find_index(-1) {|e| true }.should == nil
+    end
+    
+    ruby_version_is '1.8.7' do
+      it 'returns an Enumerator if no block given' do
+        @numerous.find_index.should be_kind_of(enumerator_class)
+      end
+    end
+
+  end
+
+end

Added: MacRuby/trunk/spec/frozen/core/enumerable/none_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/enumerable/none_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/enumerable/none_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,42 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+ruby_version_is "1.8.7" do
+  describe "Enumerable#none?" do
+    it "returns true if none of the elements in self are true" do
+      e = EnumerableSpecs::Numerous.new(false, nil, false)
+      e.none?.should be_true
+    end
+
+    it "returns false if at least one of the elements in self are true" do
+      e = EnumerableSpecs::Numerous.new(false, nil, true, false)
+      e.none?.should be_false
+    end
+  end
+
+  describe "Enumerable#none? with a block" do
+    before(:each) do
+      @e = EnumerableSpecs::Numerous.new(1,1,2,3,4)
+    end
+
+    it "passes each element to the block in turn until it returns true" do
+      acc = []
+      @e.none? {|e| acc << e; false }
+      acc.should == [1,1,2,3,4]
+    end
+
+    it "stops passing elements to the block when it returns true" do
+      acc = []
+      @e.none? {|e| acc << e; e == 3 ? true : false }
+      acc.should == [1,1,2,3]
+    end
+
+    it "returns true if the block never returns true" do
+      @e.none? {|e| false }.should be_true
+    end
+
+    it "returns false if the block ever returns true" do
+      @e.none? {|e| e == 3 ? true : false }.should be_false
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/enumerable/one_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/enumerable/one_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/enumerable/one_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,5 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe "Enumerable#one?" do
+  it "needs to be reviewed for spec completeness"
+end

Modified: MacRuby/trunk/spec/frozen/core/enumerable/sort_by_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/enumerable/sort_by_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/enumerable/sort_by_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -14,4 +14,12 @@
     ar = [a, b].sort_by { |d| d.s }
     ar.should == [b, a]
   end
+
+  ruby_version_is "1.8.7" do
+    it "returns an Enumerator when a block is not supplied" do
+      a = EnumerableSpecs::Numerous.new("a","b")
+      a.sort_by.should be_an_instance_of(enumerator_class)
+      a.to_a.should == ["a", "b"]
+    end
+  end
 end

Added: MacRuby/trunk/spec/frozen/core/enumerator/each_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/enumerator/each_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/enumerator/each_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,7 @@
+require File.dirname(__FILE__) + '/../../shared/enumerator/each'
+
+ruby_version_is "1.9" do
+  describe "Enumerator#each" do
+    it_behaves_like(:enum_each, :each)
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/enumerator/each_with_index_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/enumerator/each_with_index_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/enumerator/each_with_index_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,15 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  require File.dirname(__FILE__) + '/../../shared/enumerator/with_index'
+
+  describe "Enumerator#each_with_index" do
+    it_behaves_like(:enum_with_index, :each_with_index)
+
+    it "raises an ArgumentError if passed extra arguments" do 
+      lambda do
+        [1].to_enum.each_with_index(:glark)
+      end.should raise_error(ArgumentError)
+    end    
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/enumerator/enum_for_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/enumerator/enum_for_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/enumerator/enum_for_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,9 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  require File.dirname(__FILE__) + '/../../shared/enumerator/enum_for'
+  
+  describe "#enum_for" do
+    it_behaves_like :enum_for, :enum_for
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/enumerator/new_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/enumerator/new_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/enumerator/new_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,24 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  require File.dirname(__FILE__) + '/../../shared/enumerator/new'
+
+  describe "Enumerator.new" do
+    it_behaves_like(:enum_new, :new)
+
+    it "accepts a block" do
+      enum = enumerator_class.new do |yielder|
+        yielder.yield 3
+        yielder.yield 2
+        yielder.yield 1
+      end
+      enum.should be_kind_of(enumerator_class)
+      enum.to_a.should == [3,2,1]
+    end
+
+    it "ignores block if arg given" do
+      enum = enumerator_class.new([1,2,3]){|y| y.yield 4}
+      enum.to_a.should == [1,2,3]
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/enumerator/next_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/enumerator/next_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/enumerator/next_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,9 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do  
+  require File.dirname(__FILE__) + '/../../shared/enumerator/next'
+  
+  describe "Enumerator#next" do
+    it_behaves_like(:enum_next,:next)
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/enumerator/peek_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/enumerator/peek_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/enumerator/peek_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,38 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do  
+  describe "Enumerator#peek" do
+    before(:each) do
+      @e = (1..5).to_a.to_enum
+    end
+
+    it "returns the next element in self" do
+      @e.peek.should == 1
+    end
+
+    it "does not advance the position of the current element" do
+      @e.next.should == 1
+      @e.peek.should == 2
+      @e.next.should == 2
+    end
+
+    it "can be called repeatedly without advancing the position of the current element" do
+      @e.peek
+      @e.peek
+      @e.peek.should == 1
+      @e.next.should == 1
+    end
+
+    it "works in concert with #rewind" do
+      @e.next
+      @e.next
+      @e.rewind
+      @e.peek.should == 1
+    end
+
+    it "raises StopIteration if called on a finished enumerator" do
+      5.times { @e.next }
+      lambda { @e.peek }.should raise_error(StopIteration)
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/enumerator/rewind_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/enumerator/rewind_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/enumerator/rewind_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,22 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do  
+  require File.dirname(__FILE__) + '/../../shared/enumerator/rewind'
+
+  describe "Enumerator#rewind" do
+    it_behaves_like(:enum_rewind, :rewind)
+
+    it "calls the enclosed object's rewind method if one exists" do
+      obj = mock('rewinder')
+      enum = enumerator_class.new(obj, :enum) 
+      obj.should_receive(:rewind)
+      enum.rewind
+    end
+
+    it "does nothing if the object doesn't have a #rewind method" do
+      obj = mock('rewinder')
+      enum = enumerator_class.new(obj) 
+      lambda { enum.rewind.should == enum }.should_not raise_error
+    end
+  end    
+end

Added: MacRuby/trunk/spec/frozen/core/enumerator/to_enum_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/enumerator/to_enum_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/enumerator/to_enum_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,9 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  require File.dirname(__FILE__) + '/../../shared/enumerator/enum_for'
+
+  describe "#to_enum" do
+    it_behaves_like :enum_for, :enum_for
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/enumerator/with_index_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/enumerator/with_index_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/enumerator/with_index_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,31 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  require File.dirname(__FILE__) + '/../../shared/enumerator/with_index'
+
+  describe "Enumerator#with_index" do
+    it_behaves_like(:enum_with_index, :with_index)
+
+    it "accepts an optional argument when given a block" do
+      lambda do
+        @enum.with_index(1) { |f| f}
+      end.should_not raise_error(ArgumentError)
+    end
+
+    it "accepts an optional argument when not given a block" do
+      lambda do
+        @enum.with_index(1)
+      end.should_not raise_error(ArgumentError)
+    end
+
+    it "numbers indices from the given index when given an offset but no block" do
+      @enum.with_index(1).to_a.should == [[1,1],[2,2],[3,3],[4,4]]
+    end
+
+    it "numbers indices from the given index when given an offset and block" do
+      acc = []
+      @enum.with_index(1) {|e,i| acc << [e,i] }
+      acc.should == [[1,1],[2,2],[3,3],[4,4]]
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/file/absolute_path_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/file/absolute_path_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/file/absolute_path_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,33 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "File.absolute_path" do
+    before(:each) do
+      @abs = File.expand_path(__FILE__)
+    end
+
+    it "returns the argument if it's an absolute pathname" do
+      File.absolute_path(@abs).should == @abs
+    end
+
+    it "resolves paths relative to the current working directory" do
+      Dir.chdir(File.dirname(@abs)) do |dir|
+        File.absolute_path(File.expand_path('./' + File.basename(__FILE__))).should == @abs
+      end
+    end
+
+    it "doesn't expand '~'" do
+      File.absolute_path('~').should_not == File.expand_path('~')
+    end 
+
+    it "accepts a second argument of a directory from which to resolve the path" do
+      File.absolute_path(__FILE__, File.dirname(__FILE__)).should == @abs
+    end
+
+    it "calls #to_path on its argument" do
+      obj = mock('path')
+      obj.should_receive(:to_path).and_return(@abs)
+      File.absolute_path(obj).should == @abs
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/file/stat/world_readable_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/file/stat/world_readable_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/file/stat/world_readable_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,9 @@
+require File.dirname(__FILE__) + '/../../../spec_helper'
+require File.dirname(__FILE__) + '/../../../shared/file/world_readable'
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+ruby_version_is "1.9" do
+  describe "File::Stat.world_readable?" do
+    it_behaves_like(:file_world_readable, :world_readable?, FileStat)
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/file/stat/world_writable_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/file/stat/world_writable_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/file/stat/world_writable_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,11 @@
+require File.dirname(__FILE__) + '/../../../spec_helper'
+require File.dirname(__FILE__) + '/../../../shared/file/world_writable'
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+ruby_version_is "1.9" do
+  describe "File::Stat.world_writable?" do
+    
+    it_behaves_like(:file_world_writable, :world_writable?, FileStat)
+
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/file/to_path_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/file/to_path_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/file/to_path_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,33 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "File#to_path" do
+    
+    it "returns a String" do
+      File.new(__FILE__).to_path.should be_an_instance_of(String)
+    end
+
+    it "doesn't normalise the path it returns" do
+      Dir.chdir(File.dirname(__FILE__)) do
+        unorm ='./' + File.basename(__FILE__)
+        File.new(unorm).to_path.should == unorm
+      end
+    end
+
+    it "doesn't expand the path it returns" do
+      File.new('../').to_path.should == '../'
+    end
+
+    it "doesn't absolute-ise the path it returns" do
+      Dir.chdir(File.dirname(__FILE__)) do
+        rel_path = File.basename(__FILE__)
+        File.new(rel_path).to_path.should == rel_path
+      end
+    end
+
+    it "preserves the encoding of the path" do
+      path = File.new(__FILE__.encode('euc-jp')).to_path
+      path.encoding.should == Encoding::EUC_JP
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/file/world_readable_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/file/world_readable_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/file/world_readable_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,14 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/../../shared/file/world_readable'
+
+ruby_version_is "1.9" do
+  describe "File.world_readable?" do
+    it_behaves_like(:file_world_readable, :world_readable?, File)
+
+    it "returns nil if the file does not exist" do
+      file = rand.to_s + $$.to_s
+      File.exists?(file).should be_false
+      File.world_readable?(file).should be_nil
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/file/world_writable_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/file/world_writable_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/file/world_writable_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,16 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/../../shared/file/world_writable'
+
+ruby_version_is "1.9" do
+  describe "File.world_writable?" do
+    
+    it_behaves_like(:file_world_writable, :world_writable?, File)
+
+    it "returns nil if the file does not exist" do
+      file = rand.to_s + $$.to_s
+      File.exists?(file).should be_false
+      File.world_writable?(file).should be_nil
+    end
+
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/float/rationalize_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/float/rationalize_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/float/rationalize_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,40 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "Float#rationalize" do
+    it "returns self as a simplified Rational with no argument" do
+      (3382729202.92822).rationalize.should == Rational(4806858197361, 1421)
+    end
+
+    # FIXME: These specs need reviewing by somebody familiar with the
+    # algorithm used by #rationalize
+    it "simplifies self to the degree specified by a Rational argument" do
+      f = 0.3
+      f.rationalize(Rational(1,10)).should == Rational(1,3)
+      f.rationalize(Rational(-1,10)).should == Rational(1,3)
+
+      f = -f
+      f.rationalize(Rational(1,10)).should == Rational(-1,3)
+      f.rationalize(Rational(-1,10)).should == Rational(-1,3)
+
+    end
+
+    it "simplifies self to the degree specified by a Float argument" do
+      f = 0.3
+      f.rationalize(0.05).should == Rational(1,3)
+      f.rationalize(0.001).should == Rational(3, 10)
+
+      f = -f
+      f.rationalize(0.05).should == Rational(-1,3)
+      f.rationalize(0.001).should == Rational(-3,10)
+    end
+
+    it "raises a FloatDomainError for Infinity" do
+      lambda {infinity_value.rationalize}.should raise_error(FloatDomainError)
+    end
+
+    it "raises a FloatDomainError for NaN" do
+      lambda { nan_value.rationalize }.should raise_error(FloatDomainError)
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/hash/assoc_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/hash/assoc_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/hash/assoc_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,43 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "Hash#assoc" do
+    before(:each) do
+      @h = {:apple => :green, :orange => :orange, :grape => :green, :banana => :yellow}
+    end
+
+    it "returns an Array if the argument is == to a key of the Hash" do
+      @h.assoc(:apple).should be_an_instance_of(Array)
+    end
+
+    it "returns a 2-element Array if the argument is == to a key of the Hash" do
+      @h.assoc(:grape).size.should == 2
+    end
+
+    it "sets the first element of the Array to the located key" do
+      @h.assoc(:banana).first.should == :banana
+    end
+
+    it "sets the last element of the Array to the value of the located key" do
+      @h.assoc(:banana).last.should == :yellow
+    end
+
+    it "only returns the first matching key-value pair for identity hashes" do
+      @h.compare_by_identity
+      @h['pear'] = :red
+      @h['pear'] = :green
+      @h.keys.grep(/pear/).size.should == 2
+      @h.assoc('pear').should == ['pear', :red]
+    end
+
+    it "uses #== to compare the argument to the keys" do
+      @h[1.0] = :value
+      1.should == 1.0
+      @h.assoc(1).should == [1.0, :value]
+    end
+
+    it "returns nil if the argument is not a key of the Hash" do
+      @h.assoc(:green).should be_nil
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/hash/compare_by_identity_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/hash/compare_by_identity_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/hash/compare_by_identity_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,109 @@
+ruby_version_is "1.9" do
+  describe "Hash#compare_by_identity" do
+    before(:each) do
+      @h = new_hash
+      @idh = new_hash.compare_by_identity
+    end
+
+    it "causes future comparisons on the receiver to be made by identity" do
+      @h["a"] = :a
+      @h["a"].should == :a
+      @h.compare_by_identity
+      @h["a"].should be_nil
+    end
+
+    it "causes #compare_by_identity? to return true" do
+      @idh.compare_by_identity?.should be_true
+    end
+
+    it "returns self" do
+      h = new_hash
+      h[:foo] = :bar
+      h.compare_by_identity.should == h
+    end
+    
+    it "uses the semantics of BasicObject#equal? to determine key identity" do
+      1.1.should_not equal(1.1)
+      @idh[1.1] = :a
+      @idh[1.1] = :b
+      [1].should_not equal([1])
+      @idh[[1]] = :c
+      @idh[[1]] = :d
+      :bar.should equal(:bar)
+      @idh[:bar] = :e
+      @idh[:bar] = :f
+      "bar".should_not equal('bar')
+      @idh["bar"] = :g
+      @idh["bar"] = :h
+      @idh.values.should == [:a, :b, :c, :d, :f, :g, :h]
+    end
+
+    it "doesn't call #equal? on keys to determine their identity" do
+      obj = mock('equal')
+      obj.should_not_receive(:equal?)
+      @idh[:foo] = :glark
+      @idh[obj] = :a
+      @idh[obj.dup].should == nil
+    end
+
+    it "regards #dup'd objects as having different identities" do
+      str = 'foo'
+      @idh[str.dup] = :str
+      @idh[str].should be_nil
+    end
+
+    it "regards #clone'd objects as having different identities" do
+      str = 'foo'
+      @idh[str.clone] = :str
+      @idh[str].should be_nil
+    end
+
+    it "regards references to the same object as having the same identity" do
+      o = Object.new
+      @h[o] = :o
+      @h[:a] = :a
+      @h[o].should == :o
+    end
+    
+    it "raises a RuntimeError on frozen hashes" do
+      @h = @h.freeze
+      lambda { @h.compare_by_identity }.should raise_error(RuntimeError)
+    end
+
+    # Behaviour confirmed in bug #1871
+    it "perists over #dups" do
+      @idh['foo'] = :bar
+      @idh['foo'] = :glark
+      @idh.dup.should == @idh
+      @idh.dup.size.should == @idh.size
+    end
+
+    it "persists over #clones" do
+      @idh['foo'] = :bar
+      @idh['foo'] = :glark
+      @idh.clone.should == @idh
+      @idh.clone.size.should == @idh.size
+    end
+  end
+
+  describe "Hash#compare_by_identity?" do
+    it "returns false by default" do
+      h = new_hash
+      h.compare_by_identity?.should be_false
+    end
+
+    it "returns true once #compare_by_identity has been invoked on self" do
+      h = new_hash
+      h.compare_by_identity
+      h.compare_by_identity?.should be_true
+    end
+
+    it "returns true when called multiple times on the same ident hash" do
+      h = new_hash
+      h.compare_by_identity
+      h.compare_by_identity?.should be_true
+      h.compare_by_identity?.should be_true
+      h.compare_by_identity?.should be_true
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/hash/flatten_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/hash/flatten_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/hash/flatten_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,64 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "Hash#flatten" do
+
+    before(:each) do
+      @h = {:plato => :greek,
+            :witgenstein => [:austrian, :british], 
+            :russell => :welsh}
+    end
+
+    it "returns an Array" do
+      new_hash.flatten.should be_an_instance_of(Array)
+    end
+
+    it "returns an empty Array for an empty Hash" do
+      new_hash.flatten.should == []
+    end
+
+    it "sets each even index of the Array to a key of the Hash" do
+      a = @h.flatten
+      a[0].should == :plato
+      a[2].should == :witgenstein
+      a[4].should == :russell
+    end
+
+    it "sets each odd index of the Array to the value corresponding to the previous element" do
+      a = @h.flatten
+      a[1].should == :greek
+      a[3].should == [:austrian, :british]
+      a[5].should == :welsh
+    end
+
+    it "does not recursively flatten Array values when called without arguments" do
+      a = @h.flatten
+      a[3].should == [:austrian, :british]
+    end
+
+    it "does not recursively flatten Hash values when called without arguments" do
+      @h[:russell] = {:born => :wales, :influenced_by => :mill }
+      a = @h.flatten
+      a[5].should_not == {:born => :wales, :influenced_by => :mill }.flatten
+    end
+
+    it "recursively flattens Array values when called with an argument >= 2" do
+      a = @h.flatten(2)
+      a[3].should == :austrian
+      a[4].should == :british
+    end
+
+    it "recursively flattens Array values to the given depth" do
+      @h[:russell] = [[:born, :wales], [:influenced_by, :mill]]
+      a = @h.flatten(2)
+      a[6].should == [:born, :wales]
+      a[7].should == [:influenced_by, :mill]
+    end
+
+    it "raises an TypeError if given a non-Integer argument" do
+      lambda do
+        @h.flatten(Object.new)
+      end.should raise_error(TypeError)
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/hash/rassoc_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/hash/rassoc_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/hash/rassoc_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,39 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "Hash#rassoc" do
+    before(:each) do
+      @h = {:apple => :green, :orange => :orange, :grape => :green, :banana => :yellow}
+    end
+
+    it "returns an Array if the argument is a value of the Hash" do
+      @h.rassoc(:green).should be_an_instance_of(Array)
+    end
+
+    it "returns a 2-element Array if the argument is a value of the Hash" do
+      @h.rassoc(:orange).size.should == 2
+    end
+
+    it "sets the first element of the Array to the key of the located value" do
+      @h.rassoc(:yellow).first.should == :banana
+    end
+
+    it "sets the last element of the Array to the located value" do
+      @h.rassoc(:yellow).last.should == :yellow
+    end
+
+    it "only returns the first matching key-value pair" do
+      @h.rassoc(:green).should == [:apple, :green]
+    end
+
+    it "uses #== to compare the argument to the values" do
+      @h[:key] = 1.0
+      1.should == 1.0
+      @h.rassoc(1).should == [:key, 1.0]
+    end
+
+    it "returns nil if the argument is not a value of the Hash" do
+      @h.rassoc(:banana).should be_nil
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/hash/try_convert_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/hash/try_convert_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/hash/try_convert_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,23 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  
+  describe "Hash.try_convert" do
+    
+    it "returns the argument if passed a Hash" do
+      h = {:foo => :glark}
+      Hash.try_convert(h).should == h
+    end
+
+    it "returns nil if the argument can't be coerced into a Hash" do
+      Hash.try_convert(Object.new).should be_nil
+    end
+
+    it "coerces the argument with #to_hash" do
+      obj = mock('hash')
+      obj.should_receive(:to_hash).and_return({:foo => :bar})
+      Hash.try_convert(obj).should == {:foo => :bar}
+    end
+
+  end
+end

Modified: MacRuby/trunk/spec/frozen/core/io/foreach_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/io/foreach_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/io/foreach_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -123,4 +123,11 @@
       lines.should == @content_with_r
     end
   end
+
+  ruby_version_is "1.8.7" do
+    it "returns an Enumerator when called without a block" do
+      IO.foreach(@file).should be_an_instance_of(enumerator_class)
+      IO.foreach(@file).to_a.should == @content
+    end
+  end
 end

Modified: MacRuby/trunk/spec/frozen/core/io/puts_spec_disabled.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/io/puts_spec_disabled.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/io/puts_spec_disabled.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -59,6 +59,12 @@
     @io.should_receive(:write).with("\n").exactly(3).times
     @io.puts([1, 2, [3]]).should == nil
   end
+
+  it "writes nothing for an empty array" do
+    x = []
+    @io.should_receive(:write).exactly(0).times
+    @io.puts(x).should == nil
+  end
   
   it "writes [...] for a recursive array arg" do
     x = []

Modified: MacRuby/trunk/spec/frozen/core/io/read_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/io/read_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/io/read_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -236,6 +236,21 @@
     lambda { IOSpecs.closed_file.read }.should raise_error(IOError)
   end
 
+  ruby_version_is "1.9" do
+    # Example derived from test/ruby/test_io_m17n.rb on MRI
+    it "strips the BOM when given 'rb:utf-7-bom' as the mode" do
+      text = "\uFEFFT"
+      %w/UTF-8 UTF-16BE UTF-16LE UTF-32BE UTF-32LE/.each do |name|
+        path = tmp('%s-bom.txt' % name)
+        content = text.encode(name)
+        File.open(path,'w') { |f| f.print content }
+        result = File.read(path, :mode => 'rb:utf-7-bom')
+        content[1].force_encoding("ascii-8bit").should == result.force_encoding("ascii-8bit")
+        File.unlink(path)
+      end
+    end
+  end
+
   it "ignores unicode encoding" do
     begin
       old = $KCODE

Deleted: MacRuby/trunk/spec/frozen/core/kernel/define_singleton_method.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/kernel/define_singleton_method.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/kernel/define_singleton_method.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,63 +0,0 @@
-require File.dirname(__FILE__) + '/../../spec_helper'
-require File.dirname(__FILE__) + '/fixtures/classes'
-
-ruby_version_is '1.9' do
-  describe "Kernel#define_singleton_method" do
-    describe "when given an UnboundMethod" do
-      class DefineSingletonMethodSpecClass
-        MY_CONST = 42
-        define_singleton_method(:another_test_method, self.method(:constants))
-      end
-
-      it "correctly calls the new method" do
-        klass = DefineSingletonMethodSpecClass
-        klass.another_test_method.should == klass.constants
-      end
-
-      it "adds the new method to the methods list" do
-        DefineSingletonMethodSpecClass.should have_method(:another_test_method)
-      end
-    end
-
-    it "defines a new method with the given name and the given block as body in self" do
-      class DefineSingletonMethodSpecClass
-        define_singleton_method(:block_test1) { self }
-        define_singleton_method(:block_test2, &lambda { self })
-      end
-    
-      o = DefineSingletonMethodSpecClass
-      o.block_test1.should == o
-      o.block_test2.should == o
-    end
-  
-    it "raises a TypeError when the given method is no Method/Proc" do
-      lambda {
-        Class.new { define_singleton_method(:test, "self") }
-      }.should raise_error(TypeError)
-    
-      lambda {
-        Class.new { define_singleton_method(:test, 1234) }
-      }.should raise_error(TypeError)
-    end
-  
-    it "defines a new singleton method for objects" do
-      s = "hello"
-      s.define_singleton_method(:test) { "world!" }
-      s.test.should == "world!"
-      lambda {
-        "hello".test
-      }.should raise_error(NoMethodError)
-    end
-
-    it "maintains the Proc's scope" do
-      class DefineMethodByProcClass
-        in_scope = true
-        method_proc = proc { in_scope }
-      
-        define_singleton_method(:proc_test, &method_proc)
-      end
-    
-      DefineMethodByProcClass.proc_test.should == true
-    end
-  end
-end
\ No newline at end of file

Copied: MacRuby/trunk/spec/frozen/core/kernel/define_singleton_method_spec.rb (from rev 2411, MacRuby/trunk/spec/frozen/core/kernel/define_singleton_method.rb)
===================================================================
--- MacRuby/trunk/spec/frozen/core/kernel/define_singleton_method_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/kernel/define_singleton_method_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,63 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+ruby_version_is '1.9' do
+  describe "Kernel#define_singleton_method" do
+    describe "when given an UnboundMethod" do
+      class DefineSingletonMethodSpecClass
+        MY_CONST = 42
+        define_singleton_method(:another_test_method, self.method(:constants))
+      end
+
+      it "correctly calls the new method" do
+        klass = DefineSingletonMethodSpecClass
+        klass.another_test_method.should == klass.constants
+      end
+
+      it "adds the new method to the methods list" do
+        DefineSingletonMethodSpecClass.should have_method(:another_test_method)
+      end
+    end
+
+    it "defines a new method with the given name and the given block as body in self" do
+      class DefineSingletonMethodSpecClass
+        define_singleton_method(:block_test1) { self }
+        define_singleton_method(:block_test2, &lambda { self })
+      end
+    
+      o = DefineSingletonMethodSpecClass
+      o.block_test1.should == o
+      o.block_test2.should == o
+    end
+  
+    it "raises a TypeError when the given method is no Method/Proc" do
+      lambda {
+        Class.new { define_singleton_method(:test, "self") }
+      }.should raise_error(TypeError)
+    
+      lambda {
+        Class.new { define_singleton_method(:test, 1234) }
+      }.should raise_error(TypeError)
+    end
+  
+    it "defines a new singleton method for objects" do
+      s = "hello"
+      s.define_singleton_method(:test) { "world!" }
+      s.test.should == "world!"
+      lambda {
+        "hello".test
+      }.should raise_error(NoMethodError)
+    end
+
+    it "maintains the Proc's scope" do
+      class DefineMethodByProcClass
+        in_scope = true
+        method_proc = proc { in_scope }
+      
+        define_singleton_method(:proc_test, &method_proc)
+      end
+    
+      DefineMethodByProcClass.proc_test.should == true
+    end
+  end
+end
\ No newline at end of file

Modified: MacRuby/trunk/spec/frozen/core/kernel/eval_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/kernel/eval_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/kernel/eval_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -241,11 +241,13 @@
     end
   end
 
-  it "can be aliased" do
-    alias aliased_eval eval
-    x = 2
-    aliased_eval('x += 40')
-    x.should == 42
+  deviates_on "jruby" do
+    it "can be aliased" do
+      alias aliased_eval eval
+      x = 2
+      aliased_eval('x += 40')
+      x.should == 42
+    end
   end
 end
 

Modified: MacRuby/trunk/spec/frozen/core/kernel/fixtures/classes.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/kernel/fixtures/classes.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/kernel/fixtures/classes.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -41,7 +41,8 @@
   end
 
   class A
-    def public_method; :public_method; end
+    # 1.9 as Kernel#public_method, so we don't want this one to clash:
+    def pub_method; :public_method; end
 
     def undefed_method; :undefed_method; end
     undef_method :undefed_method
@@ -214,6 +215,11 @@
   end
 
   class Child < Parent
+    # In case this trips anybody up: This fixtures file must only be loaded
+    # once for the Kernel specs. If it's loaded multiple times the following
+    # line raises a NameError. This is a problem if you require it from a
+    # location outside of core/kernel on 1.8.6, because 1.8.6 doesn't
+    # normalise paths...
     undef_method :parent_method
   end
 

Modified: MacRuby/trunk/spec/frozen/core/kernel/method_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/kernel/method_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/kernel/method_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,44 +1,23 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/shared/method'
 require File.dirname(__FILE__) + '/fixtures/classes'
 
 describe "Kernel#method" do
-  it "returns a method object for a valid method" do
-    class KernelSpecs::Foo; def bar; 'done'; end; end
-    KernelSpecs::Foo.new.method(:bar).class.should == Method
-  end
+  it_behaves_like(:kernel_method, :method)
 
-  it "returns a method object for a valid singleton method" do
-    class KernelSpecs::Foo; def self.bar; 'done'; end; end
-    KernelSpecs::Foo.method(:bar).class.should == Method
+  before(:each) do
+    @obj = KernelSpecs::A.new
   end
 
-  it "raises a NameError for an invalid method name" do
-    class KernelSpecs::Foo; def bar; 'done'; end; end
-    lambda {
-      KernelSpecs::Foo.new.method(:invalid_and_silly_method_name)
-    }.should raise_error(NameError)
+  # The following examples are to clarify the difference between #method and
+  # #public_method on 1.9
+  it "can be called on a private method" do
+    @obj.send(:private_method).should == :private_method
+    @obj.method(:private_method).should be_an_instance_of(Method)
   end
 
-  it "raises a NameError for an invalid singleton method name" do
-    class KernelSpecs::Foo; def self.bar; 'done'; end; end
-    lambda { KernelSpecs::Foo.method(:baz) }.should raise_error(NameError)
+  it "raises a NameError when called on a protected method" do
+    @obj.send(:protected_method).should == :protected_method
+    @obj.method(:protected_method).should be_an_instance_of(Method)
   end
-
-  # This may be a bug; see http://redmine.ruby-lang.org/issues/show/1151
-  ruby_version_is "" ... "1.9" do
-    it "changes the method called for super on a target aliased method" do
-      c1 = Class.new do
-        def a; 'a'; end
-        def b; 'b'; end
-      end
-      c2 = Class.new(c1) do
-        def a; super; end
-        alias b a
-      end
-
-      c2.new.a.should == 'a'
-      c2.new.b.should == 'a'
-      c2.new.method(:b).call.should == 'b'
-    end
-  end
 end

Added: MacRuby/trunk/spec/frozen/core/kernel/public_method_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/kernel/public_method_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/kernel/public_method_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,27 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/fixtures/classes'
+require File.dirname(__FILE__) + '/shared/method'
+
+ruby_version_is "1.9" do
+  describe "Kernel#public_method" do
+    it_behaves_like(:kernel_method, :public_method)
+
+    before(:each) do
+      @obj = KernelSpecs::A.new
+    end
+
+    it "raises a NameError when called on a private method" do
+      @obj.send(:private_method).should == :private_method
+      lambda do
+        @obj.public_method(:private_method)
+      end.should raise_error(NameError)
+    end
+
+    it "raises a NameError when called on a protected method" do
+      @obj.send(:protected_method).should == :protected_method
+      lambda do
+        @obj.public_method(:protected_method)
+       end.should raise_error(NameError)
+    end
+  end
+end

Modified: MacRuby/trunk/spec/frozen/core/kernel/respond_to_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/kernel/respond_to_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/kernel/respond_to_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -21,8 +21,8 @@
 
   it "returns true if obj responds to the given public method" do    
     @a.respond_to?("five").should == false
-    @a.respond_to?(:public_method).should == true
-    @a.respond_to?("public_method").should == true
+    @a.respond_to?(:pub_method).should == true
+    @a.respond_to?("pub_method").should == true
   end
   
   it "returns true if obj responds to the given protected method" do

Copied: MacRuby/trunk/spec/frozen/core/kernel/shared/method.rb (from rev 2411, MacRuby/trunk/spec/frozen/core/kernel/method_spec.rb)
===================================================================
--- MacRuby/trunk/spec/frozen/core/kernel/shared/method.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/kernel/shared/method.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,43 @@
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe :kernel_method, :shared => true do
+  it "returns a method object for a valid method" do
+    class KernelSpecs::Foo; def bar; 'done'; end; end
+    KernelSpecs::Foo.new.send(@method, :bar).class.should == Method
+  end
+
+  it "returns a method object for a valid singleton method" do
+    class KernelSpecs::Foo; def self.bar; 'done'; end; end
+    KernelSpecs::Foo.send(@method, :bar).class.should == Method
+  end
+
+  it "raises a NameError for an invalid method name" do
+    class KernelSpecs::Foo; def bar; 'done'; end; end
+    lambda {
+      KernelSpecs::Foo.new.send(@method, :invalid_and_silly_method_name)
+    }.should raise_error(NameError)
+  end
+
+  it "raises a NameError for an invalid singleton method name" do
+    class KernelSpecs::Foo; def self.bar; 'done'; end; end
+    lambda { KernelSpecs::Foo.send(@method, :baz) }.should raise_error(NameError)
+  end
+
+  # This may be a bug; see http://redmine.ruby-lang.org/issues/show/1151
+  ruby_version_is "" ... "1.9" do
+    it "changes the method called for super on a target aliased method" do
+      c1 = Class.new do
+        def a; 'a'; end
+        def b; 'b'; end
+      end
+      c2 = Class.new(c1) do
+        def a; super; end
+        alias b a
+      end
+
+      c2.new.a.should == 'a'
+      c2.new.b.should == 'a'
+      c2.new.send(@method, :b).call.should == 'b'
+    end
+  end
+end

Modified: MacRuby/trunk/spec/frozen/core/kernel/singleton_methods_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/kernel/singleton_methods_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/kernel/singleton_methods_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -12,6 +12,23 @@
       
       KernelSpecs::Methods.new.singleton_methods(false).should == []
     end
+
+    it "returns a list of names of singleton methods in object and superclasses when passed true" do |e|
+      x = Class.new {
+        def self.cls_inherited; end
+      }
+      y = Class.new(x)
+
+      m0 = x.singleton_methods(false)
+      m1 = y.singleton_methods(false)
+      m2 = x.singleton_methods(true)
+      m3 = y.singleton_methods(true)
+
+      m0.should include "cls_inherited"
+      m1.should_not include "cls_inherited"
+      m2.should include "cls_inherited"
+      m3.should include "cls_inherited"
+    end
     
     it "should handle singleton_methods call with and without argument" do
       [1, "string", :symbol, [], {} ].each do |e|
@@ -45,6 +62,23 @@
       KernelSpecs::Methods.new.singleton_methods(false).should == []
     end
     
+    it "returns a list of names of singleton methods in object and superclasses when passed true" do |e|
+      x = Class.new {
+        def self.cls_inherited; end
+      }
+      y = Class.new(x)
+
+      m0 = x.singleton_methods(false)
+      m1 = y.singleton_methods(false)
+      m2 = x.singleton_methods(true)
+      m3 = y.singleton_methods(true)
+
+      m0.should include :cls_inherited
+      m1.should_not include :cls_inherited
+      m2.should include :cls_inherited
+      m3.should include :cls_inherited
+    end
+    
     it "should handle singleton_methods call with and without argument" do
       [1, "string", :symbol, [], {} ].each do |e|
         lambda {e.singleton_methods}.should_not raise_error

Added: MacRuby/trunk/spec/frozen/core/kernel/spawn_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/kernel/spawn_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/kernel/spawn_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,90 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "Kernel.spawn" do
+    before(:each) do
+      @f = tmp("spawn-#{rand}-#{$$}")
+    end
+
+    after(:each) do
+      File.unlink(@f) if File.exists?(@f)
+    end
+
+    it "executes the given command" do
+      File.exists?(@f).should be_false
+      pid = spawn("ruby -e 'print :spawn' >#{@f}")
+      sleep 0.1
+      File.exists?(@f).should be_true
+      File.read(@f).should == "spawn"
+    end
+
+    it "executes the given command as a new process" do
+      pid = spawn("ruby -v >#{@f}")
+      pid.should_not == Process.pid
+    end
+
+    it "returns the process ID of the new process as a Fixnum" do
+      pid = spawn("ruby -v >#{@f}")
+      pid.should be_an_instance_of(Fixnum)
+    end
+
+    it "returns immediately" do
+      start = Time.now
+      pid = spawn('ruby -e "sleep 10"')
+      (Time.now - start).should < 1
+    end
+
+    it "sets the child's environment variables according to a supplied hash" do
+      pid = spawn({:spawn_of_ruby => 'yes'}, "ruby -e 'print ENV[:spawn_of_ruby]' >#{@f}")
+      sleep 0.1
+      File.exists?(@f).should be_true
+      File.read(@f).should == "yes"
+    end
+
+    it "joins the current process group by default" do
+      pid =  spawn("ruby -e 'print Process.getpgid(Process.pid)' >#{@f}")
+      sleep 0.1
+      File.exists?(@f).should be_true
+      pgid = File.read(@f).to_i
+      pgid.should == Process.getpgid(Process.pid)
+    end
+
+    it "joins a new process group if :pgroup => true" do
+      pid =  spawn("ruby -e 'print Process.getpgid(Process.pid)' >#{@f}", {:pgroup => true})
+      sleep 0.1
+      File.exists?(@f).should be_true
+      pgid = File.read(@f).to_i
+      pgid.should_not == Process.getpgid(Process.pid)
+    end
+
+    it "uses the current working directory as its working directory" do
+      pid =  spawn("ruby -e 'print Dir.pwd' >#{@f}")
+      sleep 0.1
+      File.exists?(@f).should be_true
+      File.read(@f).should == Dir.pwd
+    end
+
+    it "uses the given working directory if :chdir => dir is supplied" do
+      dir = File.expand_path('../')
+      dir.should_not == Dir.pwd
+      pid =  spawn("ruby -e 'print Dir.pwd' >#{@f}", {:chdir => dir})
+      sleep 0.1
+      File.exists?(@f).should be_true
+      File.read(@f).should == dir
+    end
+
+    it "redirects STDERR to the given file descriptior if if :err => Fixnum" do
+      fd = File.open(@f,'w').fileno
+      spawn("ruby -e 'print warn(:glark)'", {:err => fd})  
+      sleep 0.1
+      File.read(@f).should =~ /glark/
+    end
+
+    it "redirects STDERR to the given file if :err => String" do
+      spawn("ruby -e 'print warn(:glark)'", {:err => @f})  
+      sleep 0.1
+      File.read(@f).should =~ /glark/
+    end
+
+  end
+end

Modified: MacRuby/trunk/spec/frozen/core/matchdata/element_reference_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/matchdata/element_reference_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/matchdata/element_reference_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -16,3 +16,5 @@
     /(.)(.)(\d+)(\d)/.match("THX1138.")[1..3].should == %w|H X 113|
   end
 end
+
+language_version __FILE__, "element_reference"

Added: MacRuby/trunk/spec/frozen/core/matchdata/versions/element_reference_1.9.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/matchdata/versions/element_reference_1.9.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/matchdata/versions/element_reference_1.9.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,35 @@
+ruby_version_is "1.9" do
+  describe "MatchData#[Symbol]" do
+    it "returns the corresponding named match when given a Symbol" do
+      md = 'haystack'.match(/(?<t>t(?<a>ack))/)
+      md[:a].should == 'ack'
+      md[:t].should == 'tack'
+    end
+
+    it "returns the corresponding named match when given a String" do
+      md = 'haystack'.match(/(?<t>t(?<a>ack))/)
+      md['a'].should == 'ack'
+      md['t'].should == 'tack'
+    end
+
+    it "raises an IndexError if there is no named match corresponding to the Symbol" do
+      md = 'haystack'.match(/(?<t>t(?<a>ack))/)
+      lambda do
+        md[:hay]
+      end.should raise_error(IndexError)
+    end
+
+    it "raises an IndexError if there is no named match corresponding to the String" do
+      md = 'haystack'.match(/(?<t>t(?<a>ack))/)
+      lambda do
+        md['hay']
+      end.should raise_error(IndexError)
+    end
+
+    it "returns matches in the String's encoding" do
+      rex = /(?<t>t(?<a>ack))/u
+      md = 'haystack'.force_encoding('euc-jp').match(rex)
+      md[:t].encoding.should == Encoding::EUC_JP
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/method/eql_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/method/eql_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/method/eql_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,8 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/shared/eql'
+
+ruby_version_is "1.9" do
+  describe "Method#eql?" do
+    it_behaves_like(:method_equal, :eql?)
+  end
+end

Modified: MacRuby/trunk/spec/frozen/core/method/equal_value_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/method/equal_value_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/method/equal_value_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,43 +1,6 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
-require File.dirname(__FILE__) + '/fixtures/classes'
+require File.dirname(__FILE__) + '/shared/eql'
 
 describe "Method#==" do
-  before(:each) do
-    @m = MethodSpecs::Methods.new
-    @m2 = MethodSpecs::Methods.new
-    @a = MethodSpecs::A.new
-  end
-
-  it "returns true if methods are the same" do
-    m1 = @m.method(:foo)
-    m2 = @m.method(:foo)
-
-    (m1 == m1).should == true
-    (m1 == m2).should == true
-  end
-
-  it "returns true on aliased methods" do
-    m1 = @m.method(:foo)
-    m2 = @m.method(:bar)
-
-    (m1 == m2).should == true
-  end
-  
-  it "returns false on a method which is neither aliases nor the same method" do
-    m1 = @m.method(:foo)
-    m2 = @m.method(:zero)
-    
-    (m1 == m2).should == false
-  end
-  
-  it "returns false for a method which is not bound to the same object" do
-    m1 = @m.method(:foo)
-    m2 = @m2.method(:foo)
-
-    a = @a.method(:baz)
-    
-    (m1 == m2).should == false
-    (m1 == a).should == false
-    (m2 == a).should == false
-  end
+  it_behaves_like(:method_equal, :==)
 end

Modified: MacRuby/trunk/spec/frozen/core/method/fixtures/classes.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/method/fixtures/classes.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/method/fixtures/classes.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -86,4 +86,38 @@
   class D
     def bar() 'done' end
   end
+
+  class Eql
+
+    def same_body
+      1 + 1
+    end
+
+    alias :same_body_alias :same_body
+
+    def same_body_with_args(arg)
+      1 + 1
+    end
+
+    def different_body
+      1 + 2
+    end
+
+    def same_body_two 
+      1 + 1
+    end
+
+    private
+    def same_body_private
+      1 + 1
+    end
+  end
+
+  class Eql2
+
+    def same_body
+      1 + 1
+    end
+
+  end
 end

Added: MacRuby/trunk/spec/frozen/core/method/fixtures/classes_1.9.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/method/fixtures/classes_1.9.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/method/fixtures/classes_1.9.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,10 @@
+module MethodSpecs
+
+  class Methods
+    def one_splat_one_req(*a,b); end
+    def one_splat_two_req(*a,b,c); end
+    def one_splat_one_req_with_block(*a,b,&block); end
+
+    def one_opt_with_stabby(a=->(b){true}); end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/method/parameters_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/method/parameters_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/method/parameters_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,3 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+language_version __FILE__, "parameters"

Added: MacRuby/trunk/spec/frozen/core/method/shared/eql.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/method/shared/eql.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/method/shared/eql.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,77 @@
+require File.dirname(__FILE__) + '/../../../spec_helper'
+require File.dirname(__FILE__) + '/../fixtures/classes'
+
+describe :method_equal, :shared => true do
+  before(:each) do
+    @m = MethodSpecs::Methods.new
+    @m2 = MethodSpecs::Methods.new
+    @a = MethodSpecs::A.new
+  end
+
+  it "returns true if methods are the same" do
+    m1 = @m.method(:foo)
+    m2 = @m.method(:foo)
+
+    m1.send(@method, m1).should be_true
+    m1.send(@method, m2).should be_true
+  end
+
+  it "returns true on aliased methods" do
+    m1 = @m.method(:foo)
+    m2 = @m.method(:bar)
+
+    m1.send(@method, m2).should be_true
+  end
+  
+  ruby_version_is "1.9" do
+    it "returns true if the two methods are alises of each other in C" do
+      a = String.instance_method(:size)
+      b = String.instance_method(:length)
+      a.send(@method, b).should be_true
+    end
+  end
+
+  it "returns false on a method which is neither aliased nor the same method" do
+    m1 = @m.method(:foo)
+    m2 = @m.method(:zero)
+    
+    (m1 == m2).should be_false
+  end
+  
+  it "returns false for a method which is not bound to the same object" do
+    m1 = @m.method(:foo)
+    m2 = @m2.method(:foo)
+
+    a = @a.method(:baz)
+    
+    m1.send(@method, m2).should be_false
+    m1.send(@method, a).should be_false
+    m2.send(@method, a).should be_false
+  end
+
+  it "returns false if the two methods are bound to the same object but have different bodies" do
+    a = MethodSpecs::Eql.instance_method(:different_body)
+    b = MethodSpecs::Eql.instance_method(:same_body)
+    a.send(@method, b).should be_false
+  end
+
+  it "returns false if the two methods are bound to different objects, have different names, but identical bodies" do
+    a = MethodSpecs::Eql.instance_method(:same_body_two)
+    b = MethodSpecs::Eql2.instance_method(:same_body)
+    a.send(@method, b).should be_false
+  end
+
+  it "returns false if the two methods are bound to different objects, have the same names, and identical bodies" do
+    a = MethodSpecs::Eql.instance_method(:same_body)
+    b = MethodSpecs::Eql2.instance_method(:same_body)
+    a.send(@method, b).should be_false
+  end
+
+  it "returns false if the argument is not a Method object" do
+    String.instance_method(:size).send(@method, 7).should be_false
+  end
+
+  it "returns false if the argument is an unbound version of self" do
+    method(:load).send(@method, method(:load).unbind).should be_false
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/method/versions/parameters_1.9.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/method/versions/parameters_1.9.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/method/versions/parameters_1.9.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,153 @@
+require File.dirname(__FILE__) + '/../../../spec_helper'
+require File.dirname(__FILE__) + '/../fixtures/classes'
+require File.dirname(__FILE__) + '/../fixtures/classes_1.9'
+
+ruby_version_is "1.9" do
+  describe "Method#parameters" do
+
+    it "returns an empty Array when the method expects no arguments" do
+      MethodSpecs::Methods.instance_method(:zero).parameters.should == []
+    end
+
+    it "returns [[:req,:name]] for a method expecting one required argument called 'name'" do
+      MethodSpecs::Methods.instance_method(:one_req).parameters.should == [[:req,:a]]
+    end
+
+    it "returns [[:req,:a],[:req,:b]] for a method expecting two required arguments called 'a' and 'b''" do
+      m = MethodSpecs::Methods.instance_method(:two_req)
+      m.parameters.should == [[:req,:a], [:req,:b]]
+    end
+
+    it "returns [[:block,:a]] for a method expecting one block argument called 'a'" do
+      m = MethodSpecs::Methods.instance_method(:zero_with_block)
+      m.parameters.should == [[:block,:block]]
+    end
+
+    it "returns [[:req,:a],[:block,:b] for a method expecting a required argument ('a') and a block argument ('b')" do
+      m = MethodSpecs::Methods.instance_method(:one_req_with_block)
+      m.parameters.should == [[:req,:a], [:block,:block]]
+    end
+
+    it "returns [[:req,:a],[:req,:b],[:block,:c] for a method expecting two required arguments ('a','b') and a block argument ('c')" do
+      m = MethodSpecs::Methods.instance_method(:two_req_with_block)
+      m.parameters.should == [[:req,:a], [:req,:b], [:block,:block]]
+    end
+
+    it "returns [[:opt,:a]] for a method expecting one optional argument ('a')" do
+      m = MethodSpecs::Methods.instance_method(:one_opt)
+      m.parameters.should == [[:opt,:a]]
+    end
+
+    it "returns [[:req,:a],[:opt,:b]] for a method expecting one required argument ('a') and one optional argument ('b')" do
+      m = MethodSpecs::Methods.instance_method(:one_req_one_opt)
+      m.parameters.should == [[:req,:a],[:opt,:b]]
+    end
+
+    it "returns [[:req,:a],[:opt,:b]] for a method expecting one required argument ('a') and one optional argument ('b')" do
+      m = MethodSpecs::Methods.instance_method(:one_req_one_opt)
+      m.parameters.should == [[:req,:a],[:opt,:b]]
+    end
+
+    it "returns [[:req,:a],[:opt,:b],[:opt,:c]] for a method expecting one required argument ('a') and two optional arguments ('b','c')" do
+      m = MethodSpecs::Methods.instance_method(:one_req_two_opt)
+      m.parameters.should == [[:req,:a],[:opt,:b],[:opt,:c]]
+    end
+
+    it "returns [[:req,:a],[:req,:b],[:opt,:c]] for a method expecting two required arguments ('a','b') and one optional arguments ('c')" do
+      m = MethodSpecs::Methods.instance_method(:two_req_one_opt)
+      m.parameters.should == [[:req,:a],[:req,:b],[:opt,:c]]
+    end
+    
+    it "returns [[:opt,:a],[:block,:b]] for a method expecting one required argument ('a') and one block argument ('b')" do
+      m = MethodSpecs::Methods.instance_method(:one_opt_with_block)
+      m.parameters.should == [[:opt,:a],[:block,:block]]
+    end
+
+    it "returns [[:req,:a],[:opt,:b],[:block,:c]] for a method expecting one required argument ('a'), one optional argument ('b'), and a block ('c')" do
+      m = MethodSpecs::Methods.instance_method(:one_req_one_opt_with_block)
+      m.parameters.should == [[:req,:a],[:opt,:b],[:block,:block]]
+    end
+
+    it "returns [[:req,:a],[:opt,:b],[:opt,:c],[:block,:d]] for a method expecting one required argument ('a'), two optional arguments ('b','c'), and a block ('d')" do
+      m = MethodSpecs::Methods.instance_method(:one_req_two_opt_with_block)
+      m.parameters.should == [[:req,:a],[:opt,:b],[:opt,:c],[:block,:block]]
+    end
+
+    it "returns [[:rest,:a]] for a method expecting a single splat argument ('a')" do
+      m = MethodSpecs::Methods.instance_method(:zero_with_splat)
+      m.parameters.should == [[:rest,:a]]
+    end
+
+    it "returns [[:req,:a],[:rest,:b]] for a method expecting a splat argument ('a') and a required argument ('b')" do
+      m = MethodSpecs::Methods.instance_method(:one_req_with_splat)
+      m.parameters.should == [[:req,:a],[:rest,:b]]
+    end
+
+    it "returns [[:req,:a],[:req,:b],[:rest,:c]] for a method expecting two required arguments ('a','b') and a splat argument ('c')" do
+      m = MethodSpecs::Methods.instance_method(:two_req_with_splat)
+      m.parameters.should == [[:req,:a],[:req,:b],[:rest,:c]]
+    end
+
+    it "returns [[:req,:a],[:opt,:b],[:rest,:c]] for a method expecting a required argument ('a','b'), an optional argument ('b'), and a splat argument ('c')" do
+      m = MethodSpecs::Methods.instance_method(:one_req_one_opt_with_splat)
+      m.parameters.should == [[:req,:a],[:opt,:b],[:rest,:c]]
+    end
+
+    it "returns [[:req,:a],[:req,:b],[:opt,:b],[:rest,:d]] for a method expecting two required arguments ('a','b'), an optional argument ('c'), and a splat argument ('d')" do
+      m = MethodSpecs::Methods.instance_method(:two_req_one_opt_with_splat)
+      m.parameters.should == [[:req,:a],[:req,:b],[:opt,:c],[:rest,:d]]
+    end
+
+    it "returns [[:req,:a],[:opt,:b],[:opt,:c],[:rest,:d]] for a method expecting a required argument ('a'), two optional arguments ('b','c'), and a splat argument ('d')" do
+      m = MethodSpecs::Methods.instance_method(:one_req_two_opt_with_splat)
+      m.parameters.should == [[:req,:a],[:opt,:b],[:opt,:c],[:rest,:d]]
+    end
+
+    it "returns [[:rest,:a],[:block,:b]] for a method expecting a splat argument ('a') and a block argument ('b')" do
+      m = MethodSpecs::Methods.instance_method(:zero_with_splat_and_block)
+      m.parameters.should == [[:rest,:a],[:block,:block]]
+    end
+
+    it "returns [[:req,:a],[:rest,:b],[:block,:c]] for a method expecting a required argument ('a'), a splat argument ('b'), and a block ('c')" do
+      m = MethodSpecs::Methods.instance_method(:one_req_with_splat_and_block)
+      m.parameters.should == [[:req,:a],[:rest,:b],[:block,:block]]
+    end
+
+    it "returns [[:req,:a],[:req,:b],[:rest,:c],[:block,:d]] for a method expecting two required arguments ('a','b'), a splat argument ('c'), and a block ('d')" do
+      m = MethodSpecs::Methods.instance_method(:two_req_with_splat_and_block)
+      m.parameters.should == [[:req,:a],[:req,:b],[:rest,:c],[:block,:block]]
+    end
+    
+    it "returns [[:req,:a],[:opt,:b],[:rest,:c],[:block,:d]] for a method expecting a required argument ('a'), a splat argument ('c'), and a block ('d')" do
+      m = MethodSpecs::Methods.instance_method(:one_req_one_opt_with_splat_and_block)
+      m.parameters.should == [[:req,:a],[:opt,:b],[:rest,:c],[:block,:block]]
+    end
+
+    it "returns [[:req,:a],[:req,:b],[:opt,:c],[:block,:d]] for a method expecting two required arguments ('a','b'), an optional argument ('c'), a splat argument ('d'), and a block ('e')" do
+      m = MethodSpecs::Methods.instance_method(:two_req_one_opt_with_splat_and_block)
+      m.parameters.should == [[:req,:a],[:req,:b],[:opt,:c],[:rest,:d],[:block,:block]]
+    end
+
+    # 1.9 semantics
+    #
+    it "returns [[:rest,:a],[:req,:b]] for a method expecting a splat argument ('a') and a required argument ('b')" do
+      m = MethodSpecs::Methods.instance_method(:one_splat_one_req)
+      m.parameters.should == [[:rest,:a],[:req,:b]]
+    end
+    
+    it "returns [[:rest,:a],[:req,:b],[:req,:c]] for a method expecting a splat argument ('a') and two required arguments ('b','c')" do
+      m = MethodSpecs::Methods.instance_method(:one_splat_two_req)
+      m.parameters.should == [[:rest,:a],[:req,:b],[:req,:c]]
+    end
+
+    it "returns [[:rest,:a],[:req,:b],[:block,:c]] for a method expecting a splat argument ('a'), a required argument ('b'), and a block ('c')" do
+      m = MethodSpecs::Methods.instance_method(:one_splat_one_req_with_block)
+      m.parameters.should == [[:rest,:a],[:req,:b],[:block,:block]]
+    end
+
+    it "works with ->(){} as the value of an optional argument" do
+      m = MethodSpecs::Methods.instance_method(:one_opt_with_stabby)
+      m.parameters.should == [[:opt,:a]]
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/nil/rationalize_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/nil/rationalize_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/nil/rationalize_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,13 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "NilClass#rationalize" do
+    it "returns 0/1" do
+      nil.rationalize.should == Rational(0, 1)
+    end
+
+    it "ignores arguments" do
+      nil.rationalize(0.1).should == Rational(0, 1)
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/nil/to_r_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/nil/to_r_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/nil/to_r_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,9 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "NilClass#to_r" do
+    it "returns 0/1" do
+      nil.to_r.should == Rational(0, 1)
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/numeric/i_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/numeric/i_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/numeric/i_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,17 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "Numeric#i" do
+    it "returns a Complex object" do
+      34.i.should be_an_instance_of(Complex)
+    end
+
+    it "sets the real part to 0" do
+      7342.i.real.should == 0
+    end
+
+    it "sets the imaginary part to self" do
+      62.81.i.imag.should == 62.81
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/numeric/rationalize_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/numeric/rationalize_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/numeric/rationalize_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,32 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "Numeric#rationalize" do
+    before(:all) do
+      @numbers = [
+        0,
+        29871,
+        99999999999999**99,
+        -72628191273,
+      ]
+    end
+
+    it "returns a Rational object" do
+      @numbers.each do |number|
+        number.rationalize.should be_an_instance_of(Rational)
+      end
+    end
+
+    it "uses self as the numerator" do
+      @numbers.each do |number|
+        number.rationalize.numerator.should == number
+      end
+    end
+
+    it "uses 1 as the denominator" do
+      @numbers.each do |number|
+        number.rationalize.denominator.should == 1
+      end
+    end
+  end
+end

Modified: MacRuby/trunk/spec/frozen/core/random/int_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/random/int_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/random/int_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -83,13 +83,15 @@
       end.should raise_error(TypeError)
     end
 
-    # http://redmine.ruby-lang.org/issues/show/1859
-    quarantine! do
-      it "raises a TypeError if a Float..Integer range is given" do
-        lambda do
-          Random.new.int(20.2..40)
-        end.should raise_error(TypeError)
-      end
+    # (#int(3.3..5) previously segfaulted (bug #1859) which is why we test it
+    # here. Now, #int(3.3..5) is interpreted as #int(3...5), which has been
+    # reported as part of the same bug
+    it "converts each endpoint of the supplied Range to Integers" do
+      prng = Random.new(272726)
+      ints_a = 10.times.map { prng.int(3.3..5) }
+      prng = Random.new(272726)
+      ints_b = 10.times.map { prng.int(3..5) }
+      ints_a.should == ints_b
     end
 
     # The following examples fail. This has been reported as bug #1858

Added: MacRuby/trunk/spec/frozen/core/range/max_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/range/max_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/range/max_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,55 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.8.7" do
+  describe "Range#max" do
+    it "returns the maximum value in the range when called with no arguments" do
+      (1..10).max.should == 10
+      ('f'..'l').max.should == 'l'
+    end
+
+    ruby_version_is "1.9" do
+      it "returns the maximum value in the Float range when called with no arguments" do
+        (303.20..908.1111).max.should == 908.1111
+      end
+    end
+
+    it "returns nil when the endpoint is less than the start point" do
+      (100..10).max.should be_nil
+      ('z'..'l').max.should be_nil
+    end
+
+    ruby_version_is "1.9" do
+      it "returns nil when the endpoint is less than the start point in a Float range" do
+        (3003.20..908.1111).max.should be_nil
+      end
+    end
+  end
+
+  describe "Range#max given a block" do
+    it "passes each pair of values in the range to the block" do
+      acc = []
+      (1..10).max {|a,b| acc << [a,b]; a }
+      acc.flatten!
+      (1..10).each do |value|
+        acc.include?(value).should be_true
+      end
+    end
+
+    it "passes each pair of elements to the block in reversed order" do
+      acc = []
+      (1..5).max {|a,b| acc << [a,b]; a }
+      acc.should == [[2,1],[3,2], [4,3], [5, 4]]
+    end
+
+    it "calls #> and #< on the return value of the block" do
+      obj = mock('obj')
+      obj.should_receive(:>).exactly(2).times
+      obj.should_receive(:<).exactly(2).times
+      (1..3).max {|a,b| obj }
+    end
+
+    it "returns the element the block determines to be the maximum" do
+      (1..3).max {|a,b| -3 }.should == 1
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/range/min_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/range/min_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/range/min_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,55 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.8.7" do
+  describe "Range#min" do
+    it "returns the minimum value in the range when called with no arguments" do
+      (1..10).min.should == 1
+      ('f'..'l').min.should == 'f'
+    end
+
+    ruby_version_is "1.9" do
+      it "returns the minimum value in the Float range when called with no arguments" do
+        (303.20..908.1111).min.should == 303.20
+      end
+    end
+
+    it "returns nil when the start point is greater than the endpoint" do
+      (100..10).min.should be_nil
+      ('z'..'l').min.should be_nil
+    end
+
+    ruby_version_is "1.9" do
+      it "returns nil when the start point is greater than the endpoint in a Float range" do
+        (3003.20..908.1111).min.should be_nil
+      end
+    end
+  end
+
+  describe "Range#min given a block" do
+    it "passes each pair of values in the range to the block" do
+      acc = []
+      (1..10).min {|a,b| acc << [a,b]; a }
+      acc.flatten!
+      (1..10).each do |value|
+        acc.include?(value).should be_true
+      end
+    end
+
+    it "passes each pair of elements to the block where the first argument is the current element, and the last is the first element" do
+      acc = []
+      (1..5).min {|a,b| acc << [a,b]; a }
+      acc.should == [[2, 1], [3, 1], [4, 1], [5, 1]]
+    end
+
+    it "calls #> and #< on the return value of the block" do
+      obj = mock('obj')
+      obj.should_receive(:>).exactly(2).times
+      obj.should_receive(:<).exactly(2).times
+      (1..3).min {|a,b| obj }
+    end
+
+    it "returns the element the block determines to be the minimum" do
+      (1..3).min {|a,b| -3 }.should == 3
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/rational/integer_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/rational/integer_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/rational/integer_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,13 @@
+ruby_version_is "1.9" do
+  describe "Rational#integer?" do
+
+    it "returns false for a rational with a numerator and no denominator" do
+      Rational(20).integer?.should be_false
+    end 
+
+    it "returns false for a rational with a numerator and a denominator" do
+      Rational(20,3).integer?.should be_false
+    end 
+
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/rational/rationalize_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/rational/rationalize_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/rational/rationalize_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,33 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "Rational#rationalize" do
+    it "returns self with no argument" do
+      Rational(12,3).rationalize.should == Rational(12,3)
+      Rational(-45,7).rationalize.should == Rational(-45,7)
+    end
+
+    # FIXME: These specs need reviewing by somebody familiar with the
+    # algorithm used by #rationalize
+    it "simplifies self to the degree specified by a Rational argument" do
+      r = Rational(5404319552844595,18014398509481984)
+      r.rationalize(Rational(1,10)).should == Rational(1,3)
+      r.rationalize(Rational(-1,10)).should == Rational(1,3)
+
+      r = Rational(-5404319552844595,18014398509481984)
+      r.rationalize(Rational(1,10)).should == Rational(-1,3)
+      r.rationalize(Rational(-1,10)).should == Rational(-1,3)
+
+    end
+
+    it "simplifies self to the degree specified by a Float argument" do
+      r = Rational(5404319552844595,18014398509481984)
+      r.rationalize(0.05).should == Rational(1,3)
+      r.rationalize(0.001).should == Rational(3, 10)
+
+      r = Rational(-5404319552844595,18014398509481984)
+      r.rationalize(0.05).should == Rational(-1,3)
+      r.rationalize(0.001).should == Rational(-3,10)
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/rational/zero_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/rational/zero_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/rational/zero_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,15 @@
+ruby_version_is "1.9" do
+  describe "Rational#zero?" do
+    it "returns true if the numerator is 0" do
+      Rational(0,26).zero?.should be_true
+    end
+
+    it "returns true if the numerator is 0.0" do
+      Rational(0.0,26).zero?.should be_true
+    end
+
+    it "returns false if the numerator isn't 0" do
+      Rational(26).zero?.should be_false
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/regexp/encoding_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/regexp/encoding_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/regexp/encoding_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,56 @@
+# coding: utf-8
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "Regexp#encoding" do
+
+    it "returns an Encoding object" do
+      /glar/.encoding.should be_an_instance_of(Encoding)
+    end
+
+    it "defaults to US-ASCII if the Regexp contains only US-ASCII character" do
+      /ASCII/.encoding.should == Encoding::US_ASCII
+    end
+
+    it "returns US_ASCII if the 'n' modifier is supplied and only US-ASCII characters are present" do
+      /ASCII/n.encoding.should == Encoding::US_ASCII
+    end
+
+    it "returns ASCII-8BIT if the 'n' modifier is supplied and non-US-ASCII characters are present" do
+      /#{}\xc2\xa1/n.encoding.should == Encoding::ASCII_8BIT
+    end
+
+    it "defaults to UTF-8 if \\u escapes appear" do
+      /\u{9879}/.encoding.should == Encoding::UTF_8
+    end
+
+    it "defaults to UTF-8 if a literal UTF-8 character appears" do
+      /¥/.encoding.should == Encoding::UTF_8
+    end
+
+    it "returns UTF-8 if the 'u' modifier is supplied" do
+      /ASCII/u.encoding.should == Encoding::UTF_8
+    end
+
+    it "returns Windows-31J if the 's' modifier is supplied" do
+      /ASCII/s.encoding.should == Encoding::Windows_31J
+    end
+
+    it "returns EUC_JP if the 'e' modifier is supplied" do
+      /ASCII/e.encoding.should == Encoding::EUC_JP
+    end
+
+    it "upgrades the encoding to that of an embedded String" do
+      str = "文字化け".encode('euc-jp')
+      /#{str}/.encoding.should == Encoding::EUC_JP
+    end
+
+    it "ignores the default_internal encoding" do
+      old_internal = Encoding.default_internal
+      Encoding.default_internal = Encoding::EUC_JP
+      /foo/.encoding.should_not == Encoding::EUC_JP
+      Encoding.default_internal = old_internal
+    end
+
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/regexp/fixed_encoding_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/regexp/fixed_encoding_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/regexp/fixed_encoding_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,36 @@
+# coding: utf-8
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "Regexp#fixed_encoding?" do
+
+    it "returns false by default" do
+      /needle/.fixed_encoding?.should be_false
+    end
+
+    it "returns false if the 'n' modifier was supplied to the Regexp" do
+      /needle/n.fixed_encoding?.should be_false
+    end
+
+    it "returns true if the 'u' modifier was supplied to the Regexp" do
+      /needle/u.fixed_encoding?.should be_true
+    end
+
+    it "returns true if the 's' modifier was supplied to the Regexp" do
+      /needle/s.fixed_encoding?.should be_true
+    end
+
+    it "returns true if the 'e' modifier was supplied to the Regexp" do
+      /needle/e.fixed_encoding?.should be_true
+    end
+
+    it "returns true if the Regexp contains a \\u escape" do
+      /needle \u{8768}/.fixed_encoding?.should be_true
+    end
+
+    it "returns true if the Regexp contains a UTF-8 literal" do
+      /文字化け/.fixed_encoding?.should be_true
+    end
+
+  end
+end

Modified: MacRuby/trunk/spec/frozen/core/regexp/last_match_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/regexp/last_match_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/regexp/last_match_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,6 +1,6 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
 
-describe "Range.last_match" do
+describe "Regexp.last_match" do
   it "returns MatchData instance when not passed arguments" do
     /c(.)t/ =~ 'cat'
     

Added: MacRuby/trunk/spec/frozen/core/regexp/named_captures_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/regexp/named_captures_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/regexp/named_captures_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1 @@
+language_version __FILE__, "named_captures"

Added: MacRuby/trunk/spec/frozen/core/regexp/names_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/regexp/names_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/regexp/names_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1 @@
+language_version __FILE__, "names"

Modified: MacRuby/trunk/spec/frozen/core/regexp/quote_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/regexp/quote_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/regexp/quote_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,6 +1,6 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
 require File.dirname(__FILE__) + '/shared/quote'
 
-describe "Range.quote" do
+describe "Regexp.quote" do
   it_behaves_like(:regexp_quote, :quote)
 end

Added: MacRuby/trunk/spec/frozen/core/regexp/try_convert_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/regexp/try_convert_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/regexp/try_convert_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,21 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "Regexp.try_convert" do
+    it "returns the argument if given a Regexp" do
+      Regexp.try_convert(/foo/s).should == /foo/s
+    end
+
+    it "returns nil if given an argument that can't be converted to a Regexp" do
+      ['', 'glark', [], Object.new, :pat].each do |arg|
+        Regexp.try_convert(arg).should be_nil
+      end
+    end
+
+    it "tries to coerce the argument by calling #to_regexp" do
+      rex = mock('regexp')
+      rex.should_receive(:to_regexp).and_return(/(p(a)t[e]rn)/)
+      Regexp.try_convert(rex).should == /(p(a)t[e]rn)/
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/regexp/versions/named_captures_1.9.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/regexp/versions/named_captures_1.9.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/regexp/versions/named_captures_1.9.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,35 @@
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe "Regexp#named_captures" do
+  it "returns a Hash" do
+    /foo/.named_captures.should be_an_instance_of(Hash)
+  end
+
+  it "returns an empty Hash when there are no capture groups" do
+    /foo/.named_captures.should == {}
+  end
+
+  it "sets the keys of the Hash to the names of the capture groups" do
+    rex = /this (?<is>is) [aA] (?<pat>pate?rn)/
+    rex.named_captures.keys.should == ['is','pat']
+  end
+
+  it "sets the values of the Hash to Arrays" do
+    rex = /this (?<is>is) [aA] (?<pat>pate?rn)/
+    rex.named_captures.values.each do |value|
+      value.should be_an_instance_of(Array)
+    end
+  end
+
+  it "sets each element of the Array to the corresponding group's index" do
+    rex = /this (?<is>is) [aA] (?<pat>pate?rn)/
+    rex.named_captures['is'].should == [1]
+    rex.named_captures['pat'].should == [2]
+  end
+    
+  it "works with duplicate capture group names" do
+    rex = /this (?<is>is) [aA] (?<pat>pate?(?<is>rn))/
+    rex.named_captures['is'].should == [1,3]
+    rex.named_captures['pat'].should == [2]
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/regexp/versions/names_1.9.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/regexp/versions/names_1.9.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/regexp/versions/names_1.9.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,29 @@
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe "Regexp#names" do
+  it "returns an Array" do
+    /foo/.names.should be_an_instance_of(Array)
+  end
+
+  it "returns an empty Array if there are no named captures" do
+    /needle/.names.should == []
+  end
+
+  it "returns each named capture as a String" do
+    /n(?<cap>ee)d(?<ture>le)/.names.each do |name|
+      name.should be_an_instance_of(String)
+    end      
+  end
+
+  it "returns all of the named captures" do
+    /n(?<cap>ee)d(?<ture>le)/.names.should == ['cap', 'ture']
+  end
+
+  it "works with nested named captures" do
+    /n(?<cap>eed(?<ture>le))/.names.should == ['cap', 'ture']
+  end
+
+  it "returns each capture name only once" do
+    /n(?<cap>ee)d(?<cap>le)/.names.should == ['cap']
+  end
+end

Modified: MacRuby/trunk/spec/frozen/core/string/ascii_only_spec_disabled.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/string/ascii_only_spec_disabled.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/string/ascii_only_spec_disabled.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -66,9 +66,14 @@
       lambda { "Glark".ascii_only?('?') }.should raise_error(ArgumentError)
     end
     
-    it "returns true for the empty String" do
+    it "returns true for the empty String with an ASCII-compatiable encoding" do
       ''.ascii_only?.should be_true
       ''.encode('UTF-8').ascii_only?.should be_true
     end
+
+    it "returns false for the empty String with a non-ASCII-compatiable encoding" do
+      ''.force_encoding('UTF-16LE').ascii_only?.should be_false
+      ''.encode('UTF-16BE').ascii_only?.should be_false
+    end
   end
 end

Modified: MacRuby/trunk/spec/frozen/core/string/element_reference_spec_disabled.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/string/element_reference_spec_disabled.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/string/element_reference_spec_disabled.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -22,6 +22,12 @@
   it_behaves_like :string_slice_regexp_index, :[]
 end
 
+ruby_version_is "1.9" do
+  describe "String#[] with Regexp, group" do
+    it_behaves_like :string_slice_regexp_group, :[]
+  end
+end
+
 describe "String#[] with String" do
   it_behaves_like :string_slice_string, :[]
 end

Modified: MacRuby/trunk/spec/frozen/core/string/gsub_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/string/gsub_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/string/gsub_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -229,6 +229,100 @@
   end
 end
 
+ruby_version_is "1.9" do
+
+  describe "String#gsub with pattern and Hash" do
+  
+    it "returns a copy of self with all occurrences of pattern replaced with the value of the corresponding hash key" do
+      "hello".gsub(/./, 'l' => 'L').should == "LL"
+      "hello!".gsub(/(.)(.)/, 'he' => 'she ', 'll' => 'said').should == 'she said'
+      "hello".gsub('l', 'l' => 'el').should == 'heelelo'
+    end
+    
+    it "ignores keys that don't correspond to matches" do
+      "hello".gsub(/./, 'z' => 'L', 'h' => 'b', 'o' => 'ow').should == "bow"
+    end
+
+    it "returns an empty string if the pattern matches but the hash specifies no replacements" do
+      "hello".gsub(/./, 'z' => 'L').should == ""
+    end
+
+    it "ignores non-String keys" do
+      "hello".gsub(/(ll)/, 'll' => 'r', :ll => 'z').should == "hero"
+    end
+
+    it "uses a key's value as many times as needed" do
+      "food".gsub(/o/, 'o' => '0').should == "f00d"
+    end
+
+    it "uses the hash's default value for missing keys" do
+      hsh = new_hash
+      hsh.default='?'
+      hsh['o'] = '0'
+      "food".gsub(/./, hsh).should == "?00?"
+    end
+
+    it "coerces the hash values with #to_s" do
+      hsh = new_hash
+      hsh.default=[]
+      hsh['o'] = 0
+      obj = mock('!')
+      obj.should_receive(:to_s).and_return('!')
+      hsh['!'] = obj
+      "food!".gsub(/./, hsh).should == "[]00[]!"
+    end
+
+    it "raises a TypeError if the hash has a default proc" do
+      hsh = new_hash
+      hsh.default_proc = lambda { 'lamb' }
+      lambda do
+        "food!".gsub(/./, hsh)
+      end.should_not raise_error(TypeError)
+    end
+    
+    it "sets $~ to MatchData of last match and nil when there's none for access from outside" do
+      'hello.'.gsub('l', 'l' => 'L')
+      $~.begin(0).should == 3
+      $~[0].should == 'l'
+
+      'hello.'.gsub('not', 'ot' => 'to')
+      $~.should == nil
+
+      'hello.'.gsub(/.(.)/, 'o' => ' hole')
+      $~[0].should == 'o.'
+
+      'hello.'.gsub(/not/, 'z' => 'glark')
+      $~.should == nil
+    end
+
+    it "doesn't interpolate special sequences like \\1 for the block's return value" do
+      repl = '\& \0 \1 \` \\\' \+ \\\\ foo'
+      "hello".gsub(/(.+)/, 'hello' => repl ).should == repl
+    end
+    
+    it "untrusts the result if the original string is untrusted" do
+      str = "Ghana".untrust
+      str.gsub(/[Aa]na/, 'ana' => '').untrusted?.should be_true
+    end
+
+    it "untrusts the result if a hash value is untrusted" do
+      str = "Ghana"
+      str.gsub(/a$/, 'a' => 'di'.untrust).untrusted?.should be_true
+    end
+
+    it "taints the result if the original string is tainted" do
+      str = "Ghana".taint
+      str.gsub(/[Aa]na/, 'ana' => '').tainted?.should be_true
+    end
+
+    it "taints the result if a hash value is tainted" do
+      str = "Ghana"
+      str.gsub(/a$/, 'a' => 'di'.taint).tainted?.should be_true
+    end
+
+  end
+end
+
 describe "String#gsub with pattern and block" do
   it "returns a copy of self with all occurrences of pattern replaced with the block's return value" do
     "hello".gsub(/./) { |s| s.succ + ' ' }.should == "i f m m p "
@@ -263,7 +357,7 @@
         "x"
       end
 
-      $~.should == old_md
+      $~[0].should == old_md[0]
       $~.string.should == "hello"
     end
   end

Modified: MacRuby/trunk/spec/frozen/core/string/scan_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/string/scan_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/string/scan_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -134,7 +134,7 @@
         "x"
       end
 
-      $~.should == old_md
+      $~[0].should == old_md[0]
       $~.string.should == "hello"
     end
   end

Modified: MacRuby/trunk/spec/frozen/core/string/shared/slice.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/string/shared/slice.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/string/shared/slice.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -406,3 +406,5 @@
     r.class.should == StringSpecs::MyString
   end
 end
+
+language_version __FILE__, "slice"

Added: MacRuby/trunk/spec/frozen/core/string/shared/versions/slice_1.9.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/string/shared/versions/slice_1.9.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/string/shared/versions/slice_1.9.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,78 @@
+
+describe :string_slice_regexp_group, :shared => true do
+
+  it "returns the capture for the given name" do
+    "hello there".send(@method, /(?<g>[aeiou](.))/, 'g').should == "el"
+    "hello there".send(@method, /[aeiou](?<g>.)/, 'g').should == "l"
+
+    "har".send(@method, /(?<g>(.)(.)(.))/, 'g').should == "har"
+    "har".send(@method, /(?<h>.)(.)(.)/, 'h').should == "h"
+    "har".send(@method, /(.)(?<a>.)(.)/, 'a').should == "a"
+    "har".send(@method, /(.)(.)(?<r>.)/, 'r').should == "r"
+    "har".send(@method, /(?<h>.)(?<a>.)(?<r>.)/, 'r').should == "r"
+  end
+
+  it "returns the last capture for duplicate names" do
+    "hello there".send(@method, /(?<g>h)(?<g>.)/, 'g').should == "e"
+    "hello there".send(@method, /(?<g>h)(?<g>.)(?<f>.)/, 'g').should == "e"
+  end
+
+  it "returns the innermost capture for nested duplicate names" do
+    "hello there".send(@method, /(?<g>h(?<g>.))/, 'g').should == "e"
+  end
+
+  it "always taints resulting strings when self or regexp is tainted" do
+    strs = ["hello world"]
+    strs += strs.map { |s| s.dup.taint }
+
+    strs.each do |str|
+      str.send(@method, /(?<hi>hello)/, 'hi').tainted?.should == str.tainted?
+
+      str.send(@method, /(?<g>(.)(.)(.))/, 'g').tainted?.should == str.tainted?
+      str.send(@method, /(?<h>.)(.)(.)/, 'h').tainted?.should == str.tainted?
+      str.send(@method, /(.)(?<a>.)(.)/, 'a').tainted?.should == str.tainted?
+      str.send(@method, /(.)(.)(?<r>.)/, 'r').tainted?.should == str.tainted?
+      str.send(@method, /(?<h>.)(?<a>.)(?<r>.)/, 'r').tainted?.should == str.tainted?
+
+      tainted_re = /(?<a>.)(?<b>.)(?<c>.)/
+      tainted_re.taint
+
+      str.send(@method, tainted_re, 'a').tainted?.should be_true
+      str.send(@method, tainted_re, 'b').tainted?.should be_true
+      str.send(@method, tainted_re, 'c').tainted?.should be_true
+    end
+  end
+
+  it "returns nil if there is no match" do
+    "hello there".send(@method, /(?<whut>what?)/, 'whut').should be_nil
+  end
+
+  it "raises an IndexError if there is no capture for the given name" do
+    lambda do
+      "hello there".send(@method, /[aeiou](.)\1/, 'non')
+    end.should raise_error(IndexError)
+  end
+
+  it "raises a TypeError when the given name is not a String" do
+    lambda { "hello".send(@method, /(?<q>.)/, mock('x')) }.should raise_error(TypeError)
+    lambda { "hello".send(@method, /(?<q>.)/, {})        }.should raise_error(TypeError)
+    lambda { "hello".send(@method, /(?<q>.)/, [])        }.should raise_error(TypeError)
+  end
+
+  it "raises an IndexError when given the empty String as a group name" do
+    lambda { "hello".send(@method, /(?<q>)/, '') }.should raise_error(IndexError)
+  end
+
+  it "returns subclass instances" do
+    s = StringSpecs::MyString.new("hello")
+    s.send(@method, /(?<q>.)/, 'q').class.should == StringSpecs::MyString
+  end
+
+  it "sets $~ to MatchData when there is a match and nil when there's none" do
+    'hello'.send(@method, /(?<hi>.(.))/, 'hi')
+    $~[0].should == 'he'
+
+    'hello'.send(@method, /(?<non>not)/, 'non')
+    $~.should be_nil
+  end
+end

Modified: MacRuby/trunk/spec/frozen/core/string/slice_spec_disabled.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/string/slice_spec_disabled.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/string/slice_spec_disabled.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -22,6 +22,12 @@
   it_behaves_like :string_slice_regexp_index, :slice
 end
 
+ruby_version_is "1.9" do
+  describe "String#slice with Regexp, group" do
+    it_behaves_like :string_slice_regexp_group, :slice
+  end
+end
+
 describe "String#slice with String" do
   it_behaves_like :string_slice_string, :slice
 end

Added: MacRuby/trunk/spec/frozen/core/symbol/capitalize_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/symbol/capitalize_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/symbol/capitalize_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,44 @@
+# encoding: utf-8
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "Symbol#capitalize" do
+    it "returns a Symbol" do
+      :glark.capitalize.should be_an_instance_of(Symbol)
+    end
+
+    it "converts the first character to uppercase if it is ASCII" do
+      :lower.capitalize.should == :Lower
+    end
+
+    it "leaves the first character alone if it is not an alphabetical ASCII character" do
+      :"£1.20".capitalize.should == :"£1.20"
+      "\u{00DE}c".to_sym.capitalize.should == :"Þc"
+      "\u{00DF}C".to_sym.capitalize.should == :"ßc"
+    end
+
+    it "converts subsequent uppercase ASCII characters to their lowercase equivalents" do
+      :lOWER.capitalize.should == :Lower
+    end
+
+    it "leaves ASCII characters already in the correct case as they were" do
+      :Title.capitalize.should == :Title
+    end
+
+    it "works with both upper- and lowercase ASCII characters in the same Symbol" do
+      :mIxEd.capitalize.should == :Mixed
+    end
+
+    it "leaves uppercase Unicode characters as they were" do
+      "a\u{00DE}c".to_sym.capitalize.should == :"AÞc"
+    end
+
+    it "leaves lowercase Unicode characters as they were" do
+      "a\u{00DF}C".to_sym.capitalize.should == :"Aßc"
+    end
+
+    it "leaves non-alphabetic ASCII characters as they were" do
+      "Glark?!?".to_sym.capitalize.should == :"Glark?!?"
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/symbol/downcase_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/symbol/downcase_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/symbol/downcase_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,26 @@
+# encoding: utf-8
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "Symbol#downcase" do
+    it "returns a Symbol" do
+      :glark.downcase.should be_an_instance_of(Symbol)
+    end
+
+    it "converts uppercase ASCII characters to their lowercase equivalents" do
+      :lOwEr.downcase.should == :lower
+    end
+
+    it "leaves lowercase Unicode characters as they were" do
+      "\u{C0}Bc".to_sym.downcase.should == :"Àbc"
+    end
+
+    it "leaves uppercase Unicode characters as they were" do
+      "\u{DE}Bc".to_sym.downcase.should == :"Þbc"
+    end
+
+    it "leaves non-alphabetic ASCII characters as they were" do
+      "Glark?!?".to_sym.downcase.should == :"glark?!?"
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/symbol/empty_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/symbol/empty_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/symbol/empty_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,14 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "Symbol#empty?" do
+    it "returns true if self is empty" do
+      # 1.8.6 chokes on empty Symbol literals
+      "".to_sym.empty?.should be_true
+    end
+
+    it "returns false if self is non-empty" do
+      :"a".empty?.should be_false
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/symbol/swapcase_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/symbol/swapcase_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/symbol/swapcase_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,34 @@
+# encoding: utf-8
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "Symbol#swapcase" do
+    it "returns a Symbol" do
+      :glark.swapcase.should be_an_instance_of(Symbol)
+    end
+
+    it "converts lowercase ASCII characters to their uppercase equivalents" do
+      :lower.swapcase.should == :LOWER
+    end
+
+    it "converts uppercase ASCII characters to their lowercase equivalents" do
+      :UPPER.swapcase.should == :upper
+    end
+
+    it "works with both upper- and lowercase ASCII characters in the same Symbol" do
+      :mIxEd.swapcase.should == :MiXeD
+    end
+
+    it "leaves uppercase Unicode characters as they were" do
+      "\u{00DE}Bc".to_sym.swapcase.should == :"ÞbC"
+    end
+
+    it "leaves lowercase Unicode characters as they were" do
+      "\u{00DF}Bc".to_sym.swapcase.should == :"ßbC"
+    end
+
+    it "leaves non-alphabetic ASCII characters as they were" do
+      "Glark?!?".to_sym.swapcase.should == :"gLARK?!?"
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/core/symbol/upcase_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/symbol/upcase_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/core/symbol/upcase_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,22 @@
+# encoding: utf-8
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.9" do
+  describe "Symbol#upcase" do
+    it "returns a Symbol" do
+      :glark.upcase.should be_an_instance_of(Symbol)
+    end
+
+    it "converts lowercase ASCII characters to their uppercase equivalents" do
+      :lOwEr.upcase.should == :LOWER
+    end
+
+    it "leaves lowercase Unicode characters as they were" do
+      "\u{C0}Bc".to_sym.upcase.should == :"ÀBC"
+    end
+
+    it "leaves non-alphabetic ASCII characters as they were" do
+      "Glark?!?".to_sym.upcase.should == :"GLARK?!?"
+    end
+  end
+end

Modified: MacRuby/trunk/spec/frozen/core/time/at_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/core/time/at_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/core/time/at_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -5,14 +5,14 @@
   ruby_version_is ""..."1.9" do
     it "converts to time object" do
       # the #chomp calls are necessary because of RSpec
-      Time.at(1168475924).inspect.chomp.should == localtime_18(1168475924).chomp
+      Time.at(1184027924).inspect.chomp.should == localtime_18(1184027924).chomp
     end
   end
   
   ruby_version_is "1.9" do
     it "converts to time object" do
       # the #chomp calls are necessary because of RSpec
-      Time.at(1168475924).inspect.chomp.should == localtime_19(1168475924).chomp
+      Time.at(1184027924).inspect.chomp.should == localtime_19(1184027924).chomp
     end
   end
 

Copied: MacRuby/trunk/spec/frozen/fixtures/enumerator/classes.rb (from rev 2411, MacRuby/trunk/spec/frozen/library/enumerator/fixtures/classes.rb)
===================================================================
--- MacRuby/trunk/spec/frozen/fixtures/enumerator/classes.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/fixtures/enumerator/classes.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,15 @@
+module EnumSpecs
+  class Numerous
+
+    include Enumerable
+
+    def initialize(*list)
+      @list = list.empty? ? [2, 5, 3, 6, 1, 4] : list
+    end
+    
+    def each
+      @list.each { |i| yield i }
+    end 
+  end
+
+end

Modified: MacRuby/trunk/spec/frozen/language/not_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/not_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/language/not_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -10,8 +10,28 @@
     (not false).should be_true
     (not nil).should be_true
   end
+
+  it "accepts an argument" do
+    lambda do
+      not(true)
+    end.should_not raise_error(SyntaxError)
+  end
+
+  it "returns false if the argument is true" do
+    (not(true)).should be_false
+  end
+
+  it "returns true if the argument is false" do
+    (not(false)).should be_true
+  end
+
+  it "returns true if the argument is nil" do
+    (not(false)).should be_true
+  end
 end
 
+language_version __FILE__, "not"
+
 describe "The `!' keyword" do
   it "negates a `true' value" do
     (!true).should be_false
@@ -32,4 +52,4 @@
     (!!false).should be_false
     (!!nil).should be_false
   end
-end
\ No newline at end of file
+end

Modified: MacRuby/trunk/spec/frozen/language/predefined_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/predefined_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/language/predefined_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -327,10 +327,18 @@
     ($:.length > 0).should == true
   end
 
-  it "includes the current directory" do
-    $:.should include(".")
+  ruby_version_is ""..."1.9" do
+    it "includes the current directory" do
+      $:.should include(".")
+    end
   end
 
+  ruby_version_is "1.9" do
+    it "does not include the current directory" do
+      $:.should_not include(".")
+    end
+  end
+
   it "does not include '.' when the taint check level > 1" do
     begin
       orig_opts, ENV['RUBYOPT'] = ENV['RUBYOPT'], '-T'

Copied: MacRuby/trunk/spec/frozen/language/predefined_spec.rb.orig (from rev 2411, MacRuby/trunk/spec/frozen/language/predefined_spec.rb)
===================================================================
--- MacRuby/trunk/spec/frozen/language/predefined_spec.rb.orig	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/language/predefined_spec.rb.orig	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,505 @@
+require File.dirname(__FILE__) + '/../spec_helper'
+
+# MacRuby TODO: We need StringIO for one spec: Predefined global $_ is set to the last line read by e.g. StringIO#gets
+# require 'stringio'
+
+# The following tables are excerpted from Programming Ruby: The Pragmatic Programmer's Guide'
+# Second Edition by Dave Thomas, Chad Fowler, and Andy Hunt, page 319-22.
+# 
+# Entries marked [r/o] are read-only and an error will be raised of the program attempts to
+# modify them. Entries marked [thread] are thread local.
+
+=begin
+Exception Information 
+---------------------------------------------------------------------------------------------------
+
+$!               Exception       The exception object passed to raise. [thread] 
+$@               Array           The stack backtrace generated by the last exception. [thread] 
+=end
+
+=begin
+Pattern Matching Variables 
+---------------------------------------------------------------------------------------------------
+
+These variables (except $=) are set to nil after an unsuccessful pattern match.
+
+$&               String          The string matched (following a successful pattern match). This variable is 
+                                 local to the current scope. [r/o, thread] 
+$+               String          The contents of the highest-numbered group matched following a successful 
+                                 pattern match. Thus, in "cat" =~/(c|a)(t|z)/, $+ will be set to “t”. This 
+                                 variable is local to the current scope. [r/o, thread] 
+$`               String          The string preceding the match in a successful pattern match. This variable 
+                                 is local to the current scope. [r/o, thread] 
+$'               String          The string following the match in a successful pattern match. This variable 
+                                 is local to the current scope. [r/o, thread] 
+$=               Object          Deprecated.1.8 If set to any value apart from nil or false, all pattern matches 
+                                 will be case insensitive, string comparisons will ignore case, and string hash 
+                                 values will be case insensitive. 
+$1 to $9         String          The contents of successive groups matched in a successful pattern match. In 
+                                 "cat" =~/(c|a)(t|z)/, $1 will be set to “a” and $2 to “t”. This variable 
+                                 is local to the current scope. [r/o, thread] 
+$~               MatchData       An object that encapsulates the results of a successful pattern match. The 
+                                 variables $&, $`, $', and $1 to $9 are all derived from $~. Assigning to $~ 
+                                 changes the values of these derived variables. This variable is local to the 
+                                 current scope. [thread] 
+=end
+
+
+describe "Predefined global $~" do
+  it "is set to contain the MatchData object of the last match if successful" do
+    md = /foo/.match 'foo'
+    $~.class.should == MatchData
+    $~.object_id.should == md.object_id
+
+    /bar/ =~ 'bar'
+    $~.class.should == MatchData
+    $~.object_id.should_not == md.object_id
+  end   
+
+  it "is set to nil if the last match was unsuccessful" do
+    /foo/ =~ 'foo'
+    $~.nil?.should == false
+
+    /foo/ =~ 'bar'
+    $~.nil?.should == true
+  end
+
+  it "is set at the method-scoped level rather than block-scoped" do
+    obj = Object.new
+    def obj.foo; yield; end
+    def obj.foo2(&proc); proc.call; end
+
+    match = /foo/.match "foo"
+
+    obj.foo { match = /bar/.match("bar") }
+
+    $~.should == match
+
+    eval 'match = /baz/.match("baz")'
+
+    $~.should == match
+
+    obj.foo2 { match = /qux/.match("qux") }
+
+    $~.should == match
+  end
+
+  it "raises an error if assigned an object not nil or instanceof MatchData" do
+    lambda { $~ = nil }.should_not raise_error
+    lambda { $~ = /foo/.match("foo") }.should_not raise_error
+    lambda { $~ = Object.new }.should raise_error(TypeError)
+    lambda { $~ = 1 }.should raise_error(TypeError)
+  end
+end
+
+describe "Predefined global $&" do
+  it "is equivalent to MatchData#[0] on the last match $~" do
+    /foo/ =~ 'barfoobaz'
+    $&.should == $~[0]
+    $&.should == 'foo'
+  end
+end
+
+describe "Predefined global $`" do
+  it "is equivalent to MatchData#pre_match on the last match $~" do
+    /foo/ =~ 'barfoobaz'
+    $`.should == $~.pre_match
+    $`.should == 'bar'
+  end
+end
+
+describe "Predefined global $'" do
+  it "is equivalent to MatchData#post_match on the last match $~" do
+    /foo/ =~ 'barfoobaz'
+    $'.should == $~.post_match
+    $'.should == 'baz'
+  end
+end
+
+describe "Predefined global $+" do
+  it "is equivalent to $~.captures.last" do
+    /(f(o)o)/ =~ 'barfoobaz'
+    $+.should == $~.captures.last
+    $+.should == 'o'
+  end
+end
+
+describe "Predefined globals $1..N" do
+  it "are equivalent to $~[N]" do
+    /(f)(o)(o)/ =~ 'foo'
+    $1.should == $~[1]
+    $2.should == $~[2]
+    $3.should == $~[3]
+    $4.should == $~[4]
+
+    [$1, $2, $3, $4].should == ['f', 'o', 'o', nil]
+  end
+
+  it "are nil unless a match group occurs" do
+    def test(arg)
+      case arg
+      when /-(.)?/
+        $1
+      end
+    end
+    test("-").should == nil
+  end
+end
+
+describe "Predefined global $stdout" do
+  before(:each) do
+    @old_stdout = $stdout
+  end
+
+  after(:each) do
+    $stdout = @old_stdout
+  end
+
+  ruby_version_is "" ... "1.9" do
+    it "is the same as $defout" do
+      $stdout.should == $defout
+
+      $stdout = IOStub.new
+      $stdout.should == $defout
+    end
+  end
+
+  it "is the same as $DEFAULT_OUTPUT from 'English' library" do
+    require 'English'
+    $stdout.should == $DEFAULT_OUTPUT
+
+    $stdout = IOStub.new
+    $stdout.should == $DEFAULT_OUTPUT
+  end
+
+  it "raises TypeError error if assigned to nil" do
+    lambda { $stdout = nil }.should raise_error(TypeError)
+  end
+
+  it "raises TypeError error if assigned to object that doesn't respond to #write" do
+    obj = mock('object')
+    lambda { $stdout = obj }.should raise_error(TypeError)
+
+    obj.stub!(:write)
+    lambda { $stdout = obj }.should_not raise_error()
+  end
+end
+
+=begin
+Input/Output Variables 
+---------------------------------------------------------------------------------------------------
+
+$/               String          The input record separator (newline by default). This is the value that rou- 
+                                 tines such as Kernel#gets use to determine record boundaries. If set to 
+                                 nil, gets will read the entire file. 
+$-0              String          Synonym for $/. 
+$\               String          The string appended to the output of every call to methods such as 
+                                 Kernel#print and IO#write. The default value is nil. 
+$,               String          The separator string output between the parameters to methods such as 
+                                 Kernel#print and Array#join. Defaults to nil, which adds no text. 
+$.               Fixnum          The number of the last line read from the current input file. 
+$;               String          The default separator pattern used by String#split. May be set from the 
+                                 command line using the -F flag.
+$<               Object          An object that provides access to the concatenation of the contents of all 
+                                 the files given as command-line arguments or $stdin (in the case where 
+                                 there are no arguments). $< supports methods similar to a File object: 
+                                 binmode, close, closed?, each, each_byte, each_line, eof, eof?, 
+                                 file, filename, fileno, getc, gets, lineno, lineno=, path, pos, pos=, 
+                                 read, readchar, readline, readlines, rewind, seek, skip, tell, to_a, 
+                                 to_i, to_io, to_s, along with the methods in Enumerable. The method 
+                                 file returns a File object for the file currently being read. This may change 
+                                 as $< reads through the files on the command line. [r/o] 
+$>               IO              The destination of output for Kernel#print and Kernel#printf. The 
+                                 default value is $stdout. 
+$_               String          The last line read by Kernel#gets or Kernel#readline. Many string- 
+                                 related functions in the Kernel module operate on $_ by default. The vari- 
+                                 able is local to the current scope. [thread] 
+$-F              String          Synonym for $;. 
+$stderr          IO              The current standard error output. 
+$stdin           IO              The current standard input. 
+$stdout          IO              The current standard output. Assignment to $stdout is deprecated: use 
+                                 $stdout.reopen instead. 
+=end
+
+
+describe "Predefined global $_" do
+  it "is set to the last line read by e.g. StringIO#gets" do
+    stdin = StringIO.new("foo\nbar\n", "r")
+
+    read = stdin.gets
+    read.should == "foo\n"
+    $_.should == read
+
+    read = stdin.gets
+    read.should == "bar\n"
+    $_.should == read
+
+    read = stdin.gets
+    read.should == nil
+    $_.should == read
+  end
+
+  it "is set at the method-scoped level rather than block-scoped" do
+    obj = Object.new
+    def obj.foo; yield; end
+    def obj.foo2; yield; end
+
+    stdin = StringIO.new("foo\nbar\nbaz\nqux\n", "r")
+    match = stdin.gets
+
+    obj.foo { match = stdin.gets }
+
+    match.should == "bar\n"
+    $_.should == match
+
+    eval 'match = stdin.gets'
+
+    match.should == "baz\n"
+    $_.should == match
+
+    obj.foo2 { match = stdin.gets }
+
+    match.should == "qux\n"
+    $_.should == match
+  end
+
+  it "can be assigned any value" do
+    lambda { $_ = nil }.should_not raise_error
+    lambda { $_ = "foo" }.should_not raise_error
+    lambda { $_ = Object.new }.should_not raise_error
+    lambda { $_ = 1 }.should_not raise_error
+  end
+end
+
+=begin
+Execution Environment Variables 
+---------------------------------------------------------------------------------------------------
+
+$0               String          The name of the top-level Ruby program being executed. Typically this will 
+                                 be the program’s filename. On some operating systems, assigning to this 
+                                 variable will change the name of the process reported (for example) by the 
+                                 ps(1) command. 
+$*               Array           An array of strings containing the command-line options from the invoca- 
+                                 tion of the program. Options used by the Ruby interpreter will have been 
+                                 removed. [r/o] 
+$"               Array           An array containing the filenames of modules loaded by require. [r/o] 
+$$               Fixnum          The process number of the program being executed. [r/o] 
+$?               Process::Status The exit status of the last child process to terminate. [r/o, thread] 
+$:               Array           An array of strings, where each string specifies a directory to be searched for 
+                                 Ruby scripts and binary extensions used by the load and require methods. 
+                                 The initial value is the value of the arguments passed via the -I command- 
+                                 line option, followed by an installation-defined standard library location, fol- 
+                                 lowed by the current directory (“.”). This variable may be set from within a 
+                                 program to alter the default search path; typically, programs use $: << dir 
+                                 to append dir to the path. [r/o] 
+$-a              Object          True if the -a option is specified on the command line. [r/o]
+$-d              Object          Synonym for $DEBUG. 
+$DEBUG           Object          Set to true if the -d command-line option is specified. 
+__FILE__         String          The name of the current source file. [r/o] 
+$F               Array           The array that receives the split input line if the -a command-line option is 
+                                 used. 
+$FILENAME        String          The name of the current input file. Equivalent to $<.filename. [r/o] 
+$-i              String          If in-place edit mode is enabled (perhaps using the -i command-line 
+                                 option), $-i holds the extension used when creating the backup file. If you 
+                                 set a value into $-i, enables in-place edit mode.
+$-I              Array           Synonym for $:. [r/o] 
+$-K              String          Sets the multibyte coding system for strings and regular expressions. Equiv- 
+                                 alent to the -K command-line option.
+$-l              Object          Set to true if the -l option (which enables line-end processing) is present 
+                                 on the command line. [r/o] 
+__LINE__         String          The current line number in the source file. [r/o] 
+$LOAD_PATH       Array           A synonym for $:. [r/o] 
+$-p              Object          Set to true if the -p option (which puts an implicit while gets . . . end 
+                                 loop around your program) is present on the command line. [r/o] 
+$SAFE            Fixnum          The current safe level. This variable’s value may never be 
+                                 reduced by assignment. [thread] 
+$VERBOSE         Object          Set to true if the -v, --version, -W, or -w option is specified on the com- 
+                                 mand line. Set to false if no option, or -W1 is given. Set to nil if -W0 
+                                 was specified. Setting this option to true causes the interpreter and some 
+                                 library routines to report additional information. Setting to nil suppresses 
+                                 all warnings (including the output of Kernel.warn). 
+$-v              Object          Synonym for $VERBOSE. 
+$-w              Object          Synonym for $VERBOSE. 
+=end
+describe "Execution variable $:" do
+  it "is initialized to an array of strings" do
+    $:.is_a?(Array).should == true
+    ($:.length > 0).should == true
+  end
+
+  it "includes the current directory" do
+    $:.should include(".")
+  end
+
+  it "does not include '.' when the taint check level > 1" do
+    begin
+      orig_opts, ENV['RUBYOPT'] = ENV['RUBYOPT'], '-T'
+      `#{RUBY_EXE} -e 'p $:.include?(".")'`.should == "false\n"
+    ensure
+      ENV['RUBYOPT'] = orig_opts
+    end
+  end
+
+  it "is the same object as $LOAD_PATH and $-I" do
+    $:.__id__.should == $LOAD_PATH.__id__
+    $:.__id__.should == $-I.__id__
+  end
+  
+  it "can be changed via <<" do
+    $: << "foo"
+    $:.should include("foo")
+  end
+end
+=begin
+Standard Objects 
+---------------------------------------------------------------------------------------------------
+
+ARGF             Object          A synonym for $<. 
+ARGV             Array           A synonym for $*. 
+ENV              Object          A hash-like object containing the program’s environment variables. An 
+                                 instance of class Object, ENV implements the full set of Hash methods. Used 
+                                 to query and set the value of an environment variable, as in ENV["PATH"] 
+                                 and ENV["term"]="ansi". 
+false            FalseClass      Singleton instance of class FalseClass. [r/o] 
+nil              NilClass        The singleton instance of class NilClass. The value of uninitialized 
+                                 instance and global variables. [r/o]
+self             Object          The receiver (object) of the current method. [r/o] 
+true             TrueClass       Singleton instance of class TrueClass. [r/o] 
+=end
+
+describe "The predefined standard objects" do
+  it "includes ARGF" do
+    Object.const_defined?(:ARGF).should == true
+  end
+  
+  it "includes ARGV" do
+    Object.const_defined?(:ARGV).should == true
+  end
+  
+  it "includes a hash-like object ENV" do
+    Object.const_defined?(:ENV).should == true
+    ENV.respond_to?(:[]).should == true
+  end
+end
+
+describe "The predefined standard object nil" do
+  it "is an instance of NilClass" do
+    nil.class.should == NilClass
+  end
+  
+  # this needs to be tested with a subprocess because
+  # MRI aborts reading in the file
+  it "raises a SyntaxError if assigned to"
+end
+
+describe "The predefined standard object true" do
+  it "is an instance of TrueClass" do
+    true.class.should == TrueClass
+  end
+  
+  # this needs to be tested with a subprocess because
+  # MRI aborts reading in the file
+  it "raises a SyntaxError if assigned to"
+end
+
+describe "The predefined standard object false" do
+  it "is an instance of FalseClass" do
+    false.class.should == FalseClass
+  end
+  
+  # this needs to be tested with a subprocess because
+  # MRI aborts reading in the file
+  it "raises a SyntaxError if assigned to"
+end
+
+=begin
+Global Constants 
+---------------------------------------------------------------------------------------------------
+
+The following constants are defined by the Ruby interpreter. 
+
+DATA                 IO          If the main program file contains the directive __END__, then 
+                                 the constant DATA will be initialized so that reading from it will 
+                                 return lines following __END__ from the source file. 
+FALSE                FalseClass  Synonym for false. 
+NIL                  NilClass    Synonym for nil. 
+RUBY_PLATFORM        String      The identifier of the platform running this program. This string 
+                                 is in the same form as the platform identifier used by the GNU 
+                                 configure utility (which is not a coincidence). 
+PLATFORM             String      Same as RUBY_PLATFORM (only in 1.8).
+RUBY_RELEASE_DATE    String      The date of this release. 
+RUBY_VERSION         String      The version number of the interpreter. 
+STDERR               IO          The actual standard error stream for the program. The initial 
+                                 value of $stderr. 
+STDIN                IO          The actual standard input stream for the program. The initial 
+                                 value of $stdin. 
+STDOUT               IO          The actual standard output stream for the program. The initial 
+                                 value of $stdout. 
+SCRIPT_LINES__       Hash        If a constant SCRIPT_LINES__ is defined and references a Hash, 
+                                 Ruby will store an entry containing the contents of each file it 
+                                 parses, with the file’s name as the key and an array of strings as 
+                                 the value.
+TOPLEVEL_BINDING     Binding     A Binding object representing the binding at Ruby’s top level— 
+                                 the level where programs are initially executed. 
+TRUE                 TrueClass   Synonym for true. 
+=end
+
+describe "The predefined global constants" do
+  it "includes DATA when main script contains __END__" do
+    ruby_exe(fixture(__FILE__, "predefined.rb")).chomp.should == "true"
+  end
+
+  it "does not include DATA when main script contains no __END__" do
+    ruby_exe("puts Object.const_defined?(:DATA)").chomp.should == 'false'
+  end
+
+  it "includes TRUE" do
+    Object.const_defined?(:TRUE).should == true
+    TRUE.should equal(true)
+  end
+  
+  it "includes FALSE" do
+    Object.const_defined?(:FALSE).should == true
+    FALSE.should equal(false)
+  end
+  
+  it "includes NIL" do
+    Object.const_defined?(:NIL).should == true
+    NIL.should equal(nil)
+  end
+  
+  it "includes STDIN" do
+    Object.const_defined?(:STDIN).should == true
+  end
+  
+  it "includes STDOUT" do
+    Object.const_defined?(:STDOUT).should == true
+  end
+  
+  it "includes STDERR" do
+    Object.const_defined?(:STDERR).should == true
+  end
+
+  it "includes RUBY_VERSION" do
+    Object.const_defined?(:RUBY_VERSION).should == true
+  end
+  
+  it "includes RUBY_RELEASE_DATE" do
+    Object.const_defined?(:RUBY_RELEASE_DATE).should == true
+  end
+  
+  it "includes RUBY_PLATFORM" do
+    Object.const_defined?(:RUBY_PLATFORM).should == true
+  end
+
+  ruby_version_is "" ... "1.9" do
+    it "includes PLATFORM" do
+      Object.const_defined?(:PLATFORM).should == true
+      RUBY_PLATFORM == PLATFORM
+    end
+  end
+
+  it "includes TOPLEVEL_BINDING" do
+    Object.const_defined?(:TOPLEVEL_BINDING).should == true
+  end
+end

Added: MacRuby/trunk/spec/frozen/language/regexp/anchors_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/regexp/anchors_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/language/regexp/anchors_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,163 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.expand_path(File.dirname(__FILE__) + '/../fixtures/classes')
+
+describe "Regexps with anchors" do
+  it 'supports ^ (line start anchor)' do
+    # Basic matching
+    /^foo/.match("foo").to_a.should == ["foo"]
+    /^bar/.match("foo\nbar").to_a.should == ["bar"]
+    # Basic non-matching
+    /^foo/.match(" foo").should be_nil
+    /foo^/.match("foo\n\n\n").should be_nil
+    
+    # A bit advanced
+    /^^^foo/.match("foo").to_a.should == ["foo"]
+    (/^[^f]/ =~ "foo\n\n").should == "foo\n".size and $~.to_a.should == ["\n"]
+    (/($^)($^)/ =~ "foo\n\n").should == "foo\n".size and $~.to_a.should == ["", "", ""]
+
+    # Different start of line chars
+    /^bar/.match("foo\rbar").should be_nil
+    /^bar/.match("foo\0bar").should be_nil
+
+    # Trivial
+    /^/.match("foo").to_a.should == [""]
+
+    # Grouping
+    /(^foo)/.match("foo").to_a.should == ["foo", "foo"]
+    /(^)/.match("foo").to_a.should == ["", ""]
+    /(foo\n^)(^bar)/.match("foo\nbar").to_a.should == ["foo\nbar", "foo\n", "bar"]   
+  end
+  
+  it 'does not match ^ after trailing \n' do
+    /^(?!\A)/.match("foo\n").should be_nil # There is no (empty) line after a trailing \n
+  end
+
+  it 'supports $ (line end anchor)' do
+    # Basic  matching
+    /foo$/.match("foo").to_a.should == ["foo"]
+    /foo$/.match("foo\nbar").to_a.should == ["foo"]
+    # Basic non-matching
+    /foo$/.match("foo ").should be_nil
+    /$foo/.match("\n\n\nfoo").should be_nil
+
+    # A bit advanced
+    /foo$$$/.match("foo").to_a.should == ["foo"]
+    (/[^o]$/ =~ "foo\n\n").should == ("foo\n".size - 1) and $~.to_a.should == ["\n"]
+
+    # Different end of line chars
+    /foo$/.match("foo\r\nbar").should be_nil
+    /foo$/.match("foo\0bar").should be_nil
+
+    # Trivial
+    (/$/ =~ "foo").should == "foo".size and $~.to_a.should == [""]
+
+    # Grouping
+    /(foo$)/.match("foo").to_a.should == ["foo", "foo"]
+    (/($)/ =~ "foo").should == "foo".size and $~.to_a.should == ["", ""]
+    /(foo$)($\nbar)/.match("foo\nbar").to_a.should == ["foo\nbar", "foo", "\nbar"]
+  end
+
+  it 'supports \A (string start anchor)' do
+    # Basic matching
+    /\Afoo/.match("foo").to_a.should == ["foo"]
+    # Basic non-matching
+    /\Abar/.match("foo\nbar").should be_nil
+    /\Afoo/.match(" foo").should be_nil
+    
+    # A bit advanced
+    /\A\A\Afoo/.match("foo").to_a.should == ["foo"]
+    /(\A\Z)(\A\Z)/.match("").to_a.should == ["", "", ""]
+
+    # Different start of line chars
+    /\Abar/.match("foo\0bar").should be_nil
+
+    # Grouping
+    /(\Afoo)/.match("foo").to_a.should == ["foo", "foo"]
+    /(\A)/.match("foo").to_a.should == ["", ""]
+  end
+  
+  it 'supports \Z (string end anchor, including before trailing \n)' do
+    # Basic matching
+    /foo\Z/.match("foo").to_a.should == ["foo"]
+    /foo\Z/.match("foo\n").to_a.should == ["foo"]
+    # Basic non-matching
+    /foo\Z/.match("foo\nbar").should be_nil
+    /foo\Z/.match("foo ").should be_nil
+    
+    # A bit advanced
+    /foo\Z\Z\Z/.match("foo\n").to_a.should == ["foo"]
+    (/($\Z)($\Z)/ =~ "foo\n").should == "foo".size and $~.to_a.should == ["", "", ""]
+    (/(\z\Z)(\z\Z)/ =~ "foo\n").should == "foo\n".size and $~.to_a.should == ["", "", ""]
+
+    # Different end of line chars
+    /foo\Z/.match("foo\0bar").should be_nil
+    /foo\Z/.match("foo\r\n").should be_nil
+
+    # Grouping
+    /(foo\Z)/.match("foo").to_a.should == ["foo", "foo"]
+    (/(\Z)/ =~ "foo").should == "foo".size and $~.to_a.should == ["", ""]
+  end
+  
+  it 'supports \z (string end anchor)' do
+    # Basic matching
+    /foo\z/.match("foo").to_a.should == ["foo"]
+    # Basic non-matching
+    /foo\z/.match("foo\nbar").should be_nil
+    /foo\z/.match("foo\n").should be_nil
+    /foo\z/.match("foo ").should be_nil
+    
+    # A bit advanced
+    /foo\z\z\z/.match("foo").to_a.should == ["foo"]
+    (/($\z)($\z)/ =~ "foo").should == "foo".size and $~.to_a.should == ["", "", ""]
+
+    # Different end of line chars
+    /foo\z/.match("foo\0bar").should be_nil
+    /foo\z/.match("foo\r\nbar").should be_nil
+
+    # Grouping
+    /(foo\z)/.match("foo").to_a.should == ["foo", "foo"]
+    (/(\z)/ =~ "foo").should == "foo".size and $~.to_a.should == ["", ""]
+  end
+  
+  it 'supports \b (word boundary)' do
+    # Basic matching
+    /foo\b/.match("foo").to_a.should == ["foo"]
+    /foo\b/.match("foo\n").to_a.should == ["foo"]
+    LanguageSpecs.white_spaces.scan(/./).each do |c|
+    /foo\b/.match("foo" + c).to_a.should == ["foo"]
+    end
+    LanguageSpecs.non_alphanum_non_space.scan(/./).each do |c|
+    /foo\b/.match("foo" + c).to_a.should == ["foo"]
+    end
+    /foo\b/.match("foo\0").to_a.should == ["foo"]
+    # Basic non-matching
+    /foo\b/.match("foobar").should be_nil
+    /foo\b/.match("foo123").should be_nil
+    /foo\b/.match("foo_").should be_nil
+  end
+  
+  it 'supports \B (non-word-boundary)' do
+    # Basic matching
+    /foo\B/.match("foobar").to_a.should == ["foo"]
+    /foo\B/.match("foo123").to_a.should == ["foo"]
+    /foo\B/.match("foo_").to_a.should == ["foo"]
+    # Basic non-matching
+    /foo\B/.match("foo").should be_nil
+    /foo\B/.match("foo\n").should be_nil
+    LanguageSpecs.white_spaces.scan(/./).each do |c|
+    /foo\B/.match("foo" + c).should be_nil
+    end
+    LanguageSpecs.non_alphanum_non_space.scan(/./).each do |c|
+    /foo\B/.match("foo" + c).should be_nil
+    end
+    /foo\B/.match("foo\0").should be_nil
+  end
+
+  it 'supports (?= ) (positive lookahead)' do
+    /foo.(?=bar)/.match("foo1 foo2bar").to_a.should == ["foo2"]
+  end
+  
+  it 'supports (?! ) (negative lookahead)' do
+    /foo.(?!bar)/.match("foo1bar foo2").to_a.should == ["foo2"]
+  end
+end

Added: MacRuby/trunk/spec/frozen/language/regexp/back-references_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/regexp/back-references_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/language/regexp/back-references_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,50 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.expand_path(File.dirname(__FILE__) + '/../fixtures/classes')
+
+describe "Regexps with back-references" do
+  it 'saves match data in the $~ pseudo-global variable' do
+    "hello" =~ /l+/
+    $~.to_a.should == ["ll"]
+  end
+
+  it 'saves captures in numbered $[1-9] variables' do
+    "1234567890" =~ /(1)(2)(3)(4)(5)(6)(7)(8)(9)(0)/
+    $~.to_a.should == ["1234567890", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
+    $1.should == "1"
+    $2.should == "2"
+    $3.should == "3"
+    $4.should == "4"
+    $5.should == "5"
+    $6.should == "6"
+    $7.should == "7"
+    $8.should == "8"
+    $9.should == "9"
+  end
+
+  it 'will not clobber capture variables across threads' do
+    cap1, cap2, cap3 = nil
+    "foo" =~ /(o+)/
+    cap1 = [$~.to_a, $1]
+    Thread.new do
+      cap2 = [$~.to_a, $1]
+      "bar" =~ /(a)/
+      cap3 = [$~.to_a, $1]
+    end.join
+    cap4 = [$~.to_a, $1]
+    cap1.should == [["oo", "oo"], "oo"]
+    cap2.should == [[], nil]
+    cap3.should == [["a", "a"], "a"]
+    cap4.should == [["oo", "oo"], "oo"]
+  end
+
+  it 'supports \<n> (backreference to previous group match)' do
+    /(foo.)\1/.match("foo1foo1").to_a.should == ["foo1foo1", "foo1"]
+    /(foo.)\1/.match("foo1foo2").should be_nil
+  end
+  
+  not_compliant_on :ironruby do
+    it 'resets nested \<n> backreference before match of outer subexpression' do
+      /(a\1?){2}/.match("aaaa").to_a.should == ["aa", "a"]
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/language/regexp/character_classes_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/regexp/character_classes_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/language/regexp/character_classes_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,96 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.expand_path(File.dirname(__FILE__) + '/../fixtures/classes')
+
+describe "Regexp with character classes" do
+  it 'supports \w (word character)' do
+    /\w/.match("a").to_a.should == ["a"]
+    /\w/.match("1").to_a.should == ["1"]
+    /\w/.match("_").to_a.should == ["_"]
+    
+    # Non-matches
+    /\w/.match(LanguageSpecs.white_spaces).should be_nil
+    /\w/.match(LanguageSpecs.non_alphanum_non_space).should be_nil
+    /\w/.match("\0").should be_nil
+  end
+  
+  it 'supports \W (non-word character)' do
+    /\W+/.match(LanguageSpecs.white_spaces).to_a.should == [LanguageSpecs.white_spaces]
+    /\W+/.match(LanguageSpecs.non_alphanum_non_space).to_a.should == [LanguageSpecs.non_alphanum_non_space]
+    /\W/.match("\0").to_a.should == ["\0"]
+
+    # Non-matches
+    /\W/.match("a").should be_nil
+    /\W/.match("1").should be_nil
+    /\W/.match("_").should be_nil
+  end
+  
+  it 'supports \s (space character)' do
+    /\s+/.match(LanguageSpecs.white_spaces).to_a.should == [LanguageSpecs.white_spaces]
+    
+    # Non-matches
+    /\s/.match("a").should be_nil
+    /\s/.match("1").should be_nil
+    /\s/.match(LanguageSpecs.non_alphanum_non_space).should be_nil
+    /\s/.match("\0").should be_nil
+  end
+  
+  it 'supports \S (non-space character)' do    
+    /\S/.match("a").to_a.should == ["a"]
+    /\S/.match("1").to_a.should == ["1"]
+    /\S+/.match(LanguageSpecs.non_alphanum_non_space).to_a.should == [LanguageSpecs.non_alphanum_non_space]
+    /\S/.match("\0").to_a.should == ["\0"]
+
+    # Non-matches
+    /\S/.match(LanguageSpecs.white_spaces).should be_nil
+  end
+  
+  it 'supports \d (numeric digit)' do
+    /\d/.match("1").to_a.should == ["1"]
+    
+    # Non-matches
+    /\d/.match("a").should be_nil
+    /\d/.match(LanguageSpecs.white_spaces).should be_nil
+    /\d/.match(LanguageSpecs.non_alphanum_non_space).should be_nil
+    /\d/.match("\0").should be_nil
+  end
+  
+  it 'supports \D (non-digit)' do   
+    /\D/.match("a").to_a.should == ["a"]
+    /\D+/.match(LanguageSpecs.white_spaces).to_a.should == [LanguageSpecs.white_spaces]
+    /\D+/.match(LanguageSpecs.non_alphanum_non_space).to_a.should == [LanguageSpecs.non_alphanum_non_space]
+    /\D/.match("\0").to_a.should == ["\0"]
+
+    # Non-matches
+    /\D/.match("1").should be_nil
+  end
+
+  it 'supports [] (character class)' do
+    /[a-z]+/.match("fooBAR").to_a.should == ["foo"]
+    /[\b]/.match("\b").to_a.should == ["\b"] # \b inside character class is backspace
+  end
+  
+  it 'supports [[:alpha:][:digit:][:etc:]] (predefined character classes)' do
+    /[[:alnum:]]+/.match("a1").to_a.should == ["a1"]
+    /[[:alpha:]]+/.match("Aa1").to_a.should == ["Aa"]
+    /[[:blank:]]+/.match(LanguageSpecs.white_spaces).to_a.should == [LanguageSpecs.blanks]
+    # /[[:cntrl:]]/.match("").to_a.should == [""] # TODO: what should this match?
+    /[[:digit:]]/.match("1").to_a.should == ["1"]    
+    # /[[:graph:]]/.match("").to_a.should == [""] # TODO: what should this match?
+    /[[:lower:]]+/.match("Aa1").to_a.should == ["a"]
+    /[[:print:]]+/.match(LanguageSpecs.white_spaces).to_a.should == [" "]     # include all of multibyte encoded characters
+    /[[:punct:]]+/.match(LanguageSpecs.punctuations).to_a.should == [LanguageSpecs.punctuations]
+    /[[:space:]]+/.match(LanguageSpecs.white_spaces).to_a.should == [LanguageSpecs.white_spaces]
+    /[[:upper:]]+/.match("123ABCabc").to_a.should == ["ABC"]
+    /[[:xdigit:]]+/.match("xyz0123456789ABCDEFabcdefXYZ").to_a.should == ["0123456789ABCDEFabcdef"]
+    
+    # Parsing
+    /[[:lower:][:digit:]A-C]+/.match("a1ABCDEF").to_a.should == ["a1ABC"] # can be composed with other constructs in the character class
+    /[^[:lower:]A-C]+/.match("abcABCDEF123def").to_a.should == ["DEF123"] # negated character class
+    /[:alnum:]+/.match("a:l:n:u:m").to_a.should == ["a:l:n:u:m"] # should behave like regular character class composed of the individual letters
+    /[\[:alnum:]+/.match("[:a:l:n:u:m").to_a.should == ["[:a:l:n:u:m"] # should behave like regular character class composed of the individual letters
+    lambda { eval('/[[:alpha:]-[:digit:]]/') }.should raise_error(SyntaxError) # can't use character class as a start value of range
+  end
+
+  language_version __FILE__, "character_classes"
+end
+

Added: MacRuby/trunk/spec/frozen/language/regexp/encoding_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/regexp/encoding_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/language/regexp/encoding_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,57 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.expand_path(File.dirname(__FILE__) + '/../fixtures/classes')
+
+describe "Regexps with encoding modifiers" do
+
+  # Note: The encoding implied by a given modifier is specified in
+  # core/regexp/encoding_spec.rb for 1.9
+
+  ruby_version_is ""..."1.9" do
+    not_compliant_on :macruby do
+      it 'supports /e (EUC encoding)' do
+        match = /./e.match("\303\251")
+        match.to_a.should == ["\303\251"]
+      end
+      
+      it 'supports /n (Normal encoding)' do
+        /./n.match("\303\251").to_a.should == ["\303"]
+      end
+      
+      it 'supports /s (SJIS encoding)' do
+        /./s.match("\303\251").to_a.should == ["\303"]
+      end
+      
+      it 'supports /u (UTF8 encoding)' do
+        /./u.match("\303\251").to_a.should == ["\303\251"]
+      end
+      
+      it 'selects last of multiple encoding specifiers' do
+        /foo/ensuensuens.should == /foo/s
+      end
+    end
+  end
+
+  ruby_version_is "1.9" do
+    it 'supports /e (EUC encoding)' do
+      match = /./e.match("\303\251".force_encoding(Encoding::EUC_JP))
+      match.to_a.should == ["\303\251".force_encoding(Encoding::EUC_JP)]
+    end
+    
+    it 'supports /n (Normal encoding)' do
+      /./n.match("\303\251").to_a.should == ["\303"]
+    end
+    
+    it 'supports /s (Windows_31J encoding)' do
+      match = /./s.match("\303\251".force_encoding(Encoding::Windows_31J))
+      match.to_a.should == ["\303".force_encoding(Encoding::Windows_31J)]
+    end
+    
+    it 'supports /u (UTF8 encoding)' do
+      /./u.match("\303\251".force_encoding('utf-8')).to_a.should == ["\u{e9}"]
+    end
+    
+    it 'selects last of multiple encoding specifiers' do
+      /foo/ensuensuens.should == /foo/s
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/language/regexp/escapes_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/regexp/escapes_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/language/regexp/escapes_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,80 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.expand_path(File.dirname(__FILE__) + '/../fixtures/classes')
+
+describe "Regexps with escape characters" do
+  it "they're supported" do
+    /\t/.match("\t").to_a.should == ["\t"] # horizontal tab
+    /\v/.match("\v").to_a.should == ["\v"] # vertical tab
+    /\n/.match("\n").to_a.should == ["\n"] # newline
+    /\r/.match("\r").to_a.should == ["\r"] # return
+    /\f/.match("\f").to_a.should == ["\f"] # form feed
+    /\a/.match("\a").to_a.should == ["\a"] # bell
+    /\e/.match("\e").to_a.should == ["\e"] # escape
+
+    # \nnn         octal char            (encoded byte value)
+  end
+  
+  it "support quoting meta-characters via escape sequence" do
+    /\\/.match("\\").to_a.should == ["\\"]
+    /\//.match("/").to_a.should == ["/"]
+    # parenthesis, etc
+    /\(/.match("(").to_a.should == ["("]
+    /\)/.match(")").to_a.should == [")"]
+    /\[/.match("[").to_a.should == ["["]
+    /\]/.match("]").to_a.should == ["]"]
+    /\{/.match("{").to_a.should == ["{"]
+    /\}/.match("}").to_a.should == ["}"]
+    # alternation separator
+    /\|/.match("|").to_a.should == ["|"]
+    # quantifiers
+    /\?/.match("?").to_a.should == ["?"]
+    /\./.match(".").to_a.should == ["."]
+    /\*/.match("*").to_a.should == ["*"]
+    /\+/.match("+").to_a.should == ["+"]
+    # line anchors
+    /\^/.match("^").to_a.should == ["^"]
+    /\$/.match("$").to_a.should == ["$"]    
+  end
+  
+  it "allow any character to be escaped" do
+    /\y/.match("y").to_a.should == ["y"]  
+  end
+  
+  it "support \\x (hex characters)" do
+    /\xA/.match("\nxyz").to_a.should == ["\n"]
+    /\x0A/.match("\n").to_a.should == ["\n"]
+    /\xAA/.match("\nA").should be_nil
+    /\x0AA/.match("\nA").to_a.should == ["\nA"]
+    /\xAG/.match("\nG").to_a.should == ["\nG"]
+    # Non-matches
+    lambda { eval('/\xG/') }.should raise_error(SyntaxError)
+    
+    # \x{7HHHHHHH} wide hexadecimal char (character code point value)
+  end
+  
+  it "support \\c (control characters)" do
+    #/\c \c@\c`/.match("\00\00\00").to_a.should == ["\00\00\00"]
+    /\c#\cc\cC/.match("\03\03\03").to_a.should == ["\03\03\03"]
+    /\c'\cG\cg/.match("\a\a\a").to_a.should == ["\a\a\a"]
+    /\c(\cH\ch/.match("\b\b\b").to_a.should == ["\b\b\b"]
+    /\c)\cI\ci/.match("\t\t\t").to_a.should == ["\t\t\t"]
+    /\c*\cJ\cj/.match("\n\n\n").to_a.should == ["\n\n\n"]
+    /\c+\cK\ck/.match("\v\v\v").to_a.should == ["\v\v\v"]
+    /\c,\cL\cl/.match("\f\f\f").to_a.should == ["\f\f\f"]
+    /\c-\cM\cm/.match("\r\r\r").to_a.should == ["\r\r\r"]
+    
+    /\cJ/.match("\r").should be_nil
+
+    # Parsing precedence
+    /\cJ+/.match("\n\n").to_a.should == ["\n\n"] # Quantifers apply to entire escape sequence
+    /\\cJ/.match("\\cJ").to_a.should == ["\\cJ"]
+    lambda { eval('/[abc\x]/') }.should raise_error(SyntaxError) # \x is treated as a escape sequence even inside a character class
+    # Syntax error
+    lambda { eval('/\c/') }.should raise_error(SyntaxError)
+
+    # \cx          control char          (character code point value)
+    # \C-x         control char          (character code point value)
+    # \M-x         meta  (x|0x80)        (character code point value)
+    # \M-\C-x      meta control char     (character code point value)
+  end
+end

Added: MacRuby/trunk/spec/frozen/language/regexp/grouping_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/regexp/grouping_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/language/regexp/grouping_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,23 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.expand_path(File.dirname(__FILE__) + '/../fixtures/classes')
+
+describe "Regexps with grouping" do
+  it 'support ()' do
+    /(a)/.match("a").to_a.should == ["a", "a"]
+  end
+
+  it "allow groups to be nested" do
+    md = /(hay(st)a)ck/.match('haystack')
+    md.to_a.should == ['haystack','haysta', 'st']
+  end
+
+  it "raise a SyntaxError when parentheses aren't balanced" do
+   lambda { eval "/(hay(st)ack/" }.should raise_error(SyntaxError)
+  end
+
+  it 'supports (?: ) (non-capturing group)' do
+    /(?:foo)(bar)/.match("foobar").to_a.should == ["foobar", "bar"]
+    # Parsing precedence
+    /(?:xdigit:)/.match("xdigit:").to_a.should == ["xdigit:"]
+  end
+end

Added: MacRuby/trunk/spec/frozen/language/regexp/interpolation_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/regexp/interpolation_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/language/regexp/interpolation_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,55 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.expand_path(File.dirname(__FILE__) + '/../fixtures/classes')
+
+describe "Regexps with interpolation" do
+
+  it "allow interpolation of strings" do
+    str = "foo|bar"
+    /#{str}/.should == /foo|bar/
+  end
+
+  it "allows interpolation of literal regexps" do
+    re = /foo|bar/
+    /#{re}/.should == /(?-mix:foo|bar)/
+  end
+  
+  it "allows interpolation of any class that responds to to_s" do
+    o = LanguageSpecs::ClassWith_to_s.new
+    /#{o}/.should == /class_with_to_s/
+  end
+  
+  it "throws NoMethodError on missing to_s" do
+    o = LanguageSpecs::ClassWithout_to_s.new
+    lambda { /#{o}/ }.should raise_error(NoMethodError)
+  end
+  
+  it "allows interpolation which mixes modifiers" do
+    re = /foo/i
+    /#{re} bar/m.should == /(?i-mx:foo) bar/m
+  end
+  
+  it "allows interpolation to interact with other Regexp constructs" do
+    str = "foo)|(bar"
+    /(#{str})/.should == /(foo)|(bar)/
+    
+    str = "a"
+    /[#{str}-z]/.should == /[a-z]/
+  end
+  
+  it "gives precedence to escape sequences over substitution" do
+    str = "J"
+    /\c#{str}/.to_s.should == '(?-mix:\c#' + '{str})'
+  end  
+
+  it "throws RegexpError for malformed interpolation" do
+    s = ""
+    lambda { /(#{s}/ }.should raise_error(RegexpError)
+    s = "("
+    lambda { /#{s}/ }.should raise_error(RegexpError)
+  end
+
+  it "allows interpolation in extended mode" do
+    var = "#comment\n  foo  #comment\n  |  bar"
+    (/#{var}/x =~ "foo").should == (/foo|bar/ =~ "foo")
+  end
+end

Added: MacRuby/trunk/spec/frozen/language/regexp/modifiers_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/regexp/modifiers_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/language/regexp/modifiers_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,129 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.expand_path(File.dirname(__FILE__) + '/../fixtures/classes')
+
+describe "Regexps with modifers" do
+  it 'supports /i (case-insensitive)' do
+    /foo/i.match("FOO").to_a.should == ["FOO"]
+  end
+  
+  it 'supports /m (multiline)' do
+    /foo.bar/m.match("foo\nbar").to_a.should == ["foo\nbar"]
+    /foo.bar/.match("foo\nbar").should be_nil
+  end
+  
+  it 'supports /x (extended syntax)' do
+    /\d +/x.match("abc123").to_a.should == ["123"] # Quantifiers can be separated from the expression they apply to
+  end
+  
+  it 'supports /o (once)' do
+    2.times do |i|
+      /#{i}/o.should == /0/
+    end
+  end
+  
+  it 'invokes substitutions for /o only once' do
+    ScratchPad.record []
+    to_s_callback = Proc.new do
+      ScratchPad << :to_s_callback
+      "class_with_to_s"
+    end
+    o = LanguageSpecs::ClassWith_to_s.new(to_s_callback)
+    2.times { /#{o}/o }
+    ScratchPad.recorded.should == [:to_s_callback]
+  end
+ 
+  ruby_version_is "" ... "1.9" do 
+    it 'does not do thread synchronization for /o' do
+      ScratchPad.record []
+      
+      to_s_callback2 = Proc.new do
+        ScratchPad << :to_s_callback2
+        "class_with_to_s2"
+      end
+  
+      to_s_callback1 = Proc.new do
+        ScratchPad << :to_s_callback1
+        t2 = Thread.new do
+          o2 = LanguageSpecs::ClassWith_to_s.new(to_s_callback2)
+          ScratchPad << LanguageSpecs.get_regexp_with_substitution(o2)
+        end
+        t2.join
+        "class_with_to_s1"
+      end
+      
+      o1 = LanguageSpecs::ClassWith_to_s.new(to_s_callback1)
+      ScratchPad << LanguageSpecs.get_regexp_with_substitution(o1)
+  
+      ScratchPad.recorded.should == [:to_s_callback1, :to_s_callback2, /class_with_to_s2/, /class_with_to_s2/]
+    end
+  end
+  
+  it 'supports modifier combinations' do
+    /foo/imox.match("foo").to_a.should == ["foo"]
+    /foo/imoximox.match("foo").to_a.should == ["foo"]
+
+    lambda { eval('/foo/a') }.should raise_error(SyntaxError)
+  end
+
+  it 'supports (?imx-imx) (inline modifiers)' do
+    /(?i)foo/.match("FOO").to_a.should == ["FOO"]
+    /foo(?i)/.match("FOO").should be_nil
+    # Interaction with /i
+    /(?-i)foo/i.match("FOO").should be_nil
+    /foo(?-i)/i.match("FOO").to_a.should == ["FOO"]
+    # Multiple uses
+    /foo (?i)bar (?-i)baz/.match("foo BAR baz").to_a.should == ["foo BAR baz"]
+    /foo (?i)bar (?-i)baz/.match("foo BAR BAZ").should be_nil
+    
+    /(?m)./.match("\n").to_a.should == ["\n"]
+    /.(?m)/.match("\n").should be_nil
+    # Interaction with /m
+    /(?-m)./m.match("\n").should be_nil
+    /.(?-m)/m.match("\n").to_a.should == ["\n"]
+    # Multiple uses
+    /. (?m). (?-m)./.match(". \n .").to_a.should == [". \n ."]
+    /. (?m). (?-m)./.match(". \n \n").should be_nil
+      
+    /(?x) foo /.match("foo").to_a.should == ["foo"]
+    / foo (?x)/.match("foo").should be_nil
+    # Interaction with /x
+    /(?-x) foo /x.match("foo").should be_nil
+    / foo (?-x)/x.match("foo").to_a.should == ["foo"]
+    # Multiple uses
+    /( foo )(?x)( bar )(?-x)( baz )/.match(" foo bar baz ").to_a.should == [" foo bar baz ", " foo ", "bar", " baz "]
+    /( foo )(?x)( bar )(?-x)( baz )/.match(" foo barbaz").should be_nil
+    
+    # Parsing
+    /(?i-i)foo/.match("FOO").should be_nil
+    /(?ii)foo/.match("FOO").to_a.should == ["FOO"]
+    /(?-)foo/.match("foo").to_a.should == ["foo"]
+    lambda { eval('/(?a)/') }.should raise_error(SyntaxError)
+    lambda { eval('/(?o)/') }.should raise_error(SyntaxError)
+  end
+  
+  it 'supports (?imx-imx:expr) (scoped inline modifiers)' do
+    /foo (?i:bar) baz/.match("foo BAR baz").to_a.should == ["foo BAR baz"]
+    /foo (?i:bar) baz/.match("foo BAR BAZ").should be_nil   
+    /foo (?-i:bar) baz/i.match("foo BAR BAZ").should be_nil
+
+    /. (?m:.) ./.match(". \n .").to_a.should == [". \n ."]
+    /. (?m:.) ./.match(". \n \n").should be_nil
+    /. (?-m:.) ./m.match("\n \n \n").should be_nil
+      
+    /( foo )(?x: bar )( baz )/.match(" foo bar baz ").to_a.should == [" foo bar baz ", " foo ", " baz "]
+    /( foo )(?x: bar )( baz )/.match(" foo barbaz").should be_nil
+    /( foo )(?-x: bar )( baz )/x.match("foo bar baz").to_a.should == ["foo bar baz", "foo", "baz"]
+    
+    # Parsing
+    /(?i-i:foo)/.match("FOO").should be_nil
+    /(?ii:foo)/.match("FOO").to_a.should == ["FOO"]
+    /(?-:)foo/.match("foo").to_a.should == ["foo"]
+    lambda { eval('/(?a:)/') }.should raise_error(SyntaxError)
+    lambda { eval('/(?o:)/') }.should raise_error(SyntaxError)
+  end
+
+  it 'supports . with /m' do
+    # Basic matching
+    /./m.match("\n").to_a.should == ["\n"]
+  end
+end

Added: MacRuby/trunk/spec/frozen/language/regexp/repetition_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/regexp/repetition_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/language/regexp/repetition_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,47 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.expand_path(File.dirname(__FILE__) + '/../fixtures/classes')
+
+describe "Regexps with repetition" do
+  it 'supports * (0 or more of previous subexpression)' do
+    /a*/.match("aaa").to_a.should == ["aaa"]
+    /a*/.match("bbb").to_a.should == [""]
+    /<.*>/.match("<a>foo</a>").to_a.should == ["<a>foo</a>"] # it is greedy
+  end
+  
+  it 'supports *? (0 or more of previous subexpression - lazy)' do
+    /a*?/.match("aaa").to_a.should == [""]
+    /<.*?>/.match("<a>foo</a>").to_a.should == ["<a>"]
+  end
+  
+  it 'supports + (1 or more of previous subexpression)' do
+    /a+/.match("aaa").to_a.should == ["aaa"]
+    /a+/.match("bbb").should be_nil
+    /<.+>/.match("<a>foo</a>").to_a.should == ["<a>foo</a>"] # it is greedy
+  end
+  
+  it 'supports +? (0 or more of previous subexpression - lazy)' do
+    /a+?/.match("aaa").to_a.should == ["a"]
+    /<.+?>/.match("<a>foo</a>").to_a.should == ["<a>"]
+  end
+  
+  it 'supports {m,n} (m to n of previous subexpression)' do
+    /a{2,4}/.match("aaaaaa").to_a.should == ["aaaa"]
+    /<.{1,}>/.match("<a>foo</a>").to_a.should == ["<a>foo</a>"] # it is greedy
+  end
+  
+  it 'supports {m,n}? (m to n of previous subexpression) - lazy)' do
+    /<.{1,}?>/.match("<a>foo</a>").to_a.should == ["<a>"]
+    not_compliant_on :ironruby do # CLR issue
+    /.([0-9]){3,5}?foo/.match("9876543210foo").to_a.should == ["543210foo", "0"]
+    end
+  end
+  
+  it 'does not treat {m,n}+ as possessive' do
+    /foo(A{0,1}+)Abar/.match("fooAAAbar").to_a.should == ["fooAAAbar", "AA"]
+  end
+  
+  it 'supports ? (0 or 1 of previous subexpression)' do
+    /a?/.match("aaa").to_a.should == ["a"]
+    /a?/.match("bbb").to_a.should == [""]
+  end
+end

Added: MacRuby/trunk/spec/frozen/language/regexp/versions/character_classes_1.9.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/regexp/versions/character_classes_1.9.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/language/regexp/versions/character_classes_1.9.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,502 @@
+# coding: utf-8
+
+it "matches ASCII characters with [[:ascii:]]" do
+  "\x00".match(/[[:ascii:]]/).to_a.should == ["\x00"]
+  "\x7F".match(/[[:ascii:]]/).to_a.should == ["\x7F"]
+end
+
+it "doesn't match non-ASCII characters with [[:ascii:]]" do
+  ('/[[:ascii:]]/').match("\u{80}").should be_nil
+  ('/[[:ascii:]]/').match("\u{9898}").should be_nil
+end
+
+it "matches Unicode letter characters with [[:alnum:]]" do
+  "à".match(/[[:alnum:]]/).to_a.should == ["à"]
+end
+
+it "matches Unicode digits with [[:alnum:]]" do
+  "\u{0660}".match(/[[:alnum:]]/).to_a.should == ["\u{0660}"]
+end
+
+it "matches Unicode marks with [[:alnum:]]" do
+  "\u{36F}".match(/[[:alnum:]]/).to_a.should == ["\u{36F}"]
+end
+
+it "doesn't match Unicode control characters with [[:alnum:]]" do
+  "\u{16}".match(/[[:alnum:]]/).to_a.should == []
+end
+
+it "doesn't match Unicode punctuation characters with [[:alnum:]]" do
+  "\u{3F}".match(/[[:alnum:]]/).to_a.should == []
+end
+
+it "matches Unicode letter characters with [[:alpha:]]" do
+  "à".match(/[[:alpha:]]/).to_a.should == ["à"]
+end
+
+it "doesn't match Unicode digits with [[:alpha:]]" do
+  "\u{0660}".match(/[[:alpha:]]/).to_a.should == []
+end
+
+it "matches Unicode marks with [[:alpha:]]" do
+  "\u{36F}".match(/[[:alpha:]]/).to_a.should == ["\u{36F}"]
+end
+
+it "doesn't match Unicode control characters with [[:alpha:]]" do
+  "\u{16}".match(/[[:alpha:]]/).to_a.should == []
+end
+
+it "doesn't match Unicode punctuation characters with [[:alpha:]]" do
+  "\u{3F}".match(/[[:alpha:]]/).to_a.should == []
+end
+
+it "matches Unicode space characters with [[:blank:]]" do
+  "\u{180E}".match(/[[:blank:]]/).to_a.should == ["\u{180E}"]
+  "\u{1680}".match(/[[:blank:]]/).to_a.should == ["\u{1680}"]
+end
+
+it "doesn't match Unicode control characters with [[:blank:]]" do
+  "\u{16}".match(/[[:blank:]]/).should be_nil
+end
+
+it "doesn't match Unicode punctuation characters with [[:blank:]]" do
+  "\u{3F}".match(/[[:blank:]]/).should be_nil
+end
+
+it "doesn't match Unicode letter characters with [[:blank:]]" do
+  "à".match(/[[:blank:]]/).should be_nil
+end
+
+it "doesn't match Unicode digits with [[:blank:]]" do
+  "\u{0660}".match(/[[:blank:]]/).should be_nil
+end
+
+it "doesn't match Unicode marks with [[:blank:]]" do
+  "\u{36F}".match(/[[:blank:]]/).should be_nil
+end
+
+it "doesn't match Unicode control characters with [[:blank:]]" do
+  "\u{16}".match(/[[:blank:]]/).should be_nil
+end
+
+it "doesn't Unicode letter characters with [[:cntrl:]]" do
+  "à".match(/[[:cntrl:]]/).should be_nil
+end
+
+it "doesn't match Unicode digits with [[:cntrl:]]" do
+  "\u{0660}".match(/[[:cntrl:]]/).should be_nil
+end
+
+it "doesn't match Unicode marks with [[:cntrl:]]" do
+  "\u{36F}".match(/[[:cntrl:]]/).should be_nil
+end
+
+it "doesn't match Unicode punctuation characters with [[:cntrl:]]" do
+  "\u{3F}".match(/[[:cntrl:]]/).should be_nil
+end
+
+it "matches Unicode control characters with [[:cntrl:]]" do
+  "\u{16}".match(/[[:cntrl:]]/).to_a.should == ["\u{16}"]
+end
+
+it "matches Unicode format characters with [[:cntrl:]]" do
+  "\u{2060}".match(/[[:cntrl:]]/).to_a.should == ["\u{2060}"]
+end
+
+it "matches Unicode private-use characters with [[:cntrl:]]" do
+  "\u{E001}".match(/[[:cntrl:]]/).to_a.should == ["\u{E001}"]
+end
+
+# Oniguruma claims the below behaviour, but also regards the surrogate
+# characters as "invalid"
+it "matches Unicode surrogate characters with [[:cntrl:]]"
+
+it "doesn't match Unicode letter characters with [[:digit:]]" do
+  "à".match(/[[:digit:]]/).should be_nil
+end
+
+it "matches Unicode digits with [[:digit:]]" do
+  "\u{0660}".match(/[[:digit:]]/).to_a.should == ["\u{0660}"]
+  "\u{FF12}".match(/[[:digit:]]/).to_a.should == ["\u{FF12}"]
+end
+
+it "doesn't match Unicode marks with [[:digit:]]" do
+  "\u{36F}".match(/[[:digit:]]/).should be_nil
+end
+
+it "doesn't match Unicode punctuation characters with [[:digit:]]" do
+  "\u{3F}".match(/[[:digit:]]/).should be_nil
+end
+
+it "doesn't match Unicode control characters with [[:digit:]]" do
+  "\u{16}".match(/[[:digit:]]/).should be_nil
+end
+
+it "doesn't match Unicode format characters with [[:digit:]]" do
+  "\u{2060}".match(/[[:digit:]]/).should be_nil
+end
+
+it "doesn't match Unicode private-use characters with [[:digit:]]" do
+  "\u{E001}".match(/[[:digit:]]/).should be_nil
+end
+
+it "matches Unicode letter characters with [[:graph:]]" do
+    "à".match(/[[:graph:]]/).to_a.should == ["à"]
+end
+
+it "matches Unicode digits with [[:graph:]]" do
+  "\u{0660}".match(/[[:graph:]]/).to_a.should == ["\u{0660}"]
+  "\u{FF12}".match(/[[:graph:]]/).to_a.should == ["\u{FF12}"]
+end
+
+it "matches Unicode marks with [[:graph:]]" do
+  "\u{36F}".match(/[[:graph:]]/).to_a.should ==["\u{36F}"]
+end
+
+it "matches Unicode punctuation characters with [[:graph:]]" do
+  "\u{3F}".match(/[[:graph:]]/).to_a.should == ["\u{3F}"]
+end
+
+it "doesn't match Unicode control characters with [[:graph:]]" do
+  "\u{16}".match(/[[:graph:]]/).should be_nil
+end
+
+it "matches Unicode format characters with [[:graph:]]" do
+  "\u{2060}".match(/[[:graph:]]/).to_a.should == ["\u{2060}"]
+end
+
+it "matches Unicode private-use characters with [[:graph:]]" do
+  "\u{E001}".match(/[[:graph:]]/).to_a.should == ["\u{E001}"]
+end
+
+
+it "matches Unicode lowercase letter characters with [[:lower:]]" do
+  "\u{FF41}".match(/[[:lower:]]/).to_a.should == ["\u{FF41}"]
+  "\u{1D484}".match(/[[:lower:]]/).to_a.should == ["\u{1D484}"]
+  "\u{E8}".match(/[[:lower:]]/).to_a.should == ["\u{E8}"]
+end
+
+it "doesn't match Unicode uppercase letter characters with [[:lower:]]" do
+  "\u{100}".match(/[[:lower:]]/).should be_nil
+  "\u{130}".match(/[[:lower:]]/).should be_nil
+  "\u{405}".match(/[[:lower:]]/).should be_nil
+end
+
+it "doesn't match Unicode title-case characters with [[:lower:]]" do
+  "\u{1F88}".match(/[[:lower:]]/).should be_nil
+  "\u{1FAD}".match(/[[:lower:]]/).should be_nil
+  "\u{01C5}".match(/[[:lower:]]/).should be_nil
+end
+
+it "doesn't match Unicode digits with [[:lower:]]" do
+  "\u{0660}".match(/[[:lower:]]/).should be_nil
+  "\u{FF12}".match(/[[:lower:]]/).should be_nil
+end
+
+it "doesn't match Unicode marks with [[:lower:]]" do
+  "\u{36F}".match(/[[:lower:]]/).should be_nil
+end
+
+it "doesn't match Unicode punctuation characters with [[:lower:]]" do
+  "\u{3F}".match(/[[:lower:]]/).should be_nil
+end
+
+it "doesn't match Unicode control characters with [[:lower:]]" do
+  "\u{16}".match(/[[:lower:]]/).should be_nil
+end
+
+it "doesn't match Unicode format characters with [[:lower:]]" do
+  "\u{2060}".match(/[[:lower:]]/).should be_nil
+end
+
+it "doesn't match Unicode private-use characters with [[:lower:]]" do
+  "\u{E001}".match(/[[:lower:]]/).should be_nil
+end
+
+it "matches Unicode lowercase letter characters with [[:print:]]" do
+  "\u{FF41}".match(/[[:print:]]/).to_a.should == ["\u{FF41}"]
+  "\u{1D484}".match(/[[:print:]]/).to_a.should == ["\u{1D484}"]
+  "\u{E8}".match(/[[:print:]]/).to_a.should == ["\u{E8}"]
+end
+
+it "matches Unicode uppercase letter characters with [[:print:]]" do
+  "\u{100}".match(/[[:print:]]/).to_a.should == ["\u{100}"]
+  "\u{130}".match(/[[:print:]]/).to_a.should == ["\u{130}"]
+  "\u{405}".match(/[[:print:]]/).to_a.should == ["\u{405}"]
+end
+
+it "matches Unicode title-case characters with [[:print:]]" do
+  "\u{1F88}".match(/[[:print:]]/).to_a.should == ["\u{1F88}"]
+  "\u{1FAD}".match(/[[:print:]]/).to_a.should == ["\u{1FAD}"]
+  "\u{01C5}".match(/[[:print:]]/).to_a.should == ["\u{01C5}"]
+end
+
+it "matches Unicode digits with [[:print:]]" do
+  "\u{0660}".match(/[[:print:]]/).to_a.should == ["\u{0660}"]
+  "\u{FF12}".match(/[[:print:]]/).to_a.should == ["\u{FF12}"]
+end
+
+it "matches Unicode marks with [[:print:]]" do
+  "\u{36F}".match(/[[:print:]]/).to_a.should == ["\u{36F}"]
+end
+
+it "matches Unicode punctuation characters with [[:print:]]" do
+  "\u{3F}".match(/[[:print:]]/).to_a.should == ["\u{3F}"]
+end
+
+it "doesn't match Unicode control characters with [[:print:]]" do
+  "\u{16}".match(/[[:print:]]/).should be_nil
+end
+
+it "matches Unicode format characters with [[:print:]]" do
+  "\u{2060}".match(/[[:print:]]/).to_a.should == ["\u{2060}"]
+end
+
+it "matches Unicode private-use characters with [[:print:]]" do
+  "\u{E001}".match(/[[:print:]]/).to_a.should == ["\u{E001}"]
+end
+
+
+it "doesn't match Unicode lowercase letter characters with [[:punct:]]" do
+  "\u{FF41}".match(/[[:punct:]]/).should be_nil
+  "\u{1D484}".match(/[[:punct:]]/).should be_nil
+  "\u{E8}".match(/[[:punct:]]/).should be_nil
+end
+
+it "doesn't match Unicode uppercase letter characters with [[:punct:]]" do
+  "\u{100}".match(/[[:punct:]]/).should be_nil
+  "\u{130}".match(/[[:punct:]]/).should be_nil
+  "\u{405}".match(/[[:punct:]]/).should be_nil
+end
+
+it "doesn't match Unicode title-case characters with [[:punct:]]" do
+  "\u{1F88}".match(/[[:punct:]]/).should be_nil
+  "\u{1FAD}".match(/[[:punct:]]/).should be_nil
+  "\u{01C5}".match(/[[:punct:]]/).should be_nil
+end
+
+it "doesn't match Unicode digits with [[:punct:]]" do
+  "\u{0660}".match(/[[:punct:]]/).should be_nil
+  "\u{FF12}".match(/[[:punct:]]/).should be_nil
+end
+
+it "doesn't match Unicode marks with [[:punct:]]" do
+  "\u{36F}".match(/[[:punct:]]/).should be_nil
+end
+
+it "matches Unicode Pc characters with [[:punct:]]" do
+  "\u{203F}".match(/[[:punct:]]/).to_a.should == ["\u{203F}"]
+end
+
+it "matches Unicode Pd characters with [[:punct:]]" do
+  "\u{2E17}".match(/[[:punct:]]/).to_a.should == ["\u{2E17}"]
+end
+
+it "matches Unicode Ps characters with [[:punct:]]" do
+  "\u{0F3A}".match(/[[:punct:]]/).to_a.should == ["\u{0F3A}"]
+end
+
+it "matches Unicode Pe characters with [[:punct:]]" do
+  "\u{2046}".match(/[[:punct:]]/).to_a.should == ["\u{2046}"]
+end
+
+it "matches Unicode Pi characters with [[:punct:]]" do
+  "\u{00AB}".match(/[[:punct:]]/).to_a.should == ["\u{00AB}"]
+end
+
+it "matches Unicode Pf characters with [[:punct:]]" do
+  "\u{201D}".match(/[[:punct:]]/).to_a.should == ["\u{201D}"]
+end
+
+it "matches Unicode Pf characters with [[:punct:]]" do
+  "\u{00BB}".match(/[[:punct:]]/).to_a.should == ["\u{00BB}"]
+end
+
+it "matches Unicode Po characters with [[:punct:]]" do
+  "\u{00BF}".match(/[[:punct:]]/).to_a.should == ["\u{00BF}"]
+end
+
+it "doesn't match Unicode format characters with [[:punct:]]" do
+  "\u{2060}".match(/[[:punct:]]/).should be_nil
+end
+
+it "doesn't match Unicode private-use characters with [[:punct:]]" do
+  "\u{E001}".match(/[[:punct:]]/).should be_nil
+end
+
+it "doesn't match Unicode lowercase letter characters with [[:space:]]" do
+  "\u{FF41}".match(/[[:space:]]/).should be_nil
+  "\u{1D484}".match(/[[:space:]]/).should be_nil
+  "\u{E8}".match(/[[:space:]]/).should be_nil
+end
+
+it "doesn't match Unicode uppercase letter characters with [[:space:]]" do
+  "\u{100}".match(/[[:space:]]/).should be_nil
+  "\u{130}".match(/[[:space:]]/).should be_nil
+  "\u{405}".match(/[[:space:]]/).should be_nil
+end
+
+it "doesn't match Unicode title-case characters with [[:space:]]" do
+  "\u{1F88}".match(/[[:space:]]/).should be_nil
+  "\u{1FAD}".match(/[[:space:]]/).should be_nil
+  "\u{01C5}".match(/[[:space:]]/).should be_nil
+end
+
+it "doesn't match Unicode digits with [[:space:]]" do
+  "\u{0660}".match(/[[:space:]]/).should be_nil
+  "\u{FF12}".match(/[[:space:]]/).should be_nil
+end
+
+it "doesn't match Unicode marks with [[:space:]]" do
+  "\u{36F}".match(/[[:space:]]/).should be_nil
+end
+
+it "matches Unicode Zs characters with [[:space:]]" do
+  "\u{205F}".match(/[[:space:]]/).to_a.should == ["\u{205F}"]
+end
+
+it "matches Unicode Zl characters with [[:space:]]" do
+  "\u{2028}".match(/[[:space:]]/).to_a.should == ["\u{2028}"]
+end
+
+it "matches Unicode Zp characters with [[:space:]]" do
+  "\u{2029}".match(/[[:space:]]/).to_a.should == ["\u{2029}"]
+end
+
+it "doesn't match Unicode format characters with [[:space:]]" do
+  "\u{2060}".match(/[[:space:]]/).should be_nil
+end
+
+it "doesn't match Unicode private-use characters with [[:space:]]" do
+  "\u{E001}".match(/[[:space:]]/).should be_nil
+end
+
+it "doesn't match Unicode lowercase characters with [[:upper:]]" do
+  "\u{FF41}".match(/[[:upper:]]/).should be_nil
+  "\u{1D484}".match(/[[:upper:]]/).should be_nil
+  "\u{E8}".match(/[[:upper:]]/).should be_nil
+end
+
+it "matches Unicode uppercase characters with [[:upper:]]" do
+  "\u{100}".match(/[[:upper:]]/).to_a.should == ["\u{100}"]
+  "\u{130}".match(/[[:upper:]]/).to_a.should == ["\u{130}"]
+  "\u{405}".match(/[[:upper:]]/).to_a.should == ["\u{405}"]
+end
+
+it "doesn't match Unicode title-case characters with [[:upper:]]" do
+  "\u{1F88}".match(/[[:upper:]]/).should be_nil
+  "\u{1FAD}".match(/[[:upper:]]/).should be_nil
+  "\u{01C5}".match(/[[:upper:]]/).should be_nil
+end
+
+it "doesn't match Unicode digits with [[:upper:]]" do
+  "\u{0660}".match(/[[:upper:]]/).should be_nil
+  "\u{FF12}".match(/[[:upper:]]/).should be_nil
+end
+
+it "doesn't match Unicode marks with [[:upper:]]" do
+  "\u{36F}".match(/[[:upper:]]/).should be_nil
+end
+
+it "doesn't match Unicode punctuation characters with [[:upper:]]" do
+  "\u{3F}".match(/[[:upper:]]/).should be_nil
+end
+
+it "doesn't match Unicode control characters with [[:upper:]]" do
+  "\u{16}".match(/[[:upper:]]/).should be_nil
+end
+
+it "doesn't match Unicode format characters with [[:upper:]]" do
+  "\u{2060}".match(/[[:upper:]]/).should be_nil
+end
+
+it "doesn't match Unicode private-use characters with [[:upper:]]" do
+  "\u{E001}".match(/[[:upper:]]/).should be_nil
+end
+
+it "doesn't match Unicode letter characters [^a-fA-F] with [[:xdigit:]]" do
+  "à".match(/[[:xdigit:]]/).should be_nil
+  "g".match(/[[:xdigit:]]/).should be_nil
+  "X".match(/[[:xdigit:]]/).should be_nil
+end
+
+it "matches Unicode letter characters [a-fA-F] with [[:xdigit:]]" do
+  "a".match(/[[:xdigit:]]/).to_a.should == ["a"]
+  "F".match(/[[:xdigit:]]/).to_a.should == ["F"]
+end
+
+it "doesn't match Unicode digits [^0-9] with [[:xdigit:]]" do
+  "\u{0660}".match(/[[:xdigit:]]/).should be_nil
+  "\u{FF12}".match(/[[:xdigit:]]/).should be_nil
+end
+
+it "doesn't match Unicode marks with [[:xdigit:]]" do
+  "\u{36F}".match(/[[:xdigit:]]/).should be_nil
+end
+
+it "doesn't match Unicode punctuation characters with [[:xdigit:]]" do
+  "\u{3F}".match(/[[:xdigit:]]/).should be_nil
+end
+
+it "doesn't match Unicode control characters with [[:xdigit:]]" do
+  "\u{16}".match(/[[:xdigit:]]/).should be_nil
+end
+
+it "doesn't match Unicode format characters with [[:xdigit:]]" do
+  "\u{2060}".match(/[[:xdigit:]]/).should be_nil
+end
+
+it "doesn't match Unicode private-use characters with [[:xdigit:]]" do
+  "\u{E001}".match(/[[:xdigit:]]/).should be_nil
+end
+
+it "matches Unicode lowercase characters with [[:word:]]" do
+  "\u{FF41}".match(/[[:word:]]/).to_a.should == ["\u{FF41}"]
+  "\u{1D484}".match(/[[:word:]]/).to_a.should == ["\u{1D484}"]
+  "\u{E8}".match(/[[:word:]]/).to_a.should == ["\u{E8}"]
+end
+
+it "matches Unicode uppercase characters with [[:word:]]" do
+  "\u{100}".match(/[[:word:]]/).to_a.should == ["\u{100}"]
+  "\u{130}".match(/[[:word:]]/).to_a.should == ["\u{130}"]
+  "\u{405}".match(/[[:word:]]/).to_a.should == ["\u{405}"]
+end
+
+it "matches Unicode title-case characters with [[:word:]]" do
+  "\u{1F88}".match(/[[:word:]]/).to_a.should == ["\u{1F88}"]
+  "\u{1FAD}".match(/[[:word:]]/).to_a.should == ["\u{1FAD}"]
+  "\u{01C5}".match(/[[:word:]]/).to_a.should == ["\u{01C5}"]
+end
+
+it "matches Unicode decimal digits with [[:word:]]" do
+  "\u{FF10}".match(/[[:word:]]/).to_a.should == ["\u{FF10}"]
+  "\u{096C}".match(/[[:word:]]/).to_a.should == ["\u{096C}"]
+end
+
+it "matches Unicode Nl characters with [[:word:]]" do
+  "\u{16EE}".match(/[[:word:]]/).to_a.should == ["\u{16EE}"]
+end
+
+it "matches Unicode No characters with [[:word:]]" do
+  "\u{17F0}".match(/[[:word:]]/).to_a.should == ["\u{17F0}"]
+end
+
+it "matches Unicode marks with [[:word:]]" do
+  "\u{36F}".match(/[[:word:]]/).to_a.should == ["\u{36F}"]
+end
+
+it "doesn't match Unicode punctuation characters with [[:word:]]" do
+  "\u{3F}".match(/[[:word:]]/).should be_nil
+end
+
+it "doesn't match Unicode control characters with [[:word:]]" do
+  "\u{16}".match(/[[:word:]]/).should be_nil
+end
+
+it "doesn't match Unicode format characters with [[:word:]]" do
+  "\u{2060}".match(/[[:word:]]/).should be_nil
+end
+
+it "doesn't match Unicode private-use characters with [[:word:]]" do
+  "\u{E001}".match(/[[:word:]]/).should be_nil
+end

Modified: MacRuby/trunk/spec/frozen/language/regexp_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/regexp_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/language/regexp_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -75,195 +75,11 @@
     %r[/].to_s.should == /\//.to_s
   end
   
-  #############################################################################
-  # Substitution
-  #############################################################################
   
-  it "allow substitution of strings" do
-    str = "foo|bar"
-    /#{str}/.should == /foo|bar/
-  end
-
-  it "allow substitution of literal regexps" do
-    re = /foo|bar/
-    /#{re}/.should == /(?-mix:foo|bar)/
-  end
-  
-  it "allow substitution of any class that responds to to_s" do
-    o = LanguageSpecs::ClassWith_to_s.new
-    /#{o}/.should == /class_with_to_s/
-  end
-  
-  it "throws NoMethodError on missing to_s" do
-    o = LanguageSpecs::ClassWithout_to_s.new
-    lambda { /#{o}/ }.should raise_error(NoMethodError)
-  end
-  
-  it "allows substitution which mixes modifiers" do
-    re = /foo/i
-    /#{re} bar/m.should == /(?i-mx:foo) bar/m
-  end
-  
-  it "allows substitution to interact with other Regexp constructs" do
-    str = "foo)|(bar"
-    /(#{str})/.should == /(foo)|(bar)/
-    
-    str = "a"
-    /[#{str}-z]/.should == /[a-z]/
-  end
-  
-  it "gives precedence to escape sequences over substitution" do
-    str = "J"
-    /\c#{str}/.to_s.should == '(?-mix:\c#' + '{str})'
-  end  
-
-  it "throws RegexpError for malformed substitution" do
-    s = ""
-    lambda { /(#{s}/ }.should raise_error(RegexpError)
-    s = "("
-    lambda { /#{s}/ }.should raise_error(RegexpError)
-  end
-
-  it "allows substituion in extended mode" do
-    var = "#comment\n  foo  #comment\n  |  bar"
-    (/#{var}/x =~ "foo").should == (/foo|bar/ =~ "foo")
-  end
-  
   #############################################################################
   # Specs for the matching semantics
   #############################################################################
-    
-  it 'supports escape characters' do
-    /\t/.match("\t").to_a.should == ["\t"] # horizontal tab
-    /\v/.match("\v").to_a.should == ["\v"] # vertical tab
-    /\n/.match("\n").to_a.should == ["\n"] # newline
-    /\r/.match("\r").to_a.should == ["\r"] # return
-    /\f/.match("\f").to_a.should == ["\f"] # form feed
-    /\a/.match("\a").to_a.should == ["\a"] # bell
-    /\e/.match("\e").to_a.should == ["\e"] # escape
-
-    # \nnn         octal char            (encoded byte value)
-  end
   
-  it 'supports quoting meta-characters via escape sequence' do
-    /\\/.match("\\").to_a.should == ["\\"]
-    /\//.match("/").to_a.should == ["/"]
-    # parenthesis, etc
-    /\(/.match("(").to_a.should == ["("]
-    /\)/.match(")").to_a.should == [")"]
-    /\[/.match("[").to_a.should == ["["]
-    /\]/.match("]").to_a.should == ["]"]
-    /\{/.match("{").to_a.should == ["{"]
-    /\}/.match("}").to_a.should == ["}"]
-    # alternation separator
-    /\|/.match("|").to_a.should == ["|"]
-    # quantifiers
-    /\?/.match("?").to_a.should == ["?"]
-    /\./.match(".").to_a.should == ["."]
-    /\*/.match("*").to_a.should == ["*"]
-    /\+/.match("+").to_a.should == ["+"]
-    # line anchors
-    /\^/.match("^").to_a.should == ["^"]
-    /\$/.match("$").to_a.should == ["$"]    
-  end
-  
-  it 'allows any character to be escaped' do
-    /\y/.match("y").to_a.should == ["y"]  
-  end
-  
-  it 'supports \x (hex characters)' do
-    /\xA/.match("\nxyz").to_a.should == ["\n"]
-    /\x0A/.match("\n").to_a.should == ["\n"]
-    /\xAA/.match("\nA").should be_nil
-    /\x0AA/.match("\nA").to_a.should == ["\nA"]
-    /\xAG/.match("\nG").to_a.should == ["\nG"]
-    # Non-matches
-    lambda { eval('/\xG/') }.should raise_error(SyntaxError)
-    
-    # \x{7HHHHHHH} wide hexadecimal char (character code point value)
-  end
-  
-  it 'supports \c (control characters)' do
-    #/\c \c@\c`/.match("\00\00\00").to_a.should == ["\00\00\00"]
-    /\c#\cc\cC/.match("\03\03\03").to_a.should == ["\03\03\03"]
-    /\c'\cG\cg/.match("\a\a\a").to_a.should == ["\a\a\a"]
-    /\c(\cH\ch/.match("\b\b\b").to_a.should == ["\b\b\b"]
-    /\c)\cI\ci/.match("\t\t\t").to_a.should == ["\t\t\t"]
-    /\c*\cJ\cj/.match("\n\n\n").to_a.should == ["\n\n\n"]
-    /\c+\cK\ck/.match("\v\v\v").to_a.should == ["\v\v\v"]
-    /\c,\cL\cl/.match("\f\f\f").to_a.should == ["\f\f\f"]
-    /\c-\cM\cm/.match("\r\r\r").to_a.should == ["\r\r\r"]
-    
-    /\cJ/.match("\r").should be_nil
-
-    # Parsing precedence
-    /\cJ+/.match("\n\n").to_a.should == ["\n\n"] # Quantifers apply to entire escape sequence
-    /\\cJ/.match("\\cJ").to_a.should == ["\\cJ"]
-    lambda { eval('/[abc\x]/') }.should raise_error(SyntaxError) # \x is treated as a escape sequence even inside a character class
-    # Syntax error
-    lambda { eval('/\c/') }.should raise_error(SyntaxError)
-
-    # \cx          control char          (character code point value)
-    # \C-x         control char          (character code point value)
-    # \M-x         meta  (x|0x80)        (character code point value)
-    # \M-\C-x      meta control char     (character code point value)
-  end
-  
-  it 'supports ^ (line start anchor)' do
-    # Basic matching
-    /^foo/.match("foo").to_a.should == ["foo"]
-    /^bar/.match("foo\nbar").to_a.should == ["bar"]
-    # Basic non-matching
-    /^foo/.match(" foo").should be_nil
-    /foo^/.match("foo\n\n\n").should be_nil
-    
-    # A bit advanced
-    /^^^foo/.match("foo").to_a.should == ["foo"]
-    (/^[^f]/ =~ "foo\n\n").should == "foo\n".size and $~.to_a.should == ["\n"]
-    (/($^)($^)/ =~ "foo\n\n").should == "foo\n".size and $~.to_a.should == ["", "", ""]
-
-    # Different start of line chars
-    /^bar/.match("foo\rbar").should be_nil
-    /^bar/.match("foo\0bar").should be_nil
-
-    # Trivial
-    /^/.match("foo").to_a.should == [""]
-
-    # Grouping
-    /(^foo)/.match("foo").to_a.should == ["foo", "foo"]
-    /(^)/.match("foo").to_a.should == ["", ""]
-    /(foo\n^)(^bar)/.match("foo\nbar").to_a.should == ["foo\nbar", "foo\n", "bar"]   
-  end
-  
-  it 'does not match ^ after trailing \n' do
-    /^(?!\A)/.match("foo\n").should be_nil # There is no (empty) line after a trailing \n
-  end
-
-  it 'supports $ (line end anchor)' do
-    # Basic  matching
-    /foo$/.match("foo").to_a.should == ["foo"]
-    /foo$/.match("foo\nbar").to_a.should == ["foo"]
-    # Basic non-matching
-    /foo$/.match("foo ").should be_nil
-    /$foo/.match("\n\n\nfoo").should be_nil
-
-    # A bit advanced
-    /foo$$$/.match("foo").to_a.should == ["foo"]
-    (/[^o]$/ =~ "foo\n\n").should == ("foo\n".size - 1) and $~.to_a.should == ["\n"]
-
-    # Different end of line chars
-    /foo$/.match("foo\r\nbar").should be_nil
-    /foo$/.match("foo\0bar").should be_nil
-
-    # Trivial
-    (/$/ =~ "foo").should == "foo".size and $~.to_a.should == [""]
-
-    # Grouping
-    /(foo$)/.match("foo").to_a.should == ["foo", "foo"]
-    (/($)/ =~ "foo").should == "foo".size and $~.to_a.should == ["", ""]
-    /(foo$)($\nbar)/.match("foo\nbar").to_a.should == ["foo\nbar", "foo", "\nbar"]
-  end
-  
   it 'supports . (any character except line terminator)' do
     # Basic matching
     /./.match("foo").to_a.should == ["f"]
@@ -273,473 +89,20 @@
     /./.match("\0").to_a.should == ["\0"]
   end
   
-  it 'supports . with /m' do
-    # Basic matching
-    /./m.match("\n").to_a.should == ["\n"]
-  end
-  
-  it 'supports \w (word character)' do
-    /\w/.match("a").to_a.should == ["a"]
-    /\w/.match("1").to_a.should == ["1"]
-    /\w/.match("_").to_a.should == ["_"]
-    
-    # Non-matches
-    /\w/.match(LanguageSpecs.white_spaces).should be_nil
-    /\w/.match(LanguageSpecs.non_alphanum_non_space).should be_nil
-    /\w/.match("\0").should be_nil
-  end
-  
-  it 'supports \W (non-word character)' do
-    /\W+/.match(LanguageSpecs.white_spaces).to_a.should == [LanguageSpecs.white_spaces]
-    /\W+/.match(LanguageSpecs.non_alphanum_non_space).to_a.should == [LanguageSpecs.non_alphanum_non_space]
-    /\W/.match("\0").to_a.should == ["\0"]
 
-    # Non-matches
-    /\W/.match("a").should be_nil
-    /\W/.match("1").should be_nil
-    /\W/.match("_").should be_nil
-  end
-  
-  it 'supports \s (space character)' do
-    /\s+/.match(LanguageSpecs.white_spaces).to_a.should == [LanguageSpecs.white_spaces]
-    
-    # Non-matches
-    /\s/.match("a").should be_nil
-    /\s/.match("1").should be_nil
-    /\s/.match(LanguageSpecs.non_alphanum_non_space).should be_nil
-    /\s/.match("\0").should be_nil
-  end
-  
-  it 'supports \S (non-space character)' do    
-    /\S/.match("a").to_a.should == ["a"]
-    /\S/.match("1").to_a.should == ["1"]
-    /\S+/.match(LanguageSpecs.non_alphanum_non_space).to_a.should == [LanguageSpecs.non_alphanum_non_space]
-    /\S/.match("\0").to_a.should == ["\0"]
-
-    # Non-matches
-    /\S/.match(LanguageSpecs.white_spaces).should be_nil
-  end
-  
-  it 'supports \d (numeric digit)' do
-    /\d/.match("1").to_a.should == ["1"]
-    
-    # Non-matches
-    /\d/.match("a").should be_nil
-    /\d/.match(LanguageSpecs.white_spaces).should be_nil
-    /\d/.match(LanguageSpecs.non_alphanum_non_space).should be_nil
-    /\d/.match("\0").should be_nil
-  end
-  
-  it 'supports \D (non-digit)' do   
-    /\D/.match("a").to_a.should == ["a"]
-    /\D+/.match(LanguageSpecs.white_spaces).to_a.should == [LanguageSpecs.white_spaces]
-    /\D+/.match(LanguageSpecs.non_alphanum_non_space).to_a.should == [LanguageSpecs.non_alphanum_non_space]
-    /\D/.match("\0").to_a.should == ["\0"]
-
-    # Non-matches
-    /\D/.match("1").should be_nil
-  end
-  
-  it 'supports \A (string start anchor)' do
-    # Basic matching
-    /\Afoo/.match("foo").to_a.should == ["foo"]
-    # Basic non-matching
-    /\Abar/.match("foo\nbar").should be_nil
-    /\Afoo/.match(" foo").should be_nil
-    
-    # A bit advanced
-    /\A\A\Afoo/.match("foo").to_a.should == ["foo"]
-    /(\A\Z)(\A\Z)/.match("").to_a.should == ["", "", ""]
-
-    # Different start of line chars
-    /\Abar/.match("foo\0bar").should be_nil
-
-    # Grouping
-    /(\Afoo)/.match("foo").to_a.should == ["foo", "foo"]
-    /(\A)/.match("foo").to_a.should == ["", ""]
-  end
-  
-  it 'supports \Z (string end anchor, including before trailing \n)' do
-    # Basic matching
-    /foo\Z/.match("foo").to_a.should == ["foo"]
-    /foo\Z/.match("foo\n").to_a.should == ["foo"]
-    # Basic non-matching
-    /foo\Z/.match("foo\nbar").should be_nil
-    /foo\Z/.match("foo ").should be_nil
-    
-    # A bit advanced
-    /foo\Z\Z\Z/.match("foo\n").to_a.should == ["foo"]
-    (/($\Z)($\Z)/ =~ "foo\n").should == "foo".size and $~.to_a.should == ["", "", ""]
-    (/(\z\Z)(\z\Z)/ =~ "foo\n").should == "foo\n".size and $~.to_a.should == ["", "", ""]
-
-    # Different end of line chars
-    /foo\Z/.match("foo\0bar").should be_nil
-    /foo\Z/.match("foo\r\n").should be_nil
-
-    # Grouping
-    /(foo\Z)/.match("foo").to_a.should == ["foo", "foo"]
-    (/(\Z)/ =~ "foo").should == "foo".size and $~.to_a.should == ["", ""]
-  end
-  
-  it 'supports \z (string end anchor)' do
-    # Basic matching
-    /foo\z/.match("foo").to_a.should == ["foo"]
-    # Basic non-matching
-    /foo\z/.match("foo\nbar").should be_nil
-    /foo\z/.match("foo\n").should be_nil
-    /foo\z/.match("foo ").should be_nil
-    
-    # A bit advanced
-    /foo\z\z\z/.match("foo").to_a.should == ["foo"]
-    (/($\z)($\z)/ =~ "foo").should == "foo".size and $~.to_a.should == ["", "", ""]
-
-    # Different end of line chars
-    /foo\z/.match("foo\0bar").should be_nil
-    /foo\z/.match("foo\r\nbar").should be_nil
-
-    # Grouping
-    /(foo\z)/.match("foo").to_a.should == ["foo", "foo"]
-    (/(\z)/ =~ "foo").should == "foo".size and $~.to_a.should == ["", ""]
-  end
-  
-  it 'supports \b (word boundary)' do
-    # Basic matching
-    /foo\b/.match("foo").to_a.should == ["foo"]
-    /foo\b/.match("foo\n").to_a.should == ["foo"]
-    LanguageSpecs.white_spaces.scan(/./).each do |c|
-    /foo\b/.match("foo" + c).to_a.should == ["foo"]
-    end
-    LanguageSpecs.non_alphanum_non_space.scan(/./).each do |c|
-    /foo\b/.match("foo" + c).to_a.should == ["foo"]
-    end
-    /foo\b/.match("foo\0").to_a.should == ["foo"]
-    # Basic non-matching
-    /foo\b/.match("foobar").should be_nil
-    /foo\b/.match("foo123").should be_nil
-    /foo\b/.match("foo_").should be_nil
-  end
-  
-  it 'supports \B (non-word-boundary)' do
-    # Basic matching
-    /foo\B/.match("foobar").to_a.should == ["foo"]
-    /foo\B/.match("foo123").to_a.should == ["foo"]
-    /foo\B/.match("foo_").to_a.should == ["foo"]
-    # Basic non-matching
-    /foo\B/.match("foo").should be_nil
-    /foo\B/.match("foo\n").should be_nil
-    LanguageSpecs.white_spaces.scan(/./).each do |c|
-    /foo\B/.match("foo" + c).should be_nil
-    end
-    LanguageSpecs.non_alphanum_non_space.scan(/./).each do |c|
-    /foo\B/.match("foo" + c).should be_nil
-    end
-    /foo\B/.match("foo\0").should be_nil
-  end
-  
-  it 'supports [] (character class)' do
-    /[a-z]+/.match("fooBAR").to_a.should == ["foo"]
-    /[\b]/.match("\b").to_a.should == ["\b"] # \b inside character class is backspace
-  end
-  
-  it 'supports [[:alpha:][:digit:][:etc:]] (predefined character classes)' do
-    /[[:alnum:]]+/.match("a1").to_a.should == ["a1"]
-    /[[:alpha:]]+/.match("Aa1").to_a.should == ["Aa"]
-    /[[:blank:]]+/.match(LanguageSpecs.white_spaces).to_a.should == [LanguageSpecs.blanks]
-    # /[[:cntrl:]]/.match("").to_a.should == [""] # TODO: what should this match?
-    /[[:digit:]]/.match("1").to_a.should == ["1"]    
-    # /[[:graph:]]/.match("").to_a.should == [""] # TODO: what should this match?
-    /[[:lower:]]+/.match("Aa1").to_a.should == ["a"]
-    /[[:print:]]+/.match(LanguageSpecs.white_spaces).to_a.should == [" "]     # include all of multibyte encoded characters
-    /[[:punct:]]+/.match(LanguageSpecs.punctuations).to_a.should == [LanguageSpecs.punctuations]
-    /[[:space:]]+/.match(LanguageSpecs.white_spaces).to_a.should == [LanguageSpecs.white_spaces]
-    /[[:upper:]]+/.match("123ABCabc").to_a.should == ["ABC"]
-    /[[:xdigit:]]+/.match("xyz0123456789ABCDEFabcdefXYZ").to_a.should == ["0123456789ABCDEFabcdef"]
-    ruby_version_is "1.9" do
-    eval('/[[:ascii:]]/').match("a").to_a.should == ["a"]
-    end
-    
-    # Parsing
-    /[[:lower:][:digit:]A-C]+/.match("a1ABCDEF").to_a.should == ["a1ABC"] # can be composed with other constructs in the character class
-    /[^[:lower:]A-C]+/.match("abcABCDEF123def").to_a.should == ["DEF123"] # negated character class
-    /[:alnum:]+/.match("a:l:n:u:m").to_a.should == ["a:l:n:u:m"] # should behave like regular character class composed of the individual letters
-    /[\[:alnum:]+/.match("[:a:l:n:u:m").to_a.should == ["[:a:l:n:u:m"] # should behave like regular character class composed of the individual letters
-    lambda { eval('/[[:alpha:]-[:digit:]]/') }.should raise_error(SyntaxError) # can't use character class as a start value of range
-  end
-  
-  it 'supports ()' do
-    /(a)/.match("a").to_a.should == ["a", "a"]
-  end
-  
-  it 'supports * (0 or more of previous subexpression)' do
-    /a*/.match("aaa").to_a.should == ["aaa"]
-    /a*/.match("bbb").to_a.should == [""]
-    /<.*>/.match("<a>foo</a>").to_a.should == ["<a>foo</a>"] # it is greedy
-  end
-  
-  it 'supports *? (0 or more of previous subexpression - lazy)' do
-    /a*?/.match("aaa").to_a.should == [""]
-    /<.*?>/.match("<a>foo</a>").to_a.should == ["<a>"]
-  end
-  
-  it 'supports + (1 or more of previous subexpression)' do
-    /a+/.match("aaa").to_a.should == ["aaa"]
-    /a+/.match("bbb").should be_nil
-    /<.+>/.match("<a>foo</a>").to_a.should == ["<a>foo</a>"] # it is greedy
-  end
-  
-  it 'supports +? (0 or more of previous subexpression - lazy)' do
-    /a+?/.match("aaa").to_a.should == ["a"]
-    /<.+?>/.match("<a>foo</a>").to_a.should == ["<a>"]
-  end
-  
-  it 'supports {m,n} (m to n of previous subexpression)' do
-    /a{2,4}/.match("aaaaaa").to_a.should == ["aaaa"]
-    /<.{1,}>/.match("<a>foo</a>").to_a.should == ["<a>foo</a>"] # it is greedy
-  end
-  
-  it 'supports {m,n}? (m to n of previous subexpression) - lazy)' do
-    /<.{1,}?>/.match("<a>foo</a>").to_a.should == ["<a>"]
-    not_compliant_on :ironruby do # CLR issue
-    /.([0-9]){3,5}?foo/.match("9876543210foo").to_a.should == ["543210foo", "0"]
-    end
-  end
-  
-  it 'does not treat {m,n}+ as possessive' do
-    /foo(A{0,1}+)Abar/.match("fooAAAbar").to_a.should == ["fooAAAbar", "AA"]
-  end
-  
-  it 'supports ? (0 or 1 of previous subexpression)' do
-    /a?/.match("aaa").to_a.should == ["a"]
-    /a?/.match("bbb").to_a.should == [""]
-  end
-  
   it 'supports | (alternations)' do
     /a|b/.match("a").to_a.should == ["a"]
   end
   
-  it 'supports (?= ) (positive lookahead)' do
-    /foo.(?=bar)/.match("foo1 foo2bar").to_a.should == ["foo2"]
-  end
-  
-  it 'supports (?! ) (negative lookahead)' do
-    /foo.(?!bar)/.match("foo1bar foo2").to_a.should == ["foo2"]
-  end
-  
   it 'supports (?> ) (embedded subexpression)' do
     /(?>foo)(?>bar)/.match("foobar").to_a.should == ["foobar"]
     /(?>foo*)obar/.match("foooooooobar").should be_nil # it is possesive
   end
   
-  it 'supports (?: ) (non-capturing group)' do
-    /(?:foo)(bar)/.match("foobar").to_a.should == ["foobar", "bar"]
-    # Parsing precedence
-    /(?:xdigit:)/.match("xdigit:").to_a.should == ["xdigit:"]
-  end
-  
-  it 'supports (?imx-imx) (inline modifiers)' do
-    /(?i)foo/.match("FOO").to_a.should == ["FOO"]
-    /foo(?i)/.match("FOO").should be_nil
-    # Interaction with /i
-    /(?-i)foo/i.match("FOO").should be_nil
-    /foo(?-i)/i.match("FOO").to_a.should == ["FOO"]
-    # Multiple uses
-    /foo (?i)bar (?-i)baz/.match("foo BAR baz").to_a.should == ["foo BAR baz"]
-    /foo (?i)bar (?-i)baz/.match("foo BAR BAZ").should be_nil
-    
-    /(?m)./.match("\n").to_a.should == ["\n"]
-    /.(?m)/.match("\n").should be_nil
-    # Interaction with /m
-    /(?-m)./m.match("\n").should be_nil
-    /.(?-m)/m.match("\n").to_a.should == ["\n"]
-    # Multiple uses
-    /. (?m). (?-m)./.match(". \n .").to_a.should == [". \n ."]
-    /. (?m). (?-m)./.match(". \n \n").should be_nil
-      
-    /(?x) foo /.match("foo").to_a.should == ["foo"]
-    / foo (?x)/.match("foo").should be_nil
-    # Interaction with /x
-    /(?-x) foo /x.match("foo").should be_nil
-    / foo (?-x)/x.match("foo").to_a.should == ["foo"]
-    # Multiple uses
-    /( foo )(?x)( bar )(?-x)( baz )/.match(" foo bar baz ").to_a.should == [" foo bar baz ", " foo ", "bar", " baz "]
-    /( foo )(?x)( bar )(?-x)( baz )/.match(" foo barbaz").should be_nil
-    
-    # Parsing
-    /(?i-i)foo/.match("FOO").should be_nil
-    /(?ii)foo/.match("FOO").to_a.should == ["FOO"]
-    /(?-)foo/.match("foo").to_a.should == ["foo"]
-    lambda { eval('/(?a)/') }.should raise_error(SyntaxError)
-    lambda { eval('/(?o)/') }.should raise_error(SyntaxError)
-  end
-  
-  it 'supports (?imx-imx:expr) (scoped inline modifiers)' do
-    /foo (?i:bar) baz/.match("foo BAR baz").to_a.should == ["foo BAR baz"]
-    /foo (?i:bar) baz/.match("foo BAR BAZ").should be_nil   
-    /foo (?-i:bar) baz/i.match("foo BAR BAZ").should be_nil
-
-    /. (?m:.) ./.match(". \n .").to_a.should == [". \n ."]
-    /. (?m:.) ./.match(". \n \n").should be_nil
-    /. (?-m:.) ./m.match("\n \n \n").should be_nil
-      
-    /( foo )(?x: bar )( baz )/.match(" foo bar baz ").to_a.should == [" foo bar baz ", " foo ", " baz "]
-    /( foo )(?x: bar )( baz )/.match(" foo barbaz").should be_nil
-    /( foo )(?-x: bar )( baz )/x.match("foo bar baz").to_a.should == ["foo bar baz", "foo", "baz"]
-    
-    # Parsing
-    /(?i-i:foo)/.match("FOO").should be_nil
-    /(?ii:foo)/.match("FOO").to_a.should == ["FOO"]
-    /(?-:)foo/.match("foo").to_a.should == ["foo"]
-    lambda { eval('/(?a:)/') }.should raise_error(SyntaxError)
-    lambda { eval('/(?o:)/') }.should raise_error(SyntaxError)
-  end
-  
   it 'supports (?# )' do
     /foo(?#comment)bar/.match("foobar").to_a.should == ["foobar"]
     /foo(?#)bar/.match("foobar").to_a.should == ["foobar"]
   end
-  
-  it 'supports \<n> (backreference to previous group match)' do
-    /(foo.)\1/.match("foo1foo1").to_a.should == ["foo1foo1", "foo1"]
-    /(foo.)\1/.match("foo1foo2").should be_nil
-  end
-  
-  not_compliant_on :ironruby do
-    it 'resets nested \<n> backreference before match of outer subexpression' do
-      /(a\1?){2}/.match("aaaa").to_a.should == ["aa", "a"]
-    end
-  end
-  
-  #############################################################################
-  # Modifiers
-  #############################################################################
-
-  it 'supports /i (case-insensitive)' do
-    /foo/i.match("FOO").to_a.should == ["FOO"]
-  end
-  
-  it 'supports /m (multiline)' do
-    /foo.bar/m.match("foo\nbar").to_a.should == ["foo\nbar"]
-    /foo.bar/.match("foo\nbar").should be_nil
-  end
-  
-  it 'supports /x (extended syntax)' do
-    /\d +/x.match("abc123").to_a.should == ["123"] # Quantifiers can be separated from the expression they apply to
-  end
-  
-  it 'supports /o (once)' do
-    2.times do |i|
-      /#{i}/o.should == /0/
-    end
-  end
-  
-  it 'invokes substitutions for /o only once' do
-    ScratchPad.record []
-    to_s_callback = Proc.new do
-      ScratchPad << :to_s_callback
-      "class_with_to_s"
-    end
-    o = LanguageSpecs::ClassWith_to_s.new(to_s_callback)
-    2.times { /#{o}/o }
-    ScratchPad.recorded.should == [:to_s_callback]
-  end
- 
-  ruby_version_is "" ... "1.9" do 
-    it 'does not do thread synchronization for /o' do
-      ScratchPad.record []
-      
-      to_s_callback2 = Proc.new do
-        ScratchPad << :to_s_callback2
-        "class_with_to_s2"
-      end
-  
-      to_s_callback1 = Proc.new do
-        ScratchPad << :to_s_callback1
-        t2 = Thread.new do
-          o2 = LanguageSpecs::ClassWith_to_s.new(to_s_callback2)
-          ScratchPad << LanguageSpecs.get_regexp_with_substitution(o2)
-        end
-        t2.join
-        "class_with_to_s1"
-      end
-      
-      o1 = LanguageSpecs::ClassWith_to_s.new(to_s_callback1)
-      ScratchPad << LanguageSpecs.get_regexp_with_substitution(o1)
-  
-      ScratchPad.recorded.should == [:to_s_callback1, :to_s_callback2, /class_with_to_s2/, /class_with_to_s2/]
-    end
-  end
-  
-  it 'supports modifier combinations' do
-    /foo/imox.match("foo").to_a.should == ["foo"]
-    /foo/imoximox.match("foo").to_a.should == ["foo"]
-
-    lambda { eval('/foo/a') }.should raise_error(SyntaxError)
-  end
-  
-  #############################################################################
-  # Encodings
-  #############################################################################
-
-  not_compliant_on :ruby19, :macruby do
-    it 'supports /e (EUC encoding)' do
-      /./e.match("\303\251").to_a.should == ["\303\251"]
-    end
-    
-    it 'supports /n (Normal encoding)' do
-      /./n.match("\303\251").to_a.should == ["\303"]
-    end
-    
-    it 'supports /s (SJIS encoding)' do
-      /./s.match("\303\251").to_a.should == ["\303"]
-    end
-    
-    it 'supports /u (UTF8 encoding)' do
-      /./u.match("\303\251").to_a.should == ["\303\251"]
-    end
-    
-    it 'selects last of multiple encoding specifiers' do
-      /foo/ensuensuens.should == /foo/s
-    end
-  end
-
-  #############################################################################
-  # Back-refs
-  #############################################################################
-
-  it 'saves match data in the $~ pseudo-global variable' do
-    "hello" =~ /l+/
-    $~.to_a.should == ["ll"]
-  end
-
-  it 'saves captures in numbered $[1-9] variables' do
-    "1234567890" =~ /(1)(2)(3)(4)(5)(6)(7)(8)(9)(0)/
-    $~.to_a.should == ["1234567890", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
-    $1.should == "1"
-    $2.should == "2"
-    $3.should == "3"
-    $4.should == "4"
-    $5.should == "5"
-    $6.should == "6"
-    $7.should == "7"
-    $8.should == "8"
-    $9.should == "9"
-  end
-
-  it 'will not clobber capture variables across threads' do
-    cap1, cap2, cap3 = nil
-    "foo" =~ /(o+)/
-    cap1 = [$~.to_a, $1]
-    Thread.new do
-      cap2 = [$~.to_a, $1]
-      "bar" =~ /(a)/
-      cap3 = [$~.to_a, $1]
-    end.join
-    cap4 = [$~.to_a, $1]
-    cap1.should == [["oo", "oo"], "oo"]
-    cap2.should == [[], nil]
-    cap3.should == [["a", "a"], "a"]
-    cap4.should == [["oo", "oo"], "oo"]
-  end
 end
 
 language_version __FILE__, "regexp"

Modified: MacRuby/trunk/spec/frozen/language/rescue_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/rescue_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/language/rescue_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -68,5 +68,13 @@
       end
     end.should raise_error(OtherCustomException)
   end
-  
-end
\ No newline at end of file
+
+  ruby_version_is "1.9" do
+    it "parses  'a += b rescue c' as 'a += (b rescue c)'" do
+      a = 'a'
+      c = 'c'
+      a += b rescue c
+      a.should == 'ac'
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/language/versions/not_1.9.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/versions/not_1.9.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/language/versions/not_1.9.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,22 @@
+describe "not()" do
+  # not(arg).method and method(not(arg)) raise SyntaxErrors on 1.8. Here we
+  # use #inspect to test that the syntax works on 1.9
+
+  it "can be used as a function" do
+    lambda do
+      not(true).inspect
+    end.should_not raise_error(SyntaxError)
+  end
+
+  it "returns false if the argument is true" do
+    not(true).inspect.should == "false"
+  end
+
+  it "returns true if the argument is false" do
+    not(false).inspect.should == "true"
+  end
+
+  it "returns true if the argument is nil" do
+    not(false).inspect.should == "true"
+  end
+end

Modified: MacRuby/trunk/spec/frozen/language/versions/retry_1.8.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/versions/retry_1.8.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/language/versions/retry_1.8.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -6,7 +6,7 @@
   end
 
   # block retry has been officially deprecated by matz and is unsupported in 1.9
-  not_compliant_on :rubinius do
+  not_compliant_on :rubinius, :jruby do
     it "re-executes the entire enumeration" do
       list = []
       [1,2,3].each do |x|
@@ -17,4 +17,4 @@
       list.should == [1,2,3,1,2,3]
     end
   end
-end
\ No newline at end of file
+end

Modified: MacRuby/trunk/spec/frozen/language/versions/symbol_1.9.rb
===================================================================
--- MacRuby/trunk/spec/frozen/language/versions/symbol_1.9.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/language/versions/symbol_1.9.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -4,4 +4,12 @@
     c.class.should == Symbol
     c.inspect.should == ':""'
   end
-end
\ No newline at end of file
+
+  # These weren't allowed on 1.8
+  it "can be :!, :!=, or :!~" do
+    %w{'!', '!=', '!~'}.each do |sym|
+      lambda { sym.to_sym }.should_not raise_error(SyntaxError)
+      sym.to_sym.to_s.should == sym
+    end
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/enumerator/each_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/enumerator/each_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/enumerator/each_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,7 @@
+require File.dirname(__FILE__) + '/../../shared/enumerator/each'
+
+ruby_version_is "1.8.7"..."1.9" do
+  describe "Enumerator#each" do
+    it_behaves_like(:enum_each, :each)
+  end
+end

Added: MacRuby/trunk/spec/frozen/library/enumerator/each_with_index_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/enumerator/each_with_index_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/enumerator/each_with_index_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,9 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.8.7"..."1.9" do
+  require File.dirname(__FILE__) + '/../../shared/enumerator/with_index'
+
+  describe "Enumerator#each_with_index" do
+    it_behaves_like(:enum_with_index, :each_with_index)
+  end
+end

Modified: MacRuby/trunk/spec/frozen/library/enumerator/enum_cons_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/enumerator/enum_cons_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/library/enumerator/enum_cons_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,15 +1,10 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
-require File.dirname(__FILE__) + '/fixtures/classes'
-require 'enumerator'
 
-describe "Enumerator#enum_cons" do
-  ruby_version_is ''...'1.9' do
-    it "returns an enumerator of the receiver with iteration of each_cons for each array of n concecutive elements" do
-      a = []
-      enum = EnumSpecs::Numerous.new.enum_cons(3)
-      enum.each {|x| a << x}
-      enum.should be_kind_of(enumerator_class)
-      a.should == [[2, 5, 3], [5, 3, 6], [3, 6, 1], [6, 1, 4]]
-    end  
+ruby_version_is ""..."1.9" do
+  require 'enumerator'
+  require File.dirname(__FILE__) + '/../../shared/enumerator/enum_cons'
+  
+  describe "Enumerator#enum_cons" do
+    it_behaves_like(:enum_cons, :enum_cons)
   end
-end
\ No newline at end of file
+end

Modified: MacRuby/trunk/spec/frozen/library/enumerator/enum_for_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/enumerator/enum_for_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/library/enumerator/enum_for_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,6 +1,10 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
-require File.dirname(__FILE__) + '/shared/enum_for'
 
-describe "#enum_for" do
-  it_behaves_like :enumerator_enum_for, :enum_for
+ruby_version_is ""..."1.9" do
+  require 'enumerator'
+  require File.dirname(__FILE__) + '/../../shared/enumerator/enum_for'
+  
+  describe "#enum_for" do
+    it_behaves_like :enum_for, :enum_for
+  end
 end

Modified: MacRuby/trunk/spec/frozen/library/enumerator/enum_slice_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/enumerator/enum_slice_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/library/enumerator/enum_slice_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,10 +1,11 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
-require File.dirname(__FILE__) + '/fixtures/classes'
+require File.dirname(__FILE__) + '/../../fixtures/enumerator/classes'
+
+ruby_version_is ""..."1.9" do
 require 'enumerator'
-
-describe "Enumerator#enum_slice" do
-  ruby_version_is ''...'1.9' do
-    it "returns an enumerator of the receiver with iteration of each_slice for each slice of n elements" do
+  
+  describe "Enumerator#enum_slice" do
+    it "returns an enumerator of the receiver with iteration of each_slice for each slice of n elemts" do
       a = []
       enum = EnumSpecs::Numerous.new.enum_slice(4)
       enum.should be_kind_of(enumerator_class)
@@ -12,4 +13,4 @@
       a.should == [[2, 5, 3, 6], [1, 4]]
     end  
   end
-end
\ No newline at end of file
+end

Modified: MacRuby/trunk/spec/frozen/library/enumerator/enum_with_index_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/enumerator/enum_with_index_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/library/enumerator/enum_with_index_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,9 +1,10 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
-require File.dirname(__FILE__) + '/fixtures/classes'
-require 'enumerator'
 
-describe "Enumerator#enum_with_index" do
-  ruby_version_is ''...'1.9' do
+ruby_version_is ""..."1.9" do 
+  require File.dirname(__FILE__) + '/../../fixtures/enumerator/classes'
+  require 'enumerator'
+
+  describe "Enumerator#enum_with_index" do
     it "returns an enumerator of the receiver with an iteration of each_with_index" do
       a = []
       enum = EnumSpecs::Numerous.new.enum_with_index
@@ -12,4 +13,4 @@
       a.should == [[2, 0], [5, 1], [3, 2], [6, 3], [1, 4], [4, 5]]
     end
   end
-end
\ No newline at end of file
+end

Deleted: MacRuby/trunk/spec/frozen/library/enumerator/fixtures/classes.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/enumerator/fixtures/classes.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/library/enumerator/fixtures/classes.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,13 +0,0 @@
-module EnumSpecs
-  class Numerous
-    include Enumerable
-    
-    def initialize(*list)
-      @list = list.empty? ? [2, 5, 3, 6, 1, 4] : list
-    end
-    
-    def each
-      @list.each { |i| yield i }
-    end 
-  end
-end

Modified: MacRuby/trunk/spec/frozen/library/enumerator/new_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/enumerator/new_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/library/enumerator/new_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,64 +1,14 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
-require 'enumerator'
 
-describe "Enumerator.new" do
-  it "creates a new custom enumerator with the given object, iterator and arguments" do
-    enum = enumerator_class.new(1, :upto, 3)
-    enum.should be_kind_of(enumerator_class)
-  end
+ruby_version_is ""..."1.9" do
+  require 'enumerator'
+  require File.dirname(__FILE__) + '/../../shared/enumerator/new'
 
-  it "creates a new custom enumerator that responds to #each" do
-    enum = enumerator_class.new(1, :upto, 3)
-    enum.respond_to?(:each).should == true
-  end
-
-  it "creates a new custom enumerator that runs correctly" do
-    enumerator_class.new(1, :upto, 3).map{|x|x}.should == [1,2,3]
-  end
-  
-  it "aliases the second argument to :each" do
-    enumerator_class.new(1..2).to_a.should == enumerator_class.new(1..2, :each).to_a
-  end
-  
-  it "doesn't check for the presence of the iterator method" do
-    enumerator_class.new(nil).should be_kind_of(enumerator_class)
-  end
-
-  it "uses the latest define iterator method" do
-    class StrangeEach
-      def each
-        yield :foo
-      end
-    end
-    enum = enumerator_class.new(StrangeEach.new)
-    enum.to_a.should == [:foo]
-    class StrangeEach
-      def each
-        yield :bar
-      end
-    end
-    enum.to_a.should == [:bar]
-  end
-
-  ruby_version_is ''...'1.9' do
+  describe "Enumerator.new" do
     it "requires an argument" do
       lambda {enumerator_class.new}.should raise_error(ArgumentError)
     end
-  end
-  ruby_version_is '1.9' do
-    it "accepts a block" do
-      enum = enumerator_class.new do |yielder|
-        yielder.yield 3
-        yielder.yield 2
-        yielder.yield 1
-      end
-      enum.should be_kind_of(enumerator_class)
-      enum.to_a.should == [3,2,1]
-    end
 
-    it "ignores block if arg given" do
-      enum = enumerator_class.new([1,2,3]){|y| y.yield 4}
-      enum.to_a.should == [1,2,3]
-    end
-  end    
+    it_behaves_like(:enum_new, :new)
+  end
 end

Modified: MacRuby/trunk/spec/frozen/library/enumerator/next_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/enumerator/next_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/library/enumerator/next_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,28 +1,10 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
-require 'enumerator'
 
-describe "Enumerator#next" do
-
-  ruby_version_is "1.8.7" do  
-    before(:each) do
-      @enum = enumerator_class.new(1, :upto, 3)
-    end  
-
-    it "returns the next element of the enumeration" do
-      @enum.next.should == 1
-      @enum.next.should == 2
-      @enum.next.should == 3
-    end
-
-    it "raises a StopIteration exception at the end of the stream" do
-      3.times { @enum.next }
-      lambda { @enum.next }.should raise_error(StopIteration)
-    end
-
-    it "rewinds the enumerator after raising StopIteration" do
-      3.times { @enum.next }
-      lambda { @enum.next }.should raise_error(StopIteration)
-      @enum.next.should == 1
-    end
-  end    
+ruby_version_is "1.8.7"..."1.9" do  
+  require File.dirname(__FILE__) + '/../../shared/enumerator/next'
+  require 'enumerator'
+  
+  describe "Enumerator#next" do
+    it_behaves_like(:enum_next,:next)
+  end
 end

Modified: MacRuby/trunk/spec/frozen/library/enumerator/rewind_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/enumerator/rewind_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/library/enumerator/rewind_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,49 +1,10 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
-require 'enumerator'
 
-describe "Enumerator#rewind" do
+ruby_version_is "1.8.7"..."1.9" do  
+  require File.dirname(__FILE__) + '/../../shared/enumerator/rewind'
+  require 'enumerator'
 
-  ruby_version_is "1.8.7" do  
-    before(:each) do
-      @enum = enumerator_class.new(1, :upto, 3)
-    end  
-
-    it "resets the enumerator to its initial state" do
-      @enum.next.should == 1
-      @enum.next.should == 2
-      @enum.rewind
-      @enum.next.should == 1
-    end
-
-    it "returns self" do
-      @enum.rewind.should == @enum
-    end
-
-    it "has no effect on a new enumerator" do
-      @enum.rewind
-      @enum.next.should == 1
-    end
-
-    it "has no effect if called multiple, consecutive times" do
-      @enum.next.should == 1
-      @enum.rewind
-      @enum.rewind
-      @enum.next.should == 1
-    end
-    
-    ruby_version_is "1.9" do
-      it "calls the enclosed object's rewind method if one exists" do
-        obj = mock('rewinder')
-        enum = enumerator_class.new(obj, :enum) 
-        obj.should_receive(:rewind)
-        enum.rewind
-      end
-
-      it "does nothing if the object doesn't have a #rewind method" do
-        obj = mock('rewinder')
-        enum = enumerator_class.new(obj) 
-        lambda { enum.rewind.should == enum }.should_not raise_error
-      end
-    end
+  describe "Enumerator#rewind" do
+    it_behaves_like(:enum_rewind, :rewind)
   end    
 end

Deleted: MacRuby/trunk/spec/frozen/library/enumerator/shared/enum_for.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/enumerator/shared/enum_for.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/library/enumerator/shared/enum_for.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,16 +0,0 @@
-require 'enumerator'
-
-describe :enumerator_enum_for, :shared => true do
-  it "is defined in Kernel" do
-    Kernel.method_defined?(@method).should be_true
-  end
-
-  it "returns a new enumerator" do
-    "abc".send(@method).should be_kind_of(enumerator_class)
-  end
-
-  it "defaults the first argument to :each" do
-    enum = [1,2].send(@method)
-    enum.map { |v| v }.should == [1,2].each { |v| v }
-  end
-end

Modified: MacRuby/trunk/spec/frozen/library/enumerator/to_enum_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/enumerator/to_enum_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/library/enumerator/to_enum_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1,6 +1,10 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
-require File.dirname(__FILE__) + '/shared/enum_for'
 
-describe "#to_enum" do
-  it_behaves_like :enumerator_enum_for, :enum_for
+ruby_version_is ""..."1.9" do
+  require File.dirname(__FILE__) + '/../../shared/enumerator/enum_for'
+  require 'enumerator'
+
+  describe "#to_enum" do
+    it_behaves_like :enum_for, :enum_for
+  end
 end

Added: MacRuby/trunk/spec/frozen/library/enumerator/with_index_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/enumerator/with_index_spec.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/library/enumerator/with_index_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,9 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+ruby_version_is "1.8.7"..."1.9" do
+  require File.dirname(__FILE__) + '/../../shared/enumerator/with_index'
+
+  describe "Enumerator#with_index" do
+    it_behaves_like(:enum_with_index, :with_index)
+  end
+end

Modified: MacRuby/trunk/spec/frozen/library/tempfile/open_spec.rb
===================================================================
--- MacRuby/trunk/spec/frozen/library/tempfile/open_spec.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/library/tempfile/open_spec.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -53,3 +53,11 @@
     tempfile.closed?.should be_true
   end
 end
+
+ruby_version_is '1.8.7' .. '1.9' do
+  describe "Tempfile.open is passed an array [base,suffix] as first argument" do
+    tempfile = nil
+    Tempfile.open(["specs", ".tt"]) { |x| tempfile = x }
+    tempfile.path.should =~ /specs.*\.tt$/
+  end
+end

Modified: MacRuby/trunk/spec/frozen/shared/complex/divide.rb
===================================================================
--- MacRuby/trunk/spec/frozen/shared/complex/divide.rb	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/shared/complex/divide.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -37,19 +37,13 @@
     (Complex(15, 16) / 2.0).should be_close(Complex(7.5, 8), TOLERANCE)
   end
 
-  ruby_version_is ""..."1.9" do
-    it "returns Complex(Infinity, Infinity) when given zero" do
-      (Complex(20, 40) / 0.0).inspect.should == "Complex(Infinity, Infinity)"
-      (Complex(-20, -40) / 0.0).inspect.should == "Complex(-Infinity, -Infinity)"
-    end
+  it "returns Complex(Infinity, Infinity) when given zero" do
+    (Complex(20, 40) / 0.0).real.infinite?.should == 1
+    (Complex(20, 40) / 0.0).imag.infinite?.should == 1
+    (Complex(-20, 40) / 0.0).real.infinite?.should == -1
+    (Complex(-20, 40) / 0.0).imag.infinite?.should == 1
   end
 
-  ruby_version_is "1.9" do
-    it "raises a ZeroDivisionError when given 0.0" do
-      lambda { Complex(20, 40) / 0.0 }.should raise_error(ZeroDivisionError)
-      lambda { Complex(-20, -40) / 0.0 }.should raise_error(ZeroDivisionError)
-    end
-  end
 end
 
 describe :complex_divide_object, :shared => true do

Added: MacRuby/trunk/spec/frozen/shared/enumerator/each.rb
===================================================================
--- MacRuby/trunk/spec/frozen/shared/enumerator/each.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/shared/enumerator/each.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,45 @@
+describe :enum_each, :shared => true do
+  it "yields each element of self to the given block" do
+    acc = []
+    enumerator_class.new([1,2,3]).each {|e| acc << e }
+    acc.should == [1,2,3]
+  end
+
+  it "calls #each on the object given in the constructor by default" do
+    each = mock('each')
+    each.should_receive(:each)
+    enumerator_class.new(each).each {|e| e }
+  end
+
+  it "calls #each on the underlying object until it's exhausted" do
+    each = mock('each')
+    each.should_receive(:each).and_yield(1).and_yield(2).and_yield(3)
+    acc = []
+    enumerator_class.new(each).each {|e| acc << e }
+    acc.should == [1,2,3]
+  end
+
+  it "calls the method given in the constructor instead of #each" do
+    each = mock('peach')
+    each.should_receive(:peach)
+    enumerator_class.new(each, :peach).each {|e| e }
+  end
+
+  it "calls the method given in the constructor until it's exhausted" do
+    each = mock('each')
+    each.should_receive(:each).and_yield(1).and_yield(2).and_yield(3)
+    acc = []
+    enumerator_class.new(each).each {|e| acc << e }
+    acc.should == [1,2,3]
+  end
+
+  it "raises a NoMethodError if the object doesn't respond to #each" do
+    lambda do
+      enumerator_class.new(Object.new).each {|e| e }
+    end.should raise_error(NoMethodError)
+  end
+
+  it "returns an Enumerator if no block is given" do
+    enumerator_class.new([1]).each.should be_an_instance_of(enumerator_class)
+  end
+end

Added: MacRuby/trunk/spec/frozen/shared/enumerator/enum_cons.rb
===================================================================
--- MacRuby/trunk/spec/frozen/shared/enumerator/enum_cons.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/shared/enumerator/enum_cons.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,12 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/../../fixtures/enumerator/classes'
+
+describe :enum_cons, :shared => true do
+  it "returns an enumerator of the receiver with iteration of each_cons for each array of n concecutive elements" do
+    a = []
+    enum = EnumSpecs::Numerous.new.enum_cons(3)
+    enum.each {|x| a << x}
+    enum.should be_kind_of(enumerator_class)
+    a.should == [[2, 5, 3], [5, 3, 6], [3, 6, 1], [6, 1, 4]]
+  end
+end

Copied: MacRuby/trunk/spec/frozen/shared/enumerator/enum_for.rb (from rev 2411, MacRuby/trunk/spec/frozen/library/enumerator/shared/enum_for.rb)
===================================================================
--- MacRuby/trunk/spec/frozen/shared/enumerator/enum_for.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/shared/enumerator/enum_for.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,15 @@
+
+describe :enum_for, :shared => true do
+  it "is defined in Kernel" do
+    Kernel.method_defined?(@method).should be_true
+  end
+
+  it "returns a new enumerator" do
+    "abc".send(@method).should be_kind_of(enumerator_class)
+  end
+
+  it "defaults the first argument to :each" do
+    enum = [1,2].send(@method)
+    enum.map { |v| v }.should == [1,2].each { |v| v }
+  end
+end

Copied: MacRuby/trunk/spec/frozen/shared/enumerator/new.rb (from rev 2411, MacRuby/trunk/spec/frozen/library/enumerator/new_spec.rb)
===================================================================
--- MacRuby/trunk/spec/frozen/shared/enumerator/new.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/shared/enumerator/new.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,42 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe :enum_new, :shared => true do
+  it "creates a new custom enumerator with the given object, iterator and arguments" do
+    enum = enumerator_class.new(1, :upto, 3)
+    enum.should be_kind_of(enumerator_class)
+  end
+
+  it "creates a new custom enumerator that responds to #each" do
+    enum = enumerator_class.new(1, :upto, 3)
+    enum.respond_to?(:each).should == true
+  end
+
+  it "creates a new custom enumerator that runs correctly" do
+    enumerator_class.new(1, :upto, 3).map{|x|x}.should == [1,2,3]
+  end
+  
+  it "aliases the second argument to :each" do
+    enumerator_class.new(1..2).to_a.should == enumerator_class.new(1..2, :each).to_a
+  end
+  
+  it "doesn't check for the presence of the iterator method" do
+    enumerator_class.new(nil).should be_kind_of(enumerator_class)
+  end
+
+  it "uses the latest define iterator method" do
+    class StrangeEach
+      def each
+        yield :foo
+      end
+    end
+    enum = enumerator_class.new(StrangeEach.new)
+    enum.to_a.should == [:foo]
+    class StrangeEach
+      def each
+        yield :bar
+      end
+    end
+    enum.to_a.should == [:bar]
+  end
+
+end

Added: MacRuby/trunk/spec/frozen/shared/enumerator/next.rb
===================================================================
--- MacRuby/trunk/spec/frozen/shared/enumerator/next.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/shared/enumerator/next.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,25 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe :enum_next, :shared => true do
+
+  before(:each) do
+    @enum = enumerator_class.new(1, :upto, 3)
+  end  
+
+  it "returns the next element of the enumeration" do
+    @enum.next.should == 1
+    @enum.next.should == 2
+    @enum.next.should == 3
+  end
+
+  it "raises a StopIteration exception at the end of the stream" do
+    3.times { @enum.next }
+    lambda { @enum.next }.should raise_error(StopIteration)
+  end
+
+  it "rewinds the enumerator after raising StopIteration" do
+    3.times { @enum.next }
+    lambda { @enum.next }.should raise_error(StopIteration)
+    @enum.next.should == 1
+  end
+end

Added: MacRuby/trunk/spec/frozen/shared/enumerator/rewind.rb
===================================================================
--- MacRuby/trunk/spec/frozen/shared/enumerator/rewind.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/shared/enumerator/rewind.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,32 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe :enum_rewind, :shared => true do
+
+  before(:each) do
+    @enum = enumerator_class.new(1, :upto, 3)
+  end  
+
+  it "resets the enumerator to its initial state" do
+    @enum.next.should == 1
+    @enum.next.should == 2
+    @enum.rewind
+    @enum.next.should == 1
+  end
+
+  it "returns self" do
+    @enum.rewind.should == @enum
+  end
+
+  it "has no effect on a new enumerator" do
+    @enum.rewind
+    @enum.next.should == 1
+  end
+
+  it "has no effect if called multiple, consecutive times" do
+    @enum.next.should == 1
+    @enum.rewind
+    @enum.rewind
+    @enum.next.should == 1
+  end
+  
+end

Added: MacRuby/trunk/spec/frozen/shared/enumerator/with_index.rb
===================================================================
--- MacRuby/trunk/spec/frozen/shared/enumerator/with_index.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/shared/enumerator/with_index.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,35 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe :enum_with_index, :shared => true do
+
+  require File.dirname(__FILE__) + '/../../fixtures/enumerator/classes'
+  
+  before :each do
+    @enum = [1, 2, 3, 4].to_enum
+  end 
+  
+  it "passes each element and its index to block" do
+    @a = []
+    @enum.send(@method) { |o, i| @a << [o, i] }
+    @a.should == [[1, 0], [2, 1], [3, 2], [4, 3]]
+  end
+  
+  it "returns the object being enumerated when given a block" do
+    [1, 2, 3, 4].should == @enum.send(@method) { |o, i| :glark }
+  end
+
+  it "binds splat arguments properly" do
+    acc = []
+    @enum.send(@method) { |*b| c,d = b; acc << c; acc << d }
+    [1, 0, 2, 1, 3, 2, 4, 3].should == acc
+  end
+  
+  ruby_version_is '1.8.7' do
+    it "returns an enumerator if no block is supplied" do 
+      ewi = @enum.send(@method)
+      ewi.should be_kind_of(enumerator_class)
+      ewi.to_a.should == [[1, 0], [2, 1], [3, 2], [4, 3]]
+    end    
+  end
+  
+end

Added: MacRuby/trunk/spec/frozen/shared/file/world_readable.rb
===================================================================
--- MacRuby/trunk/spec/frozen/shared/file/world_readable.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/shared/file/world_readable.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,50 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe :file_world_readable, :shared => true do
+  
+  before(:each) do
+    @file = tmp('world-readable')
+    File.open(@file,'w') {|f| f.puts }
+  end
+  
+  after(:each) do
+    File.unlink(@file) if File.exists?(@file)
+  end
+
+  # These will surely fail on Windows.
+  it "returns nil if the file is chmod 600" do
+    File.chmod(0600, @file)
+    @object.world_readable?(@file).should be_nil
+  end
+
+  it "returns nil if the file is chmod 000" do
+    File.chmod(0000, @file)
+    @object.world_readable?(@file).should be_nil
+  end
+
+  it "returns nil if the file is chmod 700" do
+    File.chmod(0700, @file)
+    @object.world_readable?(@file).should be_nil
+  end
+
+  # We don't specify what the Fixnum is because it's system dependent
+  it "returns a Fixnum if the file is chmod 644" do
+    File.chmod(0644, @file)
+    @object.world_readable?(@file).should be_an_instance_of(Fixnum)
+  end
+
+  it "returns a Fixnum if the file is a directory and chmod 644" do
+    dir = rand().to_s + '-ww'
+    Dir.mkdir(dir)
+    Dir.exists?(dir).should be_true
+    File.chmod(0644, dir)
+    @object.world_readable?(dir).should be_an_instance_of(Fixnum)
+    Dir.rmdir(dir)
+  end
+
+  it "coerces the argument with #to_path" do
+    obj = mock('path')
+    obj.should_receive(:to_path).and_return(@file)
+    @object.world_readable?(obj)
+  end
+end

Added: MacRuby/trunk/spec/frozen/shared/file/world_writable.rb
===================================================================
--- MacRuby/trunk/spec/frozen/shared/file/world_writable.rb	                        (rev 0)
+++ MacRuby/trunk/spec/frozen/shared/file/world_writable.rb	2009-08-28 23:39:32 UTC (rev 2412)
@@ -0,0 +1,50 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe :file_world_writable, :shared => true do
+  
+  before(:each) do
+    @file = tmp('world-writable')
+    File.open(@file,'w') {|f| f.puts }
+  end
+  
+  after(:each) do
+    File.unlink(@file) if File.exists?(@file)
+  end
+
+  # These will surely fail on Windows.
+  it "returns nil if the file is chmod 600" do
+    File.chmod(0600, @file)
+    @object.world_writable?(@file).should be_nil
+  end
+
+  it "returns nil if the file is chmod 000" do
+    File.chmod(0000, @file)
+    @object.world_writable?(@file).should be_nil
+  end
+
+  it "returns nil if the file is chmod 700" do
+    File.chmod(0700, @file)
+    @object.world_writable?(@file).should be_nil
+  end
+
+  # We don't specify what the Fixnum is because it's system dependent
+  it "returns a Fixnum if the file is chmod 777" do
+    File.chmod(0777, @file)
+    @object.world_writable?(@file).should be_an_instance_of(Fixnum)
+  end
+
+  it "returns a Fixnum if the file is a directory and chmod 777" do
+    dir = rand().to_s + '-ww'
+    Dir.mkdir(dir)
+    Dir.exists?(dir).should be_true
+    File.chmod(0777, dir)
+    @object.world_writable?(dir).should be_an_instance_of(Fixnum)
+    Dir.rmdir(dir)
+  end
+
+  it "coerces the argument with #to_path" do
+    obj = mock('path')
+    obj.should_receive(:to_path).and_return(@file)
+    @object.world_writable?(obj)
+  end
+end

Modified: MacRuby/trunk/spec/frozen/upstream
===================================================================
--- MacRuby/trunk/spec/frozen/upstream	2009-08-28 23:29:06 UTC (rev 2411)
+++ MacRuby/trunk/spec/frozen/upstream	2009-08-28 23:39:32 UTC (rev 2412)
@@ -1 +1 @@
-f4a506d2e78447c34f1e1ac28b948a20532c8e67
\ No newline at end of file
+16a88a4e3061edfae4d74def378e97bf2533e825
\ No newline at end of file
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090828/e9631279/attachment-0001.html>


More information about the macruby-changes mailing list