opal 0.3.41 → 0.3.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.md +14 -1
- data/Gemfile +2 -5
- data/Rakefile +41 -3
- data/bin/opal +33 -0
- data/lib/opal.rb +2 -12
- data/lib/opal/core_ext.rb +5 -0
- data/lib/opal/grammar.rb +2207 -2138
- data/lib/opal/grammar.y +21 -0
- data/lib/opal/grammar_helpers.rb +360 -0
- data/lib/opal/lexer.rb +55 -401
- data/lib/opal/lexer_scope.rb +28 -0
- data/lib/opal/parser.rb +155 -171
- data/lib/opal/target_scope.rb +257 -0
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +6 -2
- data/opal/opal-parser.js.erb +3 -2
- data/opal/opal.rb +20 -18
- data/opal/opal/array.rb +21 -12
- data/opal/opal/basic_object.rb +2 -1
- data/opal/opal/boolean.rb +3 -0
- data/opal/opal/browser_loader.js +57 -0
- data/opal/opal/class.rb +51 -13
- data/opal/opal/date.rb +1 -20
- data/opal/opal/enumerable.rb +66 -33
- data/opal/opal/error.rb +2 -0
- data/opal/opal/hash.rb +1 -1
- data/opal/opal/kernel.rb +14 -3
- data/opal/opal/nil_class.rb +4 -0
- data/opal/opal/proc.rb +9 -1
- data/opal/opal/racc.rb +2 -2
- data/opal/opal/regexp.rb +1 -1
- data/opal/opal/runtime.js +14 -4
- data/opal/opal/string.rb +21 -4
- data/opal/opal/time.rb +27 -0
- data/spec/core/array/allocate_spec.rb +7 -1
- data/spec/core/array/append_spec.rb +18 -3
- data/spec/core/array/array_spec.rb +7 -0
- data/spec/core/array/assoc_spec.rb +23 -8
- data/spec/core/array/at_spec.rb +23 -3
- data/spec/core/array/choice_spec.rb +20 -0
- data/spec/core/array/clear_spec.rb +45 -4
- data/spec/core/array/combination_spec.rb +55 -0
- data/spec/core/array/compact_spec.rb +72 -1
- data/spec/core/array/constructor_spec.rb +13 -2
- data/spec/core/array/count_spec.rb +15 -7
- data/spec/core/array/delete_at_spec.rb +44 -1
- data/spec/core/array/delete_if_spec.rb +52 -2
- data/spec/core/array/delete_spec.rb +83 -2
- data/spec/core/array/drop_spec.rb +24 -16
- data/spec/core/array/drop_while_spec.rb +17 -0
- data/spec/core/array/each_index_spec.rb +11 -1
- data/spec/core/array/each_spec.rb +20 -2
- data/spec/core/array/empty_spec.rb +4 -1
- data/spec/core/array/eql_spec.rb +14 -0
- data/spec/core/array/fetch_spec.rb +31 -2
- data/spec/core/array/find_index_spec.rb +8 -0
- data/spec/core/array/first_spec.rb +45 -8
- data/spec/core/array/fixtures/classes.rb +538 -0
- data/spec/core/array/flatten_spec.rb +200 -7
- data/spec/core/array/frozen_spec.rb +32 -0
- data/spec/core/array/include_spec.rb +16 -1
- data/spec/core/array/index_spec.rb +5 -25
- data/spec/core/array/insert_spec.rb +37 -3
- data/spec/core/array/inspect_spec.rb +6 -12
- data/spec/core/array/intersection_spec.rb +55 -4
- data/spec/core/array/join_spec.rb +29 -4
- data/spec/core/array/keep_if_spec.rb +13 -6
- data/spec/core/array/last_spec.rb +35 -1
- data/spec/core/array/length_spec.rb +7 -4
- data/spec/core/array/map_spec.rb +9 -47
- data/spec/core/array/minus_spec.rb +68 -4
- data/spec/core/array/multiply_spec.rb +138 -6
- data/spec/core/array/new_spec.rb +92 -3
- data/spec/core/array/ntimes_spec.rb +26 -0
- data/spec/core/array/plus_spec.rb +48 -2
- data/spec/core/array/pop_spec.rb +159 -39
- data/spec/core/array/push_spec.rb +29 -1
- data/spec/core/array/rassoc_spec.rb +31 -2
- data/spec/core/array/reject_spec.rb +89 -2
- data/spec/core/array/replace_spec.rb +7 -29
- data/spec/core/array/reverse_each_spec.rb +25 -1
- data/spec/core/array/reverse_spec.rb +53 -1
- data/spec/core/array/rindex_spec.rb +55 -5
- data/spec/core/array/select_spec.rb +35 -8
- data/spec/core/array/shared/collect.rb +0 -0
- data/spec/core/array/shared/enumeratorize.rb +12 -0
- data/spec/core/array/shared/eql.rb +95 -0
- data/spec/core/array/shared/index.rb +37 -0
- data/spec/core/array/shared/inspect.rb +3 -0
- data/spec/core/array/shared/join.rb +7 -0
- data/spec/core/array/shared/keep_if.rb +0 -0
- data/spec/core/array/shared/length.rb +0 -0
- data/spec/core/array/shared/replace.rb +0 -0
- data/spec/core/array/shared/slice.rb +0 -0
- data/spec/core/array/shift_spec.rb +132 -23
- data/spec/core/array/shuffle_spec.rb +82 -6
- data/spec/core/array/size_spec.rb +7 -4
- data/spec/core/array/slice_spec.rb +132 -1
- data/spec/core/array/sort_spec.rb +263 -14
- data/spec/core/array/take_spec.rb +24 -16
- data/spec/core/array/take_while_spec.rb +14 -10
- data/spec/core/array/to_a_spec.rb +18 -1
- data/spec/core/array/to_ary_spec.rb +15 -1
- data/spec/core/array/try_convert_spec.rb +39 -2
- data/spec/core/array/uniq_spec.rb +148 -3
- data/spec/core/array/unshift_spec.rb +36 -1
- data/spec/core/array/zip_spec.rb +36 -1
- data/spec/core/class/new_spec.rb +8 -6
- data/spec/core/enumerable/all_spec.rb +37 -9
- data/spec/core/enumerable/any_spec.rb +45 -7
- data/spec/core/enumerable/collect_spec.rb +4 -1
- data/spec/core/enumerable/count_spec.rb +4 -1
- data/spec/core/enumerable/detect_spec.rb +2 -2
- data/spec/core/enumerable/drop_spec.rb +4 -1
- data/spec/core/enumerable/drop_while_spec.rb +4 -1
- data/spec/core/enumerable/each_slice_spec.rb +2 -1
- data/spec/core/enumerable/each_with_index_spec.rb +4 -1
- data/spec/core/enumerable/each_with_object_spec.rb +4 -1
- data/spec/core/enumerable/entries_spec.rb +4 -1
- data/spec/core/enumerable/find_all_spec.rb +4 -1
- data/spec/core/enumerable/find_index_spec.rb +4 -1
- data/spec/core/enumerable/find_spec.rb +5 -2
- data/spec/core/enumerable/first_spec.rb +4 -1
- data/spec/core/enumerable/fixtures/classes.rb +198 -2
- data/spec/core/enumerable/grep_spec.rb +4 -1
- data/spec/core/enumerable/take_spec.rb +4 -1
- data/spec/core/enumerable/to_a_spec.rb +4 -1
- data/spec/core/false/and_spec.rb +11 -0
- data/spec/core/false/inspect_spec.rb +7 -0
- data/spec/core/false/or_spec.rb +11 -0
- data/spec/core/false/to_s_spec.rb +7 -0
- data/spec/core/false/xor_spec.rb +11 -0
- data/spec/core/kernel/rand_spec.rb +5 -5
- data/spec/core/module/const_get_spec.rb +4 -4
- data/spec/core/module/fixtures/classes.rb +434 -0
- data/spec/core/module/method_defined_spec.rb +49 -0
- data/spec/core/module/module_function_spec.rb +28 -0
- data/spec/core/nil/and_spec.rb +3 -1
- data/spec/core/nil/dup_spec.rb +7 -0
- data/spec/core/nil/inspect_spec.rb +3 -1
- data/spec/core/nil/nil_spec.rb +3 -1
- data/spec/core/nil/or_spec.rb +4 -2
- data/spec/core/nil/to_a_spec.rb +3 -1
- data/spec/core/nil/to_f_spec.rb +3 -1
- data/spec/core/nil/to_i_spec.rb +3 -1
- data/spec/core/nil/to_s_spec.rb +3 -1
- data/spec/core/nil/xor_spec.rb +4 -2
- data/spec/core/string/element_reference_spec.rb +14 -1
- data/spec/core/string/fixtures/classes.rb +0 -0
- data/spec/core/true/and_spec.rb +11 -0
- data/spec/core/true/inspect_spec.rb +7 -0
- data/spec/core/true/or_spec.rb +11 -0
- data/spec/core/true/to_s_spec.rb +7 -0
- data/spec/core/true/xor_spec.rb +11 -0
- data/spec/{core → core_ext}/array/element_reference_spec.rb +0 -0
- data/spec/{core → core_ext}/array/equal_value_spec.rb +0 -0
- data/spec/{core → core_ext}/array/fill_spec.rb +0 -0
- data/spec/{core → core_ext}/array/reduce_spec.rb +0 -0
- data/spec/core_ext/basic_object/send_spec.rb +3 -3
- data/spec/{core → core_ext}/boolean/singleton_class_spec.rb +0 -0
- data/spec/{core → core_ext}/boolean/to_json_spec.rb +0 -0
- data/spec/core_ext/class/_inherited_spec.rb +3 -3
- data/spec/core_ext/class/proc_methods_spec.rb +2 -2
- data/spec/core_ext/class/singleton_methods_spec.rb +8 -8
- data/spec/core_ext/method_missing_spec.rb +3 -3
- data/spec/core_ext/native/method_missing_spec.rb +3 -2
- data/spec/core_ext/native/to_native_spec.rb +3 -2
- data/spec/{core → core_ext}/nil/to_json_spec.rb +0 -0
- data/spec/date.rb +0 -0
- data/spec/fileutils.rb +0 -0
- data/spec/filters/ancestors.rb +4 -0
- data/spec/filters/array_delete.rb +3 -0
- data/spec/filters/array_fetch.rb +3 -0
- data/spec/filters/array_first.rb +3 -0
- data/spec/filters/array_flatten.rb +14 -0
- data/spec/filters/array_intersection.rb +5 -0
- data/spec/filters/array_join.rb +6 -0
- data/spec/filters/array_subclasses.rb +4 -0
- data/spec/filters/block_args.rb +3 -0
- data/spec/filters/coerce_integer.rb +9 -0
- data/spec/filters/frozen.rb +4 -0
- data/spec/filters/mocks.rb +3 -0
- data/spec/filters/should_receive.rb +4 -0
- data/spec/filters/tainted.rb +7 -0
- data/spec/fixtures/class.rb +124 -0
- data/spec/fixtures/class_variables.rb +0 -0
- data/spec/fixtures/constants.rb +0 -0
- data/spec/grammar/alias_spec.rb +1 -1
- data/spec/grammar/def_spec.rb +1 -0
- data/spec/grammar/lvar_spec.rb +1 -2
- data/spec/grammar/nth_ref_spec.rb +13 -0
- data/spec/grammar/sclass_spec.rb +6 -7
- data/spec/grammar/str_spec.rb +4 -4
- data/spec/grammar/string_spec.rb +8 -0
- data/spec/grammar/xstr_spec.rb +4 -4
- data/spec/iconv.rb +0 -0
- data/spec/language/alias_spec.rb +140 -3
- data/spec/language/and_spec.rb +14 -7
- data/spec/language/array_spec.rb +57 -5
- data/spec/language/block_spec.rb +466 -49
- data/spec/language/break_spec.rb +294 -44
- data/spec/language/case_spec.rb +151 -3
- data/spec/language/class_spec.rb +196 -0
- data/spec/language/class_variable_spec.rb +56 -0
- data/spec/language/def_spec.rb +507 -4
- data/spec/language/defined_spec.rb +19 -7
- data/spec/language/ensure_spec.rb +26 -39
- data/spec/language/execution_spec.rb +15 -0
- data/spec/language/fixtures/array.rb +11 -0
- data/spec/language/fixtures/block.rb +57 -0
- data/spec/language/fixtures/break.rb +240 -0
- data/spec/language/fixtures/ensure.rb +72 -0
- data/spec/language/fixtures/literal_lambda.rb +7 -0
- data/spec/language/fixtures/metaclass.rb +33 -0
- data/spec/language/fixtures/module.rb +24 -0
- data/spec/language/fixtures/next.rb +78 -12
- data/spec/language/fixtures/return.rb +118 -0
- data/spec/language/fixtures/send.rb +110 -0
- data/spec/language/fixtures/send_1.9.rb +22 -0
- data/spec/language/fixtures/super.rb +308 -0
- data/spec/language/fixtures/variables.rb +58 -0
- data/spec/language/fixtures/yield.rb +5 -0
- data/spec/language/for_spec.rb +192 -0
- data/spec/language/hash_spec.rb +29 -5
- data/spec/language/if_spec.rb +90 -9
- data/spec/language/literal_lambda_spec.rb +1 -47
- data/spec/language/loop_spec.rb +39 -2
- data/spec/language/metaclass_spec.rb +151 -5
- data/spec/language/module_spec.rb +56 -0
- data/spec/language/next_spec.rb +370 -12
- data/spec/language/not_spec.rb +55 -0
- data/spec/language/numbers_spec.rb +56 -0
- data/spec/language/or_spec.rb +31 -3
- data/spec/language/order_spec.rb +79 -0
- data/spec/language/precedence_spec.rb +483 -0
- data/spec/language/proc_spec.rb +249 -21
- data/spec/language/redo_spec.rb +67 -0
- data/spec/language/rescue_spec.rb +121 -0
- data/spec/language/retry_spec.rb +56 -0
- data/spec/language/return_spec.rb +281 -0
- data/spec/language/send_spec.rb +141 -48
- data/spec/language/singleton_class_spec.rb +1 -1
- data/spec/language/string_spec.rb +11 -0
- data/spec/language/super_spec.rb +213 -133
- data/spec/language/symbol_spec.rb +2 -1
- data/spec/language/undef_spec.rb +3 -1
- data/spec/language/unless_spec.rb +6 -2
- data/spec/language/until_spec.rb +102 -3
- data/spec/language/variables_spec.rb +1212 -16
- data/spec/language/versions/array_1.9.rb +39 -0
- data/spec/language/versions/case_1.9.rb +20 -0
- data/spec/language/versions/hash_1.9.rb +18 -0
- data/spec/language/versions/literal_lambda_1.9.rb +143 -0
- data/spec/language/versions/not_1.9.rb +22 -0
- data/spec/language/versions/send_1.9.rb +241 -0
- data/spec/language/versions/symbol_1.9.rb +15 -0
- data/spec/language/versions/variables_1.9.rb +8 -0
- data/spec/language/while_spec.rb +70 -5
- data/spec/language/yield_spec.rb +32 -6
- data/spec/mspec/guards/block_device.rb +0 -0
- data/spec/mspec/guards/endian.rb +0 -0
- data/spec/mspec/helpers/environment.rb +0 -0
- data/spec/mspec/helpers/language_version.rb +0 -0
- data/spec/mspec/helpers/tmp.rb +0 -0
- data/spec/ospec/filter.rb +32 -0
- data/spec/ospec/main.rb.erb +18 -0
- data/spec/ospec/phantom.rb +97 -0
- data/spec/ospec/runner.rb +95 -0
- data/spec/ospec/sprockets.js +40 -0
- data/spec/pp.rb +3 -0
- data/spec/rbconfig.rb +5 -0
- data/spec/spec_helper.rb +53 -26
- data/spec/yaml.rb +0 -0
- metadata +275 -31
- data/config.ru +0 -8
- data/lib/opal/processor.rb +0 -47
- data/lib/opal/scope.rb +0 -236
- data/lib/opal/server.rb +0 -94
- data/spec/core/boolean/and_spec.rb +0 -17
- data/spec/core/boolean/inspect_spec.rb +0 -9
- data/spec/core/boolean/or_spec.rb +0 -17
- data/spec/core/boolean/to_s_spec.rb +0 -9
- data/spec/core/boolean/xor_spec.rb +0 -17
data/spec/language/break_spec.rb
CHANGED
@@ -1,68 +1,204 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
def initialize(ensures=false)
|
4
|
-
@ensures = ensures
|
5
|
-
end
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require File.expand_path('../fixtures/break', __FILE__)
|
6
3
|
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
describe "The break statement in a block" do
|
5
|
+
before :each do
|
6
|
+
ScratchPad.record []
|
7
|
+
@program = BreakSpecs::Block.new
|
10
8
|
end
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
10
|
+
it "returns nil to method invoking the method yielding to the block when not passed an argument" do
|
11
|
+
@program.break_nil
|
12
|
+
ScratchPad.recorded.should == [:a, :aa, :b, nil, :d]
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns a value to the method invoking the method yielding to the block" do
|
16
|
+
@program.break_value
|
17
|
+
ScratchPad.recorded.should == [:a, :aa, :b, :break, :d]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "The break statement in a captured block" do
|
22
|
+
before :each do
|
23
|
+
ScratchPad.record []
|
24
|
+
@program = BreakSpecs::Block.new
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "when the invocation of the scope creating the block is still active" do
|
28
|
+
pending do
|
29
|
+
deviates_on :rubinius do
|
30
|
+
it "returns a value to the invoking scope when invoking the block from the scope creating the block" do
|
31
|
+
@program.break_in_method
|
32
|
+
ScratchPad.recorded.should == [:a, :xa, :d, :b, :break, :e]
|
33
|
+
end
|
34
|
+
|
35
|
+
it "returns a value to the scope invoking the method when invoking the block from a method" do
|
36
|
+
@program.break_in_nested_method
|
37
|
+
ScratchPad.recorded.should == [:a, :xa, :c, :aa, :b, :break, :d]
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns a value to the scope calling the yielding scope when yielding to the block" do
|
41
|
+
@program.break_in_yielding_method
|
42
|
+
ScratchPad.recorded.should == [:a, :xa, :c, :aa, :b, :break, :d]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
not_compliant_on :rubinius do
|
47
|
+
it "raises a LocalJumpError when invoking the block from the scope creating the block" do
|
48
|
+
lambda { @program.break_in_method }.should raise_error(LocalJumpError)
|
49
|
+
ScratchPad.recorded.should == [:a, :xa, :d, :b]
|
50
|
+
end
|
51
|
+
|
52
|
+
it "raises a LocalJumpError when invoking the block from a method" do
|
53
|
+
lambda { @program.break_in_nested_method }.should raise_error(LocalJumpError)
|
54
|
+
ScratchPad.recorded.should == [:a, :xa, :c, :aa, :b]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "raises a LocalJumpError when yielding to the block" do
|
58
|
+
lambda { @program.break_in_yielding_method }.should raise_error(LocalJumpError)
|
59
|
+
ScratchPad.recorded.should == [:a, :xa, :c, :aa, :b]
|
60
|
+
end
|
61
|
+
end
|
21
62
|
end
|
63
|
+
end
|
22
64
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
break :break
|
28
|
-
note :c
|
29
|
-
}
|
30
|
-
note :d
|
65
|
+
describe "from a scope that has returned" do
|
66
|
+
pending "raises a LocalJumpError when calling the block from a method" do
|
67
|
+
lambda { @program.break_in_method_captured }.should raise_error(LocalJumpError)
|
68
|
+
ScratchPad.recorded.should == [:a, :za, :xa, :zd, :zb]
|
31
69
|
end
|
32
70
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
note :bb
|
71
|
+
pending "raises a LocalJumpError when yielding to the block" do
|
72
|
+
lambda { @program.break_in_yield_captured }.should raise_error(LocalJumpError)
|
73
|
+
ScratchPad.recorded.should == [:a, :za, :xa, :zd, :aa, :zb]
|
37
74
|
end
|
38
75
|
end
|
39
76
|
end
|
40
77
|
|
41
|
-
describe "The break statement in a
|
78
|
+
describe "The break statement in a lambda" do
|
42
79
|
before :each do
|
43
80
|
ScratchPad.record []
|
44
|
-
@program = BreakSpecs::
|
81
|
+
@program = BreakSpecs::Lambda.new
|
45
82
|
end
|
46
83
|
|
47
|
-
|
48
|
-
|
49
|
-
|
84
|
+
describe "when the invocation of the scope creating the lambda is still active" do
|
85
|
+
pending "returns nil when not passed an argument" do
|
86
|
+
@program.break_in_defining_scope false
|
87
|
+
ScratchPad.recorded.should == [:a, :b, nil, :d]
|
88
|
+
end
|
89
|
+
|
90
|
+
pending "returns a value to the scope creating and calling the lambda" do
|
91
|
+
@program.break_in_defining_scope
|
92
|
+
ScratchPad.recorded.should == [:a, :b, :break, :d]
|
93
|
+
end
|
94
|
+
|
95
|
+
pending "returns a value to the method scope below invoking the lambda" do
|
96
|
+
@program.break_in_nested_scope
|
97
|
+
ScratchPad.recorded.should == [:a, :d, :aa, :b, :break, :bb, :e]
|
98
|
+
end
|
99
|
+
|
100
|
+
pending "returns a value to a block scope invoking the lambda in a method below" do
|
101
|
+
@program.break_in_nested_scope_block
|
102
|
+
ScratchPad.recorded.should == [:a, :d, :aa, :aaa, :bb, :b, :break, :cc, :bbb, :dd, :e]
|
103
|
+
end
|
104
|
+
|
105
|
+
pending do
|
106
|
+
deviates_on :rubinius do
|
107
|
+
it "returns a value when yielding to a lambda passed as a block argument" do
|
108
|
+
@program.break_in_nested_scope_yield
|
109
|
+
ScratchPad.recorded.should == [:a, :d, :aaa, :b, :break, :e]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
not_compliant_on :rubinius do
|
114
|
+
it "raises a LocalJumpError when yielding to a lambda passed as a block argument" do
|
115
|
+
lambda { @program.break_in_nested_scope_yield }.should raise_error(LocalJumpError)
|
116
|
+
ScratchPad.recorded.should == [:a, :d, :aaa, :b]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
50
120
|
end
|
51
121
|
|
52
|
-
|
53
|
-
|
54
|
-
|
122
|
+
describe "created at the toplevel" do
|
123
|
+
pending "returns a value when invoking from the toplevel" do
|
124
|
+
code = fixture __FILE__, "break_lambda_toplevel.rb"
|
125
|
+
ruby_exe(code).chomp.should == "a,b,break,d"
|
126
|
+
end
|
127
|
+
|
128
|
+
pending "returns a value when invoking from a method" do
|
129
|
+
code = fixture __FILE__, "break_lambda_toplevel_method.rb"
|
130
|
+
ruby_exe(code).chomp.should == "a,d,b,break,e,f"
|
131
|
+
end
|
132
|
+
|
133
|
+
pending "returns a value when invoking from a block" do
|
134
|
+
code = fixture __FILE__, "break_lambda_toplevel_block.rb"
|
135
|
+
ruby_exe(code).chomp.should == "a,d,f,b,break,g,e,h"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe "from a scope that has returned" do
|
140
|
+
pending "returns a value to the method scope invoking the lambda" do
|
141
|
+
@program.break_in_method
|
142
|
+
ScratchPad.recorded.should == [:a, :la, :ld, :lb, :break, :b]
|
143
|
+
end
|
144
|
+
|
145
|
+
pending "returns a value to the block scope invoking the lambda in a method" do
|
146
|
+
@program.break_in_block_in_method
|
147
|
+
ScratchPad.recorded.should == [:a, :aaa, :b, :la, :ld, :lb, :break, :c, :bbb, :d]
|
148
|
+
end
|
149
|
+
|
150
|
+
# By passing a lambda as a block argument, the user is requesting to treat
|
151
|
+
# the lambda as a block, which in this case means breaking to a scope that
|
152
|
+
# has returned. This is a subtle and confusing semantic where a block pass
|
153
|
+
# is removing the lambda-ness of a lambda.
|
154
|
+
pending "raises a LocalJumpError when yielding to a lambda passed as a block argument" do
|
155
|
+
lambda { @program.break_in_method_yield }.should raise_error(LocalJumpError)
|
156
|
+
ScratchPad.recorded.should == [:a, :la, :ld, :aaa, :lb]
|
157
|
+
end
|
55
158
|
end
|
56
159
|
end
|
57
160
|
|
58
161
|
describe "Break inside a while loop" do
|
59
162
|
describe "with a value" do
|
60
|
-
it "
|
61
|
-
a = while true; break; end;
|
62
|
-
a = while true; break nil; end;
|
63
|
-
a = while true; break 1; end;
|
64
|
-
a = while true; break []; end;
|
65
|
-
a = while true; break [1]; end;
|
163
|
+
it "exits the loop and returns the value" do
|
164
|
+
a = while true; break; end; a.should == nil
|
165
|
+
a = while true; break nil; end; a.should == nil
|
166
|
+
a = while true; break 1; end; a.should == 1
|
167
|
+
a = while true; break []; end; a.should == []
|
168
|
+
a = while true; break [1]; end; a.should == [1]
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "with a splat" do
|
173
|
+
it "exits the loop and makes the splat an Array" do
|
174
|
+
a = while true; break *[1,2]; end; a.should == [1,2]
|
175
|
+
end
|
176
|
+
|
177
|
+
ruby_version_is "" ... "1.9" do
|
178
|
+
it "unwraps the value if there is only one value" do
|
179
|
+
a = while true; break *1; end; a.should == 1
|
180
|
+
end
|
181
|
+
|
182
|
+
it "makes the value nil if the splat is empty" do
|
183
|
+
a = while true; break *[]; end; a.should == nil
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
ruby_version_is "1.9" do
|
188
|
+
it "treats nil as an empty array" do
|
189
|
+
a = while true; break *nil; end; a.should == []
|
190
|
+
end
|
191
|
+
|
192
|
+
it "preserves an array as is" do
|
193
|
+
a = while true; break *[]; end; a.should == []
|
194
|
+
a = while true; break *[1,2]; end; a.should == [1,2]
|
195
|
+
a = while true; break *[nil]; end; a.should == [nil]
|
196
|
+
a = while true; break *[[]]; end; a.should == [[]]
|
197
|
+
end
|
198
|
+
|
199
|
+
it "wraps a non-Array in an Array" do
|
200
|
+
a = while true; break *1; end; a.should == [1]
|
201
|
+
end
|
66
202
|
end
|
67
203
|
end
|
68
204
|
|
@@ -83,4 +219,118 @@ describe "Break inside a while loop" do
|
|
83
219
|
end.should == 2
|
84
220
|
at.should == 2
|
85
221
|
end
|
86
|
-
end
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
# TODO: Rewrite all the specs from here to the end of the file in the style
|
226
|
+
# above.
|
227
|
+
describe "Executing break from within a block" do
|
228
|
+
|
229
|
+
before :each do
|
230
|
+
ScratchPad.clear
|
231
|
+
end
|
232
|
+
|
233
|
+
# Discovered in JRuby (see JRUBY-2756)
|
234
|
+
pending "returns from the original invoking method even in case of chained calls" do
|
235
|
+
class BreakTest
|
236
|
+
# case #1: yield
|
237
|
+
def self.meth_with_yield(&b)
|
238
|
+
yield
|
239
|
+
fail("break returned from yield to wrong place")
|
240
|
+
end
|
241
|
+
def self.invoking_method(&b)
|
242
|
+
meth_with_yield(&b)
|
243
|
+
fail("break returned from 'meth_with_yield' method to wrong place")
|
244
|
+
end
|
245
|
+
|
246
|
+
# case #2: block.call
|
247
|
+
def self.meth_with_block_call(&b)
|
248
|
+
b.call
|
249
|
+
fail("break returned from b.call to wrong place")
|
250
|
+
end
|
251
|
+
def self.invoking_method2(&b)
|
252
|
+
meth_with_block_call(&b)
|
253
|
+
fail("break returned from 'meth_with_block_call' method to wrong place")
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# this calls a method that calls another method that yields to the block
|
258
|
+
BreakTest.invoking_method do
|
259
|
+
break
|
260
|
+
fail("break didn't, well, break")
|
261
|
+
end
|
262
|
+
|
263
|
+
# this calls a method that calls another method that calls the block
|
264
|
+
BreakTest.invoking_method2 do
|
265
|
+
break
|
266
|
+
fail("break didn't, well, break")
|
267
|
+
end
|
268
|
+
|
269
|
+
res = BreakTest.invoking_method do
|
270
|
+
break :return_value
|
271
|
+
fail("break didn't, well, break")
|
272
|
+
end
|
273
|
+
res.should == :return_value
|
274
|
+
|
275
|
+
res = BreakTest.invoking_method2 do
|
276
|
+
break :return_value
|
277
|
+
fail("break didn't, well, break")
|
278
|
+
end
|
279
|
+
res.should == :return_value
|
280
|
+
|
281
|
+
end
|
282
|
+
|
283
|
+
class BreakTest2
|
284
|
+
def one
|
285
|
+
two { yield }
|
286
|
+
end
|
287
|
+
|
288
|
+
def two
|
289
|
+
yield
|
290
|
+
ensure
|
291
|
+
ScratchPad << :two_ensure
|
292
|
+
end
|
293
|
+
|
294
|
+
def three
|
295
|
+
begin
|
296
|
+
one { break }
|
297
|
+
ScratchPad << :three_post
|
298
|
+
ensure
|
299
|
+
ScratchPad << :three_ensure
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
pending "runs ensures when continuing upward" do
|
305
|
+
ScratchPad.record []
|
306
|
+
|
307
|
+
bt2 = BreakTest2.new
|
308
|
+
bt2.one { break }
|
309
|
+
ScratchPad.recorded.should == [:two_ensure]
|
310
|
+
end
|
311
|
+
|
312
|
+
it "runs ensures when breaking from a loop" do
|
313
|
+
ScratchPad.record []
|
314
|
+
|
315
|
+
while true
|
316
|
+
begin
|
317
|
+
ScratchPad << :begin
|
318
|
+
break if true
|
319
|
+
ensure
|
320
|
+
ScratchPad << :ensure
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
ScratchPad.recorded.should == [:begin, :ensure]
|
325
|
+
end
|
326
|
+
|
327
|
+
pending "doesn't run ensures in the destination method" do
|
328
|
+
ScratchPad.record []
|
329
|
+
|
330
|
+
bt2 = BreakTest2.new
|
331
|
+
bt2.three
|
332
|
+
ScratchPad.recorded.should == [:two_ensure, :three_post, :three_ensure]
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
# language_version __FILE__, "break"
|
data/spec/language/case_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
1
3
|
describe "The 'case'-construct" do
|
2
4
|
it "evaluates the body of the when clause matching the case target expression" do
|
3
5
|
case 1
|
@@ -127,7 +129,7 @@ describe "The 'case'-construct" do
|
|
127
129
|
|
128
130
|
it "takes an expanded array in addition to a list of values" do
|
129
131
|
case 'f'
|
130
|
-
when 'f', *['a',
|
132
|
+
when 'f', *['a', 'b', 'c', 'd']
|
131
133
|
"foo"
|
132
134
|
when *['x', 'y', 'z']
|
133
135
|
"bar"
|
@@ -141,6 +143,7 @@ describe "The 'case'-construct" do
|
|
141
143
|
end.should == "foo"
|
142
144
|
end
|
143
145
|
|
146
|
+
# MR: critical
|
144
147
|
it "concats arrays before expanding them" do
|
145
148
|
a = ['a', 'b', 'c', 'd']
|
146
149
|
b = ['f']
|
@@ -153,10 +156,155 @@ describe "The 'case'-construct" do
|
|
153
156
|
end.should == "foo"
|
154
157
|
end
|
155
158
|
|
156
|
-
it "never
|
159
|
+
it "never matches when clauses with no values" do
|
157
160
|
case nil
|
158
161
|
when *[]
|
159
162
|
"foo"
|
160
163
|
end.should == nil
|
161
164
|
end
|
162
|
-
|
165
|
+
|
166
|
+
pending "lets you define a method after the case statement" do
|
167
|
+
case (def foo; 'foo'; end; 'f')
|
168
|
+
when 'a'
|
169
|
+
'foo'
|
170
|
+
when 'f'
|
171
|
+
'bar'
|
172
|
+
end.should == 'bar'
|
173
|
+
end
|
174
|
+
|
175
|
+
it "raises a SyntaxError when 'else' is used when no 'when' is given" do
|
176
|
+
lambda {
|
177
|
+
eval <<-CODE
|
178
|
+
case 4
|
179
|
+
else
|
180
|
+
true
|
181
|
+
end
|
182
|
+
CODE
|
183
|
+
}.should raise_error(SyntaxError)
|
184
|
+
end
|
185
|
+
|
186
|
+
it "raises a SyntaxError when 'else' is used before a 'when' was given" do
|
187
|
+
lambda {
|
188
|
+
eval <<-CODE
|
189
|
+
case 4
|
190
|
+
else
|
191
|
+
true
|
192
|
+
when 4; false
|
193
|
+
end
|
194
|
+
CODE
|
195
|
+
}.should raise_error(SyntaxError)
|
196
|
+
end
|
197
|
+
|
198
|
+
it "supports nested case statements" do
|
199
|
+
result = false
|
200
|
+
case :x
|
201
|
+
when Symbol
|
202
|
+
case :y
|
203
|
+
when Symbol
|
204
|
+
result = true
|
205
|
+
end
|
206
|
+
end
|
207
|
+
result.should == true
|
208
|
+
end
|
209
|
+
|
210
|
+
it "supports nested case statements followed by a when with a splatted array" do
|
211
|
+
result = false
|
212
|
+
case :x
|
213
|
+
when Symbol
|
214
|
+
case :y
|
215
|
+
when Symbol
|
216
|
+
result = true
|
217
|
+
end
|
218
|
+
when *[Symbol]
|
219
|
+
result = false
|
220
|
+
end
|
221
|
+
result.should == true
|
222
|
+
end
|
223
|
+
|
224
|
+
it "supports nested case statements followed by a when with a splatted non-array" do
|
225
|
+
result = false
|
226
|
+
case :x
|
227
|
+
when Symbol
|
228
|
+
case :y
|
229
|
+
when Symbol
|
230
|
+
result = true
|
231
|
+
end
|
232
|
+
when *Symbol
|
233
|
+
result = false
|
234
|
+
end
|
235
|
+
result.should == true
|
236
|
+
end
|
237
|
+
|
238
|
+
it "works even if there's only one when statement" do
|
239
|
+
case 1
|
240
|
+
when 1
|
241
|
+
100
|
242
|
+
end.should == 100
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
describe "The 'case'-construct with no target expression" do
|
247
|
+
pending "evaluates the body of the first clause when at least one of its condition expressions is true" do
|
248
|
+
# case
|
249
|
+
# when true, false; 'foo'
|
250
|
+
# end.should == 'foo'
|
251
|
+
end
|
252
|
+
|
253
|
+
pending "evaluates the body of the first when clause that is not false/nil" do
|
254
|
+
# case
|
255
|
+
# when false; 'foo'
|
256
|
+
# when 2; 'bar'
|
257
|
+
# when 1 == 1; 'baz'
|
258
|
+
# end.should == 'bar'
|
259
|
+
|
260
|
+
# case
|
261
|
+
# when false; 'foo'
|
262
|
+
# when nil; 'foo'
|
263
|
+
# when 1 == 1; 'bar'
|
264
|
+
# end.should == 'bar'
|
265
|
+
end
|
266
|
+
|
267
|
+
pending "evaluates the body of the else clause if all when clauses are false/nil" do
|
268
|
+
# case
|
269
|
+
# when false; 'foo'
|
270
|
+
# when nil; 'foo'
|
271
|
+
# when 1 == 2; 'bar'
|
272
|
+
# else 'baz'
|
273
|
+
# end.should == 'baz'
|
274
|
+
end
|
275
|
+
|
276
|
+
pending "evaluates multiple conditional expressions as a boolean disjunction" do
|
277
|
+
# case
|
278
|
+
# when true, false; 'foo'
|
279
|
+
# else 'bar'
|
280
|
+
# end.should == 'foo'
|
281
|
+
|
282
|
+
# case
|
283
|
+
# when false, true; 'foo'
|
284
|
+
# else 'bar'
|
285
|
+
# end.should == 'foo'
|
286
|
+
end
|
287
|
+
|
288
|
+
pending "evaluates true as only 'true' when true is the first clause" do
|
289
|
+
case 1
|
290
|
+
when true; "bad"
|
291
|
+
when Integer; "good"
|
292
|
+
end.should == "good"
|
293
|
+
end
|
294
|
+
|
295
|
+
it "evaluates false as only 'false' when false is the first clause" do
|
296
|
+
case nil
|
297
|
+
when false; "bad"
|
298
|
+
when nil; "good"
|
299
|
+
end.should == "good"
|
300
|
+
end
|
301
|
+
|
302
|
+
it "treats a literal array as its own when argument, rather than a list of arguments" do
|
303
|
+
case 'foo'
|
304
|
+
when ['foo', 'foo']; 'bad'
|
305
|
+
when 'foo'; 'good'
|
306
|
+
end.should == 'good'
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
# language_version __FILE__, "case"
|