opal 0.7.0.beta1 → 0.7.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitmodules +1 -1
  4. data/.inch.yml +19 -0
  5. data/.travis.yml +10 -7
  6. data/CHANGELOG.md +23 -0
  7. data/README.md +2 -2
  8. data/Rakefile +43 -1
  9. data/bin/opal +6 -1
  10. data/lib/mspec/opal/rake_task.rb +10 -31
  11. data/lib/mspec/opal/runner.rb +44 -1
  12. data/lib/mspec/opal/special_calls.rb +25 -0
  13. data/lib/opal/builder.rb +1 -1
  14. data/lib/opal/builder_processors.rb +4 -23
  15. data/lib/opal/cli.rb +17 -11
  16. data/lib/opal/cli_options.rb +1 -1
  17. data/lib/opal/cli_runners.rb +1 -0
  18. data/lib/opal/cli_runners/apple_script.rb +65 -0
  19. data/lib/opal/cli_runners/nodejs.rb +9 -3
  20. data/lib/opal/cli_runners/phantomjs.rb +2 -2
  21. data/lib/opal/cli_runners/server.rb +7 -5
  22. data/lib/opal/compiler.rb +1 -1
  23. data/lib/opal/nodes/call.rb +3 -2
  24. data/lib/opal/nodes/constants.rb +3 -3
  25. data/lib/opal/nodes/def.rb +7 -7
  26. data/lib/opal/nodes/defined.rb +2 -2
  27. data/lib/opal/nodes/definitions.rb +1 -1
  28. data/lib/opal/nodes/literal.rb +1 -1
  29. data/lib/opal/nodes/logic.rb +1 -1
  30. data/lib/opal/nodes/masgn.rb +1 -1
  31. data/lib/opal/nodes/module.rb +1 -1
  32. data/lib/opal/nodes/rescue.rb +1 -1
  33. data/lib/opal/nodes/scope.rb +1 -1
  34. data/lib/opal/nodes/super.rb +3 -3
  35. data/lib/opal/nodes/top.rb +11 -9
  36. data/lib/opal/nodes/variables.rb +39 -6
  37. data/lib/opal/nodes/yield.rb +3 -3
  38. data/lib/opal/parser.rb +3 -1
  39. data/lib/opal/parser/lexer.rb +8 -2
  40. data/lib/opal/paths.rb +13 -3
  41. data/lib/opal/sprockets/server.rb +1 -1
  42. data/lib/opal/version.rb +1 -1
  43. data/opal.gemspec +1 -1
  44. data/opal/corelib/array.rb +29 -20
  45. data/opal/corelib/array/inheritance.rb +3 -3
  46. data/opal/corelib/basic_object.rb +3 -1
  47. data/opal/corelib/class.rb +1 -1
  48. data/opal/corelib/comparable.rb +6 -5
  49. data/opal/corelib/dir.rb +4 -4
  50. data/opal/corelib/enumerable.rb +25 -25
  51. data/opal/corelib/enumerator.rb +16 -14
  52. data/opal/corelib/error.rb +13 -4
  53. data/opal/corelib/hash.rb +511 -162
  54. data/opal/corelib/helpers.rb +1 -1
  55. data/opal/corelib/kernel.rb +60 -44
  56. data/opal/corelib/match_data.rb +1 -10
  57. data/opal/corelib/method.rb +1 -1
  58. data/opal/corelib/module.rb +62 -32
  59. data/opal/corelib/nil_class.rb +1 -6
  60. data/opal/corelib/numeric.rb +6 -3
  61. data/opal/corelib/proc.rb +1 -1
  62. data/opal/corelib/regexp.rb +15 -6
  63. data/opal/corelib/runtime.js +57 -36
  64. data/opal/corelib/string.rb +38 -2
  65. data/opal/corelib/string/inheritance.rb +3 -3
  66. data/opal/corelib/struct.rb +1 -1
  67. data/opal/corelib/time.rb +46 -3
  68. data/spec/filters/bugs/date.rb +15 -0
  69. data/spec/filters/bugs/enumerator.rb +7 -0
  70. data/spec/filters/bugs/exception.rb +12 -0
  71. data/spec/filters/bugs/hash.rb +0 -18
  72. data/spec/filters/bugs/match_data.rb +13 -0
  73. data/spec/filters/bugs/module.rb +13 -0
  74. data/spec/filters/bugs/numeric.rb +2 -0
  75. data/spec/filters/bugs/regexp.rb +0 -2
  76. data/spec/filters/bugs/stringscanner.rb +8 -0
  77. data/spec/filters/bugs/time.rb +1 -1
  78. data/spec/filters/unsupported/float.rb +1 -0
  79. data/spec/filters/unsupported/symbols.rb +10 -0
  80. data/spec/filters/unsupported/tainted.rb +3 -0
  81. data/spec/filters/unsupported/trusted.rb +3 -0
  82. data/spec/lib/compiler_spec.rb +2 -2
  83. data/spec/lib/parser/call_spec.rb +7 -0
  84. data/spec/opal/core/date_spec.rb +49 -8
  85. data/spec/opal/core/exception_spec.rb +13 -0
  86. data/spec/opal/core/fixtures/require_tree_files/nested/nested 1.rb +1 -0
  87. data/spec/opal/core/fixtures/require_tree_files/nested/nested 2.rb +1 -0
  88. data/spec/opal/core/fixtures/require_tree_files/other/other 1.rb +1 -0
  89. data/spec/opal/core/kernel/require_tree_spec.rb +3 -1
  90. data/spec/opal/core/language/predefined_spec.rb +43 -0
  91. data/spec/opal/stdlib/promise/rescue_spec.rb +9 -0
  92. data/spec/opal/stdlib/promise/then_spec.rb +9 -0
  93. data/spec/opal/stdlib/promise/trace_spec.rb +9 -0
  94. data/spec/rubyspecs +40 -19
  95. data/spec/spec_helper.rb +10 -5
  96. data/stdlib/date.rb +68 -8
  97. data/stdlib/fileutils.rb +0 -0
  98. data/stdlib/iconv.rb +0 -0
  99. data/stdlib/json.rb +16 -3
  100. data/stdlib/native.rb +36 -17
  101. data/stdlib/nodejs.rb +3 -0
  102. data/stdlib/nodejs/dir.rb +1 -1
  103. data/stdlib/nodejs/file.rb +2 -2
  104. data/stdlib/nodejs/io.rb +1 -1
  105. data/stdlib/nodejs/process.rb +2 -2
  106. data/stdlib/nodejs/require.rb +5 -7
  107. data/stdlib/nodejs/runtime.rb +3 -2
  108. data/stdlib/pathname.rb +25 -1
  109. data/stdlib/promise.rb +16 -0
  110. data/stdlib/set.rb +48 -4
  111. data/stdlib/strscan.rb +12 -1
  112. data/stdlib/yaml.rb +1 -0
  113. metadata +27 -7
  114. data/spec/opal/core/language/symbol_spec.rb +0 -40
@@ -3,10 +3,10 @@ class String
3
3
  replace = Class.new(String::Wrapper)
4
4
 
5
5
  %x{
6
- klass.$$proto = replace.$$proto;
6
+ klass.$$proto = replace.$$proto;
7
7
  klass.$$proto.$$class = klass;
8
- klass.$$alloc = replace.$$alloc;
9
- klass.$$parent = #{String::Wrapper};
8
+ klass.$$alloc = replace.$$alloc;
9
+ klass.$$parent = #{String::Wrapper};
10
10
 
11
11
  klass.$allocate = replace.$allocate;
12
12
  klass.$new = replace.$new;
@@ -125,7 +125,7 @@ class Struct
125
125
  result = "#<struct "
126
126
 
127
127
  if self.class == Struct
128
- result += "#{self.class.name} "
128
+ result += "#{self.class} "
129
129
  end
130
130
 
131
131
  result += each_pair.map {|name, value|
@@ -326,7 +326,7 @@ class Time
326
326
 
327
327
  case 'C':
328
328
  zero = !blank;
329
- result += Match.round(#{year} / 100);
329
+ result += Math.round(#{year} / 100);
330
330
  break;
331
331
 
332
332
  case 'y':
@@ -455,8 +455,17 @@ class Time
455
455
  result += #{wday};
456
456
  break;
457
457
 
458
- // TODO: week year
459
- // TODO: week number
458
+ case 'V':
459
+ result += #{cweek_cyear[0].to_s.rjust(2, "0")};
460
+ break;
461
+
462
+ case 'G':
463
+ result += #{cweek_cyear[1]};
464
+ break;
465
+
466
+ case 'g':
467
+ result += #{cweek_cyear[1][-2..-1]};
468
+ break;
460
469
 
461
470
  case 's':
462
471
  result += #{to_i};
@@ -581,4 +590,38 @@ class Time
581
590
  }
582
591
  }
583
592
  end
593
+
594
+ private :cweek_cyear
595
+ def cweek_cyear
596
+ jan01 = Time.new(self.year, 1, 1)
597
+ jan01_wday = jan01.wday
598
+ first_monday = 0
599
+ year = self.year
600
+ if jan01_wday <= 4 && jan01_wday != 0
601
+ #Jan 01 is in the first week of the year
602
+ offset = jan01_wday-1
603
+ else
604
+ #Jan 01 is in the last week of the previous year
605
+ offset = jan01_wday-7-1
606
+ offset = -1 if offset == -8 #Adjust if Jan 01 is a Sunday
607
+ end
608
+
609
+ week = ((self.yday+offset)/7.00).ceil
610
+
611
+ if week <= 0
612
+ #Get the last week of the previous year
613
+ return Time.new(self.year-1, 12, 31).cweek_cyear
614
+ elsif week == 53
615
+ #Find out whether this is actually week 53 or already week 01 of the following year
616
+ dec31 = Time.new(self.year, 12, 31)
617
+ dec31_wday = dec31.wday
618
+ if dec31_wday <= 3 && dec31_wday != 0
619
+ week = 1
620
+ year += 1
621
+ end
622
+ end
623
+
624
+ [week, year]
625
+
626
+ end
584
627
  end
@@ -0,0 +1,15 @@
1
+ opal_filter "Date" do
2
+ fails "Date#<< raises an error on non numeric parameters"
3
+
4
+ fails "Date#strftime should be able to print the commercial year with leading zeroes"
5
+ fails "Date#strftime should be able to print the commercial year with only two digits"
6
+ fails "Date#strftime should be able to print the year day with leading zeroes"
7
+ fails "Date#strftime should be able to show a full notation"
8
+ fails "Date#strftime should be able to show the commercial week"
9
+ fails "Date#strftime should be able to show the timezone of the date with a : separator"
10
+ fails "Date#strftime should be able to show the timezone of the date with a : separator"
11
+ fails "Date#strftime should be able to show the commercial week"
12
+ fails "Date#strftime should be able to show the commercial week day"
13
+ fails "Date#strftime should be able to show the week number with the week starting on sunday and monday"
14
+ fails "Date#strftime should be able to show the number of seconds since the unix epoch"
15
+ end
@@ -1,3 +1,10 @@
1
1
  opal_filter "Enumerator" do
2
2
  fails "Enumerator#each requires multiple arguments" # arity issue
3
+
4
+ fails "Enumerator#with_index returns the object being enumerated when given a block"
5
+ fails "Enumerator#with_index numbers indices from the given index when given an offset but no block"
6
+ fails "Enumerator#with_index numbers indices from the given index when given an offset and block"
7
+ fails "Enumerator#with_index converts non-numeric arguments to Integer via #to_int"
8
+ fails "Enumerator#with_index coerces the given numeric argument to an Integer"
9
+ fails "Enumerator#with_index accepts negative argument"
3
10
  end
@@ -0,0 +1,12 @@
1
+ opal_filter "Exception" do
2
+ fails "Exception#message calls #to_s on self"
3
+
4
+ fails "Exception.new returns the exception when it has a custom constructor"
5
+
6
+ fails "Exception#to_s returns the self's name if no message is set"
7
+ fails "Exception#to_s calls #to_s on the message"
8
+
9
+ fails "Exception#inspect returns the class name when #to_s returns an empty string"
10
+ fails "Exception#inspect includes #to_s when the result is non-empty"
11
+ fails "Exception#inspect returns '#<Exception: Exception>' when no message given"
12
+ end
@@ -55,17 +55,11 @@ opal_filter "Hash" do
55
55
  fails "Hash#flatten recursively flattens Array values to the given depth"
56
56
  fails "Hash#flatten raises a TypeError if given a non-Integer argument"
57
57
 
58
- fails "Hash#has_key? compares keys with the same #hash value via #eql?"
59
- fails "Hash#has_key? returns true if argument is a key"
60
-
61
58
  fails "Hash#hash returns the same hash for recursive hashes through arrays"
62
59
  fails "Hash#hash returns the same hash for recursive hashes"
63
60
  fails "Hash#hash generates a hash for recursive hash structures"
64
61
  fails "Hash#hash returns a value which doesn't depend on the hash order"
65
62
 
66
- fails "Hash#include? compares keys with the same #hash value via #eql?"
67
- fails "Hash#include? returns true if argument is a key"
68
-
69
63
  fails "Hash#invert compares new keys with eql? semantics"
70
64
 
71
65
  fails "Hash#initialize_copy does not transfer default values"
@@ -73,14 +67,6 @@ opal_filter "Hash" do
73
67
  fails "Hash#initialize_copy tries to convert the passed argument to a hash using #to_hash"
74
68
  fails "Hash#initialize_copy replaces the contents of self with other"
75
69
 
76
- fails "Hash#inspect handles hashes with recursive values"
77
-
78
- fails "Hash#key? compares keys with the same #hash value via #eql?"
79
- fails "Hash#key? returns true if argument is a key"
80
-
81
- fails "Hash#member? compares keys with the same #hash value via #eql?"
82
- fails "Hash#member? returns true if argument is a key"
83
-
84
70
  fails "Hash#merge returns subclass instance for subclasses"
85
71
 
86
72
  fails "Hash.new raises an ArgumentError if more than one argument is passed"
@@ -113,10 +99,6 @@ opal_filter "Hash" do
113
99
  fails "Hash#sort works when some of the keys are themselves arrays"
114
100
  fails "Hash#sort uses block to sort array if passed a block"
115
101
 
116
- fails "Hash#to_h returns self for Hash instances"
117
-
118
- fails "Hash#to_s handles hashes with recursive values"
119
-
120
102
  fails "Hash.try_convert does not rescue exceptions raised by #to_hash"
121
103
  fails "Hash.try_convert sends #to_hash to the argument and raises TypeError if it's not a kind of Hash"
122
104
  fails "Hash.try_convert sends #to_hash to the argument and returns the result if it's a kind of Hash"
@@ -0,0 +1,13 @@
1
+ opal_filter "MatchData" do
2
+ fails "MatchData#regexp returns the pattern used in the match"
3
+ fails "MatchData#values_at when passed a Range returns an array of the matching value"
4
+
5
+ fails "MatchData#[Symbol] returns the corresponding named match when given a Symbol"
6
+ fails "MatchData#[Symbol] returns the corresponding named match when given a String"
7
+ fails "MatchData#[Symbol] returns the matching version of multiple corresponding named match"
8
+ fails "MatchData#[Symbol] returns the last match when multiple named matches exist with the same name"
9
+ fails "MatchData#[Symbol] returns nil on non-matching named matches"
10
+ fails "MatchData#[Symbol] raises an IndexError if there is no named match corresponding to the Symbol"
11
+ fails "MatchData#[Symbol] raises an IndexError if there is no named match corresponding to the String"
12
+ fails "MatchData#[Symbol] returns matches in the String's encoding"
13
+ end
@@ -11,4 +11,17 @@ opal_filter "Module" do
11
11
 
12
12
  fails "Module#const_defined? should not search parent scopes of classes and modules if inherit is false"
13
13
  fails "Module#const_get should not search parent scopes of classes and modules if inherit is false"
14
+
15
+ fails "Module#module_function as a toggle (no arguments) in a Module body functions normally if both toggle and definitions inside a eval"
16
+ fails "Module#module_function as a toggle (no arguments) in a Module body does not affect definitions when inside an eval even if the definitions are outside of it"
17
+
18
+ fails "Module#module_function is a private method"
19
+ fails "Module#module_function on Class raises a TypeError if calling after rebinded to Class"
20
+ fails "Module#module_function with specific method names makes the instance methods private"
21
+ fails "Module#module_function with specific method names makes the new Module methods public"
22
+ fails "Module#module_function with specific method names tries to convert the given names to strings using to_str"
23
+ fails "Module#module_function with specific method names raises a TypeError when the given names can't be converted to string using to_str"
24
+ fails "Module#module_function with specific method names can make accessible private methods"
25
+ fails "Module#module_function as a toggle (no arguments) in a Module body does not affect module_evaled method definitions also if outside the eval itself"
26
+ fails "Module#module_function as a toggle (no arguments) in a Module body has no effect if inside a module_eval if the definitions are outside of it"
14
27
  end
@@ -1,5 +1,7 @@
1
1
  opal_filter "Fixnum bugs" do
2
2
  fails "Integer#downto [stop] when self and stop are Fixnums raises an ArgumentError for invalid endpoints"
3
+ fails "Integer#upto [stop] when self and stop are Fixnums raises an ArgumentError for non-numeric endpoints"
4
+ fails "Integer#even? returns true when self is an even number"
3
5
 
4
6
  fails "Fixnum#to_s when no base given returns self converted to a String using base 10"
5
7
 
@@ -6,6 +6,4 @@ opal_filter "RegExp" do
6
6
  fails "Regexp#match matches the input at a given position"
7
7
  fails "Regexp#match with [string, position] when given a positive position matches the input at a given position"
8
8
  fails "Regexp#match with [string, position] when given a negative position matches the input at a given position"
9
- fails "MatchData#regexp returns the pattern used in the match"
10
- fails "MatchData#values_at when passed a Range returns an array of the matching value"
11
9
  end
@@ -19,4 +19,12 @@ opal_filter "StringScanner" do
19
19
 
20
20
  fails "StringScanner#pos= can poin position that greater than string length for multibyte string"
21
21
  fails "StringScanner#pos= positions from the end if the argument is negative for multibyte string"
22
+
23
+ fails "StringScanner#peek taints the returned String if the input was tainted"
24
+ fails "StringScanner#peek returns an instance of String when passed a String subclass"
25
+ fails "StringScanner#peek raises a RangeError when the passed argument is a Bignum"
26
+ fails "StringScanner#peek raises a ArgumentError when the passed argument is negative"
27
+
28
+ fails "StringScanner#rest taints the returned String if the input was tainted"
29
+ fails "StringScanner#rest returns an instance of String when passed a String subclass"
22
30
  end
@@ -173,5 +173,5 @@ opal_filter "Time" do
173
173
  # The following specs fail under certain TZ / DST conditions
174
174
  fails "Time.utc accepts various year ranges"
175
175
  fails "Time.gm accepts various year ranges"
176
-
176
+ fails "Time#yday returns an integer representing the day of the year, 1..366"
177
177
  end
@@ -2,4 +2,5 @@ opal_filter "Float" do
2
2
  fails "Array#inspect represents a recursive element with '[...]'"
3
3
  fails "Array#to_s represents a recursive element with '[...]'"
4
4
  fails "Array#eql? returns false if any corresponding elements are not #eql?"
5
+ fails "Set#eql? returns true when the passed argument is a Set and contains the same elements"
5
6
  end
@@ -0,0 +1,10 @@
1
+ # These specs fail because Opal does not have a separate Symbol class, and maps
2
+ # them to Strings. Symbol#inspect is expected to != String#inspect.
3
+ opal_filter "Symbols" do
4
+ fails "A Symbol literal is a ':' followed by any number of valid characters"
5
+ fails "A Symbol literal is a ':' followed by a single- or double-quoted string that may contain otherwise invalid characters"
6
+ fails "A Symbol literal is converted to a literal, unquoted representation if the symbol contains only valid characters"
7
+ fails "A Symbol literal can be created by the %s-delimited expression"
8
+ fails "A Symbol literal can contain null in the string"
9
+ fails "A Symbol literal can be an empty string"
10
+ end
@@ -152,4 +152,7 @@ opal_filter 'tainted' do
152
152
  fails "Enumerable#group_by returns a tainted hash if self is tainted"
153
153
 
154
154
  fails "Enumerable#to_a returns a tainted array if self is tainted"
155
+
156
+ fails "MatchData#post_match keeps taint status from the source string"
157
+ fails "MatchData#pre_match keeps taint status from the source string"
155
158
  end
@@ -77,4 +77,7 @@ opal_filter "Object#trusted/untrusted" do
77
77
  fails "String#gsub with pattern and Hash untrusts the result if the original string is untrusted"
78
78
  fails "String#gsub with pattern and Hash untrusts the result if a hash value is untrusted"
79
79
  fails "String#gsub with pattern and block untrusts the result if the original string or replacement is untrusted"
80
+
81
+ fails "MatchData#pre_match keeps untrusted status from the source string"
82
+ fails "MatchData#post_match keeps untrusted status from the source string"
80
83
  end
@@ -9,13 +9,13 @@ describe Opal::Compiler do
9
9
 
10
10
  describe 'requirable' do
11
11
  it 'executes the file' do
12
- expect_compiled("").to include('(function($opal) {')
12
+ expect_compiled("").to include('(function(Opal) {')
13
13
  expect_compiled("").to end_with("})(Opal);\n")
14
14
  end
15
15
 
16
16
  it 'puts the compiled into "Opal.modules"' do
17
17
  options = { :requirable => true, :file => "pippo" }
18
- expect_compiled("", options).to include('Opal.modules["pippo"] = function($opal) {')
18
+ expect_compiled("", options).to include('Opal.modules["pippo"] = function(Opal) {')
19
19
  expect_compiled("", options).to end_with("};\n")
20
20
  end
21
21
  end
@@ -137,3 +137,10 @@ describe "Command calls with operators" do
137
137
  end
138
138
  end
139
139
  end
140
+
141
+ describe "Command calls without a space" do
142
+ it "correctly parses symbol arguments" do
143
+ parsed("self.inject:+").should == [:call, [:self], :inject,
144
+ [:arglist, [:sym, :+]]]
145
+ end
146
+ end
@@ -84,14 +84,6 @@ describe Date do
84
84
  end
85
85
  end
86
86
 
87
- describe "#prev" do
88
- it "returns the previous date from self" do
89
- Date.new(2013, 3, 5).prev.should == Date.new(2013, 3, 4)
90
- Date.new(2013, 6, 1).prev.should == Date.new(2013, 5, 31)
91
- Date.new(2014, 1, 1).prev.should == Date.new(2013, 12, 31)
92
- end
93
- end
94
-
95
87
  describe "#prev_month" do
96
88
  it "returns the date with the previous calendar month" do
97
89
  Date.new(2013, 2, 9).prev_month.should == Date.new(2013, 1, 9)
@@ -100,6 +92,26 @@ describe Date do
100
92
  end
101
93
  end
102
94
 
95
+ describe '#next_day' do
96
+ it 'returns a new date the given number of days after self' do
97
+ Date.new(2014, 4, 5).next_day.should == Date.new(2014, 4, 6)
98
+ Date.new(2014, 4, 5).next_day(4).should == Date.new(2014, 4, 9)
99
+ end
100
+ end
101
+
102
+ describe '#prev_day' do
103
+ it 'returns the date the given number of days before self' do
104
+ Date.new(2014, 4, 5).prev_day.should == Date.new(2014, 4, 4)
105
+ Date.new(2014, 4, 5).prev_day(4).should == Date.new(2014, 4, 1)
106
+ end
107
+ end
108
+
109
+ describe '#succ' do
110
+ it 'returns the date after the receiver' do
111
+ Date.new(1986, 5, 26).succ.should == Date.new(1986, 5, 27)
112
+ end
113
+ end
114
+
103
115
  describe "#to_s" do
104
116
  it "returns an ISO 8601 representation" do
105
117
  Date.new(2013, 10, 15).to_s.should == "2013-10-15"
@@ -119,4 +131,33 @@ describe Date do
119
131
  Date.new(2013, 2, 9).year.should == 2013
120
132
  end
121
133
  end
134
+
135
+ it 'correctly reports mondays' do
136
+ Date.new(2015, 4, 6).monday?.should be_true
137
+ end
138
+
139
+ it 'correctly reports tuesdays' do
140
+ Date.new(2015, 4, 7).tuesday?.should be_true
141
+ end
142
+
143
+ it 'correctly reports wednesdays' do
144
+ Date.new(2015, 4, 8).wednesday?.should be_true
145
+ end
146
+
147
+ it 'correctly reports thursdays' do
148
+ Date.new(2015, 4, 9).thursday?.should be_true
149
+ end
150
+
151
+ it 'correctly reports fridays' do
152
+ Date.new(2015, 4, 10).friday?.should be_true
153
+ end
154
+
155
+ it 'correctly reports saturdays' do
156
+ Date.new(2015, 4, 11).saturday?.should be_true
157
+ end
158
+
159
+ it 'correctly reports sundays' do
160
+ Date.new(2015, 4, 12).sunday?.should be_true
161
+ end
162
+
122
163
  end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ class ExceptionSubclassTest < Exception
4
+ def custom_method
5
+ 42
6
+ end
7
+ end
8
+
9
+ describe "Exception" do
10
+ it "subclasses can have methods defined on them" do
11
+ ExceptionSubclassTest.new.custom_method.should == 42
12
+ end
13
+ end
@@ -0,0 +1 @@
1
+ $ScratchPad << File.basename(__FILE__)
@@ -0,0 +1 @@
1
+ $ScratchPad << File.basename(__FILE__)
@@ -0,0 +1 @@
1
+ $ScratchPad << File.basename(__FILE__)
@@ -2,6 +2,8 @@ describe 'Kernel.require_tree' do
2
2
  it 'loads all the files in a directory' do
3
3
  $ScratchPad = []
4
4
  require_tree '../fixtures/require_tree_files'
5
- $ScratchPad.sort.should == ['file 1', 'file 2', 'file 3', 'file 4', 'file 5']
5
+
6
+ $ScratchPad.sort.should == ['file 1', 'file 2', 'file 3', 'file 4', 'file 5',
7
+ 'nested 1', 'nested 2', 'other 1']
6
8
  end
7
9
  end
@@ -16,6 +16,49 @@ describe "predefined global $~" do
16
16
  /foo/ =~ 'bar'
17
17
  $~.nil?.should == true
18
18
  end
19
+
20
+ it "changes the value of derived capture globals when assigned" do
21
+ "foo" =~ /(f)oo/
22
+ foo_match = $~
23
+ "bar" =~ /(b)ar/
24
+ $~ = foo_match
25
+ $1.should == "f"
26
+ end
27
+ end
28
+
29
+ describe "Predefined global match $&" do
30
+ it "is equivalent to MatchData#[0] on the last match $~" do
31
+ /foo/ =~ 'barfoobaz'
32
+ $&.should == $~[0]
33
+ $&.should == 'foo'
34
+ end
35
+ end
36
+ describe "Predefined global $`" do
37
+ it "is equivalent to MatchData#pre_match on the last match $~" do
38
+ /foo/ =~ 'barfoobaz'
39
+ $`.should == $~.pre_match
40
+ $`.should == 'bar'
41
+ end
42
+ end
43
+
44
+ describe "Predefined global $'" do
45
+ it "is equivalent to MatchData#post_match on the last match $~" do
46
+ /foo/ =~ 'barfoobaz'
47
+ $'.should == $~.post_match
48
+ $'.should == 'baz'
49
+ end
50
+ end
51
+
52
+ describe "predefined globals $1..N" do
53
+ it "are equivalent to $~[N]" do
54
+ /(f)(o)(o)/ =~ 'foo'
55
+ $1.should == $~[1]
56
+ $2.should == $~[2]
57
+ $3.should == $~[3]
58
+ $4.should == $~[4]
59
+
60
+ [$1, $2, $3, $4].should == ['f', 'o', 'o', nil]
61
+ end
19
62
  end
20
63
 
21
64
  describe "predefined global $:" do