opal-cj 0.7.0.beta1
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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.gitmodules +27 -0
- data/.rspec +3 -0
- data/.spectator +2 -0
- data/.spectator-mspec +3 -0
- data/.travis.yml +45 -0
- data/CHANGELOG.md +406 -0
- data/CONTRIBUTING.md +41 -0
- data/Gemfile +27 -0
- data/Guardfile +77 -0
- data/LICENSE +19 -0
- data/README.md +178 -0
- data/Rakefile +116 -0
- data/benchmarks/operators.rb +11 -0
- data/bin/opal +22 -0
- data/bin/opal-build +77 -0
- data/bin/opal-mspec +10 -0
- data/bin/opal-repl +72 -0
- data/config.ru +14 -0
- data/examples/rack/Gemfile +3 -0
- data/examples/rack/app/application.rb +13 -0
- data/examples/rack/app/user.rb +21 -0
- data/examples/rack/config.ru +7 -0
- data/examples/rack/index.html.erb +10 -0
- data/examples/sinatra/Gemfile +4 -0
- data/examples/sinatra/app/application.rb +7 -0
- data/examples/sinatra/config.ru +28 -0
- data/lib/mspec/opal/main.rb.erb +9 -0
- data/lib/mspec/opal/rake_task.rb +278 -0
- data/lib/mspec/opal/runner.rb +206 -0
- data/lib/mspec/opal/sprockets.js +57 -0
- data/lib/opal.rb +11 -0
- data/lib/opal/builder.rb +135 -0
- data/lib/opal/builder_processors.rb +165 -0
- data/lib/opal/cli.rb +145 -0
- data/lib/opal/cli_options.rb +149 -0
- data/lib/opal/cli_runners.rb +10 -0
- data/lib/opal/cli_runners/nodejs.rb +56 -0
- data/lib/opal/cli_runners/phantom.js +35 -0
- data/lib/opal/cli_runners/phantomjs.rb +28 -0
- data/lib/opal/cli_runners/server.rb +54 -0
- data/lib/opal/compiler.rb +307 -0
- data/lib/opal/erb.rb +64 -0
- data/lib/opal/fragment.rb +41 -0
- data/lib/opal/hike_path_finder.rb +18 -0
- data/lib/opal/nodes.rb +26 -0
- data/lib/opal/nodes/arglist.rb +56 -0
- data/lib/opal/nodes/array.rb +54 -0
- data/lib/opal/nodes/base.rb +151 -0
- data/lib/opal/nodes/call.rb +283 -0
- data/lib/opal/nodes/call_special.rb +178 -0
- data/lib/opal/nodes/case.rb +96 -0
- data/lib/opal/nodes/class.rb +42 -0
- data/lib/opal/nodes/constants.rb +78 -0
- data/lib/opal/nodes/def.rb +157 -0
- data/lib/opal/nodes/defined.rb +113 -0
- data/lib/opal/nodes/definitions.rb +168 -0
- data/lib/opal/nodes/for.rb +35 -0
- data/lib/opal/nodes/hash.rb +67 -0
- data/lib/opal/nodes/helpers.rb +114 -0
- data/lib/opal/nodes/if.rb +67 -0
- data/lib/opal/nodes/iter.rb +131 -0
- data/lib/opal/nodes/literal.rb +230 -0
- data/lib/opal/nodes/logic.rb +217 -0
- data/lib/opal/nodes/masgn.rb +62 -0
- data/lib/opal/nodes/module.rb +46 -0
- data/lib/opal/nodes/rescue.rb +135 -0
- data/lib/opal/nodes/runtime_helpers.rb +45 -0
- data/lib/opal/nodes/scope.rb +293 -0
- data/lib/opal/nodes/singleton_class.rb +25 -0
- data/lib/opal/nodes/super.rb +97 -0
- data/lib/opal/nodes/top.rb +101 -0
- data/lib/opal/nodes/variables.rb +158 -0
- data/lib/opal/nodes/while.rb +65 -0
- data/lib/opal/nodes/yield.rb +95 -0
- data/lib/opal/parser.rb +658 -0
- data/lib/opal/parser/grammar.rb +5452 -0
- data/lib/opal/parser/grammar.y +1684 -0
- data/lib/opal/parser/keywords.rb +66 -0
- data/lib/opal/parser/lexer.rb +1208 -0
- data/lib/opal/parser/parser_scope.rb +25 -0
- data/lib/opal/parser/sexp.rb +75 -0
- data/lib/opal/path_reader.rb +28 -0
- data/lib/opal/paths.rb +38 -0
- data/lib/opal/source_map.rb +70 -0
- data/lib/opal/sprockets.rb +4 -0
- data/lib/opal/sprockets/cache_key_fix.rb +17 -0
- data/lib/opal/sprockets/environment.rb +37 -0
- data/lib/opal/sprockets/erb.rb +37 -0
- data/lib/opal/sprockets/path_reader.rb +34 -0
- data/lib/opal/sprockets/processor.rb +124 -0
- data/lib/opal/sprockets/server.rb +180 -0
- data/lib/opal/util.rb +64 -0
- data/lib/opal/version.rb +3 -0
- data/opal.gemspec +36 -0
- data/opal/README.md +6 -0
- data/opal/corelib/array.rb +1556 -0
- data/opal/corelib/array/inheritance.rb +113 -0
- data/opal/corelib/basic_object.rb +73 -0
- data/opal/corelib/boolean.rb +41 -0
- data/opal/corelib/class.rb +55 -0
- data/opal/corelib/comparable.rb +56 -0
- data/opal/corelib/complex.rb +3 -0
- data/opal/corelib/dir.rb +20 -0
- data/opal/corelib/enumerable.rb +1132 -0
- data/opal/corelib/enumerator.rb +422 -0
- data/opal/corelib/error.rb +63 -0
- data/opal/corelib/file.rb +56 -0
- data/opal/corelib/hash.rb +728 -0
- data/opal/corelib/helpers.rb +102 -0
- data/opal/corelib/io.rb +59 -0
- data/opal/corelib/kernel.rb +569 -0
- data/opal/corelib/main.rb +7 -0
- data/opal/corelib/match_data.rb +114 -0
- data/opal/corelib/method.rb +58 -0
- data/opal/corelib/module.rb +462 -0
- data/opal/corelib/nil_class.rb +62 -0
- data/opal/corelib/numeric.rb +532 -0
- data/opal/corelib/proc.rb +52 -0
- data/opal/corelib/range.rb +116 -0
- data/opal/corelib/rational.rb +3 -0
- data/opal/corelib/regexp.rb +133 -0
- data/opal/corelib/runtime.js +1240 -0
- data/opal/corelib/string.rb +1212 -0
- data/opal/corelib/string/inheritance.rb +78 -0
- data/opal/corelib/struct.rb +141 -0
- data/opal/corelib/time.rb +584 -0
- data/opal/corelib/variables.rb +24 -0
- data/opal/opal.rb +32 -0
- data/package.json +9 -0
- data/spec/filters/bugs/array.rb +232 -0
- data/spec/filters/bugs/basic_object.rb +14 -0
- data/spec/filters/bugs/class.rb +21 -0
- data/spec/filters/bugs/enumerable.rb +69 -0
- data/spec/filters/bugs/enumerator.rb +3 -0
- data/spec/filters/bugs/hash.rb +128 -0
- data/spec/filters/bugs/kernel.rb +10 -0
- data/spec/filters/bugs/language.rb +415 -0
- data/spec/filters/bugs/math.rb +95 -0
- data/spec/filters/bugs/module.rb +14 -0
- data/spec/filters/bugs/nil.rb +7 -0
- data/spec/filters/bugs/numeric.rb +20 -0
- data/spec/filters/bugs/opal.rb +14 -0
- data/spec/filters/bugs/regexp.rb +11 -0
- data/spec/filters/bugs/set.rb +7 -0
- data/spec/filters/bugs/singleton.rb +6 -0
- data/spec/filters/bugs/string.rb +360 -0
- data/spec/filters/bugs/stringscanner.rb +22 -0
- data/spec/filters/bugs/struct.rb +45 -0
- data/spec/filters/bugs/time.rb +177 -0
- data/spec/filters/bugs/unknown.rb +11 -0
- data/spec/filters/unsupported/encoding.rb +95 -0
- data/spec/filters/unsupported/enumerator.rb +14 -0
- data/spec/filters/unsupported/float.rb +5 -0
- data/spec/filters/unsupported/frozen.rb +90 -0
- data/spec/filters/unsupported/hash_compare_by_identity.rb +16 -0
- data/spec/filters/unsupported/integer_size.rb +7 -0
- data/spec/filters/unsupported/method_added.rb +10 -0
- data/spec/filters/unsupported/mutable_strings.rb +361 -0
- data/spec/filters/unsupported/private_constants.rb +30 -0
- data/spec/filters/unsupported/private_methods.rb +44 -0
- data/spec/filters/unsupported/random.rb +4 -0
- data/spec/filters/unsupported/ruby_exe.rb +5 -0
- data/spec/filters/unsupported/tainted.rb +155 -0
- data/spec/filters/unsupported/time.rb +21 -0
- data/spec/filters/unsupported/trusted.rb +80 -0
- data/spec/lib/builder_processors_spec.rb +27 -0
- data/spec/lib/builder_spec.rb +66 -0
- data/spec/lib/cli_spec.rb +134 -0
- data/spec/lib/compiler_spec.rb +197 -0
- data/spec/lib/dependency_resolver_spec.rb +40 -0
- data/spec/lib/fixtures/no_requires.rb +1 -0
- data/spec/lib/fixtures/opal_file.rb +2 -0
- data/spec/lib/fixtures/require_tree_test.rb +3 -0
- data/spec/lib/fixtures/required_tree_test/required_file1.rb +1 -0
- data/spec/lib/fixtures/required_tree_test/required_file2.rb +1 -0
- data/spec/lib/fixtures/requires.rb +7 -0
- data/spec/lib/fixtures/sprockets_file.js.rb +3 -0
- data/spec/lib/fixtures/sprockets_require_tree_test.rb +3 -0
- data/spec/lib/hike_path_finder_spec.rb +23 -0
- data/spec/lib/lexer_spec.rb +110 -0
- data/spec/lib/parser/alias_spec.rb +26 -0
- data/spec/lib/parser/and_spec.rb +13 -0
- data/spec/lib/parser/attrasgn_spec.rb +28 -0
- data/spec/lib/parser/begin_spec.rb +42 -0
- data/spec/lib/parser/block_spec.rb +12 -0
- data/spec/lib/parser/break_spec.rb +17 -0
- data/spec/lib/parser/call_spec.rb +139 -0
- data/spec/lib/parser/class_spec.rb +35 -0
- data/spec/lib/parser/comments_spec.rb +11 -0
- data/spec/lib/parser/def_spec.rb +61 -0
- data/spec/lib/parser/if_spec.rb +26 -0
- data/spec/lib/parser/iter_spec.rb +59 -0
- data/spec/lib/parser/lambda_spec.rb +64 -0
- data/spec/lib/parser/literal_spec.rb +118 -0
- data/spec/lib/parser/masgn_spec.rb +37 -0
- data/spec/lib/parser/module_spec.rb +27 -0
- data/spec/lib/parser/not_spec.rb +27 -0
- data/spec/lib/parser/op_asgn1_spec.rb +23 -0
- data/spec/lib/parser/op_asgn2_spec.rb +23 -0
- data/spec/lib/parser/or_spec.rb +13 -0
- data/spec/lib/parser/return_spec.rb +17 -0
- data/spec/lib/parser/sclass_spec.rb +21 -0
- data/spec/lib/parser/string_spec.rb +276 -0
- data/spec/lib/parser/super_spec.rb +20 -0
- data/spec/lib/parser/unary_spec.rb +48 -0
- data/spec/lib/parser/undef_spec.rb +15 -0
- data/spec/lib/parser/unless_spec.rb +13 -0
- data/spec/lib/parser/variables_spec.rb +92 -0
- data/spec/lib/parser/while_spec.rb +15 -0
- data/spec/lib/parser/yield_spec.rb +20 -0
- data/spec/lib/path_reader_spec.rb +24 -0
- data/spec/lib/shared/path_finder_shared.rb +19 -0
- data/spec/lib/shared/path_reader_shared.rb +31 -0
- data/spec/lib/spec_helper.rb +9 -0
- data/spec/lib/sprockets/environment_spec.rb +30 -0
- data/spec/lib/sprockets/erb_spec.rb +25 -0
- data/spec/lib/sprockets/path_reader_spec.rb +25 -0
- data/spec/lib/sprockets/processor_spec.rb +35 -0
- data/spec/lib/sprockets/server_spec.rb +20 -0
- data/spec/opal/compiler/irb_spec.rb +44 -0
- data/spec/opal/core/array/select_spec.rb +14 -0
- data/spec/opal/core/array/set_range_to_array_spec.rb +7 -0
- data/spec/opal/core/date_spec.rb +122 -0
- data/spec/opal/core/enumerable/all_break_spec.rb +5 -0
- data/spec/opal/core/enumerable/any_break_spec.rb +5 -0
- data/spec/opal/core/enumerable/collect_break_spec.rb +13 -0
- data/spec/opal/core/enumerable/count_break_spec.rb +5 -0
- data/spec/opal/core/enumerable/detect_break_spec.rb +5 -0
- data/spec/opal/core/enumerable/drop_while_break_spec.rb +5 -0
- data/spec/opal/core/enumerable/each_slice_break.rb +6 -0
- data/spec/opal/core/enumerable/each_with_index_break_spec.rb +5 -0
- data/spec/opal/core/enumerable/each_with_object_break_spec.rb +5 -0
- data/spec/opal/core/enumerable/find_all_break_spec.rb +5 -0
- data/spec/opal/core/enumerable/find_index_break_spec.rb +5 -0
- data/spec/opal/core/enumerable/grep_break_spec.rb +5 -0
- data/spec/opal/core/enumerable/max_break_spec.rb +5 -0
- data/spec/opal/core/enumerable/max_by_break_spec.rb +5 -0
- data/spec/opal/core/enumerable/min_break_spec.rb +5 -0
- data/spec/opal/core/enumerable/min_by_break_spec.rb +5 -0
- data/spec/opal/core/enumerable/none_break_spec.rb +5 -0
- data/spec/opal/core/enumerable/one_break_spec.rb +5 -0
- data/spec/opal/core/enumerable/reduce_break_spec.rb +5 -0
- data/spec/opal/core/enumerable/take_while_break_spec.rb +5 -0
- data/spec/opal/core/fixtures/class.rb +124 -0
- data/spec/opal/core/fixtures/class_variables.rb +0 -0
- data/spec/opal/core/fixtures/constants.rb +33 -0
- data/spec/opal/core/fixtures/require_tree_files/file 1.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_files/file 2.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_files/file 3.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_files/file 4.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_files/file 5.rb +1 -0
- data/spec/opal/core/kernel/Array_spec.rb +10 -0
- data/spec/opal/core/kernel/block_given_spec.rb +30 -0
- data/spec/opal/core/kernel/class_spec.rb +6 -0
- data/spec/opal/core/kernel/define_singleton_method_spec.rb +21 -0
- data/spec/opal/core/kernel/equal_value_spec.rb +12 -0
- data/spec/opal/core/kernel/extend_spec.rb +21 -0
- data/spec/opal/core/kernel/format_spec.rb +122 -0
- data/spec/opal/core/kernel/freeze_spec.rb +15 -0
- data/spec/opal/core/kernel/instance_eval_spec.rb +28 -0
- data/spec/opal/core/kernel/instance_variable_defined_spec.rb +15 -0
- data/spec/opal/core/kernel/instance_variable_get_spec.rb +14 -0
- data/spec/opal/core/kernel/instance_variable_set_spec.rb +10 -0
- data/spec/opal/core/kernel/loop_spec.rb +23 -0
- data/spec/opal/core/kernel/match_spec.rb +5 -0
- data/spec/opal/core/kernel/method_spec.rb +31 -0
- data/spec/opal/core/kernel/methods_spec.rb +25 -0
- data/spec/opal/core/kernel/nil_spec.rb +7 -0
- data/spec/opal/core/kernel/p_spec.rb +15 -0
- data/spec/opal/core/kernel/printf_spec.rb +11 -0
- data/spec/opal/core/kernel/proc_spec.rb +13 -0
- data/spec/opal/core/kernel/rand_spec.rb +23 -0
- data/spec/opal/core/kernel/require_tree_spec.rb +7 -0
- data/spec/opal/core/kernel/respond_to_spec.rb +41 -0
- data/spec/opal/core/kernel/send_spec.rb +56 -0
- data/spec/opal/core/kernel/sprintf_spec.rb +5 -0
- data/spec/opal/core/language/block_spec.rb +538 -0
- data/spec/opal/core/language/fixtures/array.rb +11 -0
- data/spec/opal/core/language/fixtures/block.rb +57 -0
- data/spec/opal/core/language/fixtures/break.rb +240 -0
- data/spec/opal/core/language/fixtures/ensure.rb +72 -0
- data/spec/opal/core/language/fixtures/literal_lambda.rb +7 -0
- data/spec/opal/core/language/fixtures/metaclass.rb +33 -0
- data/spec/opal/core/language/fixtures/module.rb +24 -0
- data/spec/opal/core/language/fixtures/next.rb +128 -0
- data/spec/opal/core/language/fixtures/return.rb +118 -0
- data/spec/opal/core/language/fixtures/send.rb +110 -0
- data/spec/opal/core/language/fixtures/send_1.9.rb +22 -0
- data/spec/opal/core/language/fixtures/super.rb +308 -0
- data/spec/opal/core/language/fixtures/variables.rb +58 -0
- data/spec/opal/core/language/fixtures/yield.rb +28 -0
- data/spec/opal/core/language/predefined_spec.rb +85 -0
- data/spec/opal/core/language/proc_spec.rb +263 -0
- data/spec/opal/core/language/regexp_spec.rb +20 -0
- data/spec/opal/core/language/send_spec.rb +225 -0
- data/spec/opal/core/language/string_spec.rb +44 -0
- data/spec/opal/core/language/symbol_spec.rb +40 -0
- data/spec/opal/core/language/variables_spec.rb +1366 -0
- data/spec/opal/core/language/versions/array_1.9.rb +39 -0
- data/spec/opal/core/language/versions/block_1.9.rb +0 -0
- data/spec/opal/core/language/versions/break_1.9.rb +0 -0
- data/spec/opal/core/language/versions/case_1.9.rb +20 -0
- data/spec/opal/core/language/versions/hash_1.9.rb +18 -0
- data/spec/opal/core/language/versions/literal_lambda_1.9.rb +143 -0
- data/spec/opal/core/language/versions/not_1.9.rb +22 -0
- data/spec/opal/core/language/versions/send_1.9.rb +241 -0
- data/spec/opal/core/language/versions/symbol_1.9.rb +15 -0
- data/spec/opal/core/language/versions/variables_1.9.rb +8 -0
- data/spec/opal/core/module/alias_method_spec.rb +28 -0
- data/spec/opal/core/module/ancestors_spec.rb +11 -0
- data/spec/opal/core/module/append_features_spec.rb +14 -0
- data/spec/opal/core/module/attr_accessor_spec.rb +26 -0
- data/spec/opal/core/module/const_defined_spec.rb +85 -0
- data/spec/opal/core/module/const_get_spec.rb +85 -0
- data/spec/opal/core/module/const_missing_spec.rb +17 -0
- data/spec/opal/core/module/const_set_spec.rb +64 -0
- data/spec/opal/core/module/constants_spec.rb +49 -0
- data/spec/opal/core/module/fixtures/classes.rb +434 -0
- data/spec/opal/core/module/method_defined_spec.rb +48 -0
- data/spec/opal/core/module/module_function_spec.rb +25 -0
- data/spec/opal/core/module/name_spec.rb +52 -0
- data/spec/opal/core/module/public_method_defined_spec.rb +18 -0
- data/spec/opal/core/module/remove_const_spec.rb +22 -0
- data/spec/opal/core/module/undef_method_spec.rb +66 -0
- data/spec/opal/core/numeric/bit_and_spec.rb +7 -0
- data/spec/opal/core/numeric/bit_or_spec.rb +8 -0
- data/spec/opal/core/numeric/bit_xor_spec.rb +6 -0
- data/spec/opal/core/numeric/ceil_spec.rb +8 -0
- data/spec/opal/core/numeric/chr_spec.rb +8 -0
- data/spec/opal/core/numeric/comparison_spec.rb +24 -0
- data/spec/opal/core/numeric/complement_spec.rb +8 -0
- data/spec/opal/core/numeric/divide_spec.rb +10 -0
- data/spec/opal/core/numeric/eql_spec.rb +9 -0
- data/spec/opal/core/numeric/exponent_spec.rb +33 -0
- data/spec/opal/core/numeric/floor_spec.rb +8 -0
- data/spec/opal/core/numeric/gt_spec.rb +11 -0
- data/spec/opal/core/numeric/gte_spec.rb +12 -0
- data/spec/opal/core/numeric/integer_spec.rb +9 -0
- data/spec/opal/core/numeric/left_shift_spec.rb +21 -0
- data/spec/opal/core/numeric/lt_spec.rb +11 -0
- data/spec/opal/core/numeric/lte_spec.rb +12 -0
- data/spec/opal/core/numeric/minus_spec.rb +8 -0
- data/spec/opal/core/numeric/modulo_spec.rb +19 -0
- data/spec/opal/core/numeric/multiply_spec.rb +9 -0
- data/spec/opal/core/numeric/next_spec.rb +9 -0
- data/spec/opal/core/numeric/ord_spec.rb +9 -0
- data/spec/opal/core/numeric/plus_spec.rb +8 -0
- data/spec/opal/core/numeric/pred_spec.rb +7 -0
- data/spec/opal/core/numeric/right_shift_spec.rb +25 -0
- data/spec/opal/core/numeric/step_spec.rb +11 -0
- data/spec/opal/core/numeric/succ_spec.rb +9 -0
- data/spec/opal/core/numeric/times_spec.rb +36 -0
- data/spec/opal/core/numeric/to_f_spec.rb +7 -0
- data/spec/opal/core/numeric/to_i_spec.rb +7 -0
- data/spec/opal/core/numeric/to_json_spec.rb +8 -0
- data/spec/opal/core/numeric/to_s_spec.rb +26 -0
- data/spec/opal/core/numeric/uminus_spec.rb +9 -0
- data/spec/opal/core/numeric/upto_spec.rb +19 -0
- data/spec/opal/core/numeric/zero_spec.rb +7 -0
- data/spec/opal/core/proc/call_spec.rb +21 -0
- data/spec/opal/core/proc/element_reference_spec.rb +21 -0
- data/spec/opal/core/proc/proc_tricks_spec.rb +7 -0
- data/spec/opal/core/runtime/begin_spec.rb +39 -0
- data/spec/opal/core/runtime/block_send_spec.rb +28 -0
- data/spec/opal/core/runtime/block_spec.rb +23 -0
- data/spec/opal/core/runtime/bridged_classes_spec.rb +64 -0
- data/spec/opal/core/runtime/constants_spec.rb +13 -0
- data/spec/opal/core/runtime/eval_spec.rb +5 -0
- data/spec/opal/core/runtime/main_methods_spec.rb +27 -0
- data/spec/opal/core/runtime/method_missing_spec.rb +62 -0
- data/spec/opal/core/runtime/method_spec.rb +31 -0
- data/spec/opal/core/runtime/operator_call_spec.rb +13 -0
- data/spec/opal/core/runtime/paren_spec.rb +14 -0
- data/spec/opal/core/runtime/rescue_spec.rb +38 -0
- data/spec/opal/core/runtime/return_spec.rb +38 -0
- data/spec/opal/core/runtime/send_spec.rb +34 -0
- data/spec/opal/core/runtime/singleton_class_spec.rb +13 -0
- data/spec/opal/core/runtime/super_spec.rb +212 -0
- data/spec/opal/core/runtime/truthy_spec.rb +23 -0
- data/spec/opal/core/runtime/variables_spec.rb +20 -0
- data/spec/opal/core/source_map_spec.rb +15 -0
- data/spec/opal/core/string_spec.rb +11 -0
- data/spec/opal/stdlib/erb/erb_spec.rb +30 -0
- data/spec/opal/stdlib/erb/inline_block.opalerb +3 -0
- data/spec/opal/stdlib/erb/quoted.opalerb +1 -0
- data/spec/opal/stdlib/erb/simple.opalerb +1 -0
- data/spec/opal/stdlib/json/ext_spec.rb +48 -0
- data/spec/opal/stdlib/json/parse_spec.rb +33 -0
- data/spec/opal/stdlib/native/alias_native_spec.rb +27 -0
- data/spec/opal/stdlib/native/each_spec.rb +13 -0
- data/spec/opal/stdlib/native/element_reference_spec.rb +16 -0
- data/spec/opal/stdlib/native/exposure_spec.rb +33 -0
- data/spec/opal/stdlib/native/ext_spec.rb +19 -0
- data/spec/opal/stdlib/native/initialize_spec.rb +17 -0
- data/spec/opal/stdlib/native/method_missing_spec.rb +51 -0
- data/spec/opal/stdlib/native/native_reader_spec.rb +22 -0
- data/spec/opal/stdlib/native/native_writer_spec.rb +30 -0
- data/spec/opal/stdlib/native/new_spec.rb +8 -0
- data/spec/opal/stdlib/promise/error_spec.rb +15 -0
- data/spec/opal/stdlib/promise/rescue_spec.rb +35 -0
- data/spec/opal/stdlib/promise/then_spec.rb +54 -0
- data/spec/opal/stdlib/promise/trace_spec.rb +35 -0
- data/spec/opal/stdlib/promise/value_spec.rb +15 -0
- data/spec/opal/stdlib/promise/when_spec.rb +34 -0
- data/spec/opal/stdlib/template/paths_spec.rb +10 -0
- data/spec/opal/stdlib/thread/mutex_spec.rb +40 -0
- data/spec/opal/stdlib/thread/thread_queue_spec.rb +32 -0
- data/spec/opal/stdlib/thread/thread_spec.rb +60 -0
- data/spec/rubyspecs +329 -0
- data/spec/spec_helper.rb +42 -0
- data/spec/support/mspec_rspec_adapter.rb +33 -0
- data/spec/support/parser_helpers.rb +37 -0
- data/stdlib/README.md +3 -0
- data/stdlib/base64.rb +152 -0
- data/stdlib/benchmark.rb +10 -0
- data/stdlib/buffer.rb +40 -0
- data/stdlib/buffer/array.rb +66 -0
- data/stdlib/buffer/view.rb +70 -0
- data/stdlib/date.rb +170 -0
- data/stdlib/delegate.rb +29 -0
- data/stdlib/dir.rb +1 -0
- data/stdlib/encoding.rb +166 -0
- data/stdlib/enumerator.rb +1 -0
- data/stdlib/erb.rb +16 -0
- data/stdlib/file.rb +1 -0
- data/stdlib/forwardable.rb +71 -0
- data/stdlib/json.rb +182 -0
- data/stdlib/math.rb +370 -0
- data/stdlib/native.rb +530 -0
- data/stdlib/nodejs.rb +5 -0
- data/stdlib/nodejs/dir.rb +13 -0
- data/stdlib/nodejs/file.rb +98 -0
- data/stdlib/nodejs/fileutils.rb +26 -0
- data/stdlib/nodejs/io.rb +2 -0
- data/stdlib/nodejs/irb.rb +45 -0
- data/stdlib/nodejs/process.rb +16 -0
- data/stdlib/nodejs/require.rb +32 -0
- data/stdlib/nodejs/rubygems.rb +68 -0
- data/stdlib/nodejs/runtime.rb +25 -0
- data/stdlib/nodejs/yaml.rb +11 -0
- data/stdlib/observer.rb +202 -0
- data/stdlib/opal-parser.rb +53 -0
- data/stdlib/opal-source-maps.rb +2 -0
- data/stdlib/ostruct.rb +69 -0
- data/stdlib/pathname.rb +31 -0
- data/stdlib/phantomjs.rb +8 -0
- data/stdlib/pp.rb +12 -0
- data/stdlib/process.rb +10 -0
- data/stdlib/promise.rb +300 -0
- data/stdlib/racc/parser.rb +215 -0
- data/stdlib/rbconfig.rb +20 -0
- data/stdlib/securerandom.rb +12 -0
- data/stdlib/set.rb +116 -0
- data/stdlib/singleton.rb +40 -0
- data/stdlib/source_map.rb +5 -0
- data/stdlib/source_map/map.rb +220 -0
- data/stdlib/source_map/mapping.rb +26 -0
- data/stdlib/source_map/offset.rb +88 -0
- data/stdlib/source_map/version.rb +3 -0
- data/stdlib/source_map/vlq.rb +98 -0
- data/stdlib/sourcemap.rb +1 -0
- data/stdlib/stringio.rb +181 -0
- data/stdlib/strscan.rb +155 -0
- data/stdlib/template.rb +46 -0
- data/stdlib/thread.rb +160 -0
- data/stdlib/time.rb +9 -0
- data/tasks/github.rake +19 -0
- metadata +690 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
require File.expand_path('../fixtures/send', __FILE__)
|
|
2
|
+
|
|
3
|
+
# Why so many fixed arg tests? JRuby and I assume other Ruby impls have
|
|
4
|
+
# separate call paths for simple fixed arity methods. Testing up to five
|
|
5
|
+
# will verify special and generic arity code paths for all impls.
|
|
6
|
+
#
|
|
7
|
+
# Method naming conventions:
|
|
8
|
+
# M - Manditory Args
|
|
9
|
+
# O - Optional Arg
|
|
10
|
+
# R - Rest Arg
|
|
11
|
+
# Q - Post Manditory Args (1.9)
|
|
12
|
+
|
|
13
|
+
specs = LangSendSpecs
|
|
14
|
+
|
|
15
|
+
describe "Invoking a method" do
|
|
16
|
+
describe "with zero arguments" do
|
|
17
|
+
it "requires no arguments passed" do
|
|
18
|
+
specs.fooM0.should == 100
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "raises ArgumentError if the method has a positive arity" do
|
|
22
|
+
lambda {
|
|
23
|
+
specs.fooM1
|
|
24
|
+
}.should raise_error(ArgumentError)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe "with only manditory arguments" do
|
|
29
|
+
it "requires exactly the same number of passed values" do
|
|
30
|
+
specs.fooM1(1).should == [1]
|
|
31
|
+
specs.fooM2(1,2).should == [1,2]
|
|
32
|
+
specs.fooM3(1,2,3).should == [1,2,3]
|
|
33
|
+
specs.fooM4(1,2,3,4).should == [1,2,3,4]
|
|
34
|
+
specs.fooM5(1,2,3,4,5).should == [1,2,3,4,5]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "raises ArgumentError if the methods arity doesn't match" do
|
|
38
|
+
lambda {
|
|
39
|
+
specs.fooM1(1,2)
|
|
40
|
+
}.should raise_error(ArgumentError)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe "with optional arguments" do
|
|
45
|
+
it "uses the optional argument if none is is passed" do
|
|
46
|
+
specs.fooM0O1.should == [1]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "uses the passed argument if available" do
|
|
50
|
+
specs.fooM0O1(2).should == [2]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "raises ArgumentError if extra arguments are passed" do
|
|
54
|
+
lambda {
|
|
55
|
+
specs.fooM0O1(2,3)
|
|
56
|
+
}.should raise_error(ArgumentError)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
describe "with manditory and optional arguments" do
|
|
61
|
+
it "uses the passed values in left to right order" do
|
|
62
|
+
specs.fooM1O1(2).should == [2,1]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "raises an ArgumentError if there are no values for the manditory args" do
|
|
66
|
+
lambda {
|
|
67
|
+
specs.fooM1O1
|
|
68
|
+
}.should raise_error(ArgumentError)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "raises an ArgumentError if too many values are passed" do
|
|
72
|
+
lambda {
|
|
73
|
+
specs.fooM1O1(1,2,3)
|
|
74
|
+
}.should raise_error(ArgumentError)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe "with a rest argument" do
|
|
79
|
+
it "is an empty array if there are no additional arguments" do
|
|
80
|
+
specs.fooM0R().should == []
|
|
81
|
+
specs.fooM1R(1).should == [1, []]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "gathers unused arguments" do
|
|
85
|
+
specs.fooM0R(1).should == [1]
|
|
86
|
+
specs.fooM1R(1,2).should == [1, [2]]
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "with a block makes it available to yield" do
|
|
91
|
+
specs.oneb(10) { 200 }.should == [10,200]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "with a block converts the block to a Proc" do
|
|
95
|
+
prc = specs.makeproc { "hello" }
|
|
96
|
+
prc.should be_kind_of(Proc)
|
|
97
|
+
prc.call.should == "hello"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it "with an object as a block uses 'to_proc' for coercion" do
|
|
101
|
+
o = LangSendSpecs::ToProc.new(:from_to_proc)
|
|
102
|
+
|
|
103
|
+
specs.makeproc(&o).call.should == :from_to_proc
|
|
104
|
+
|
|
105
|
+
specs.yield_now(&o).should == :from_to_proc
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it "raises a SyntaxError with both a literal block and an object as block" do
|
|
109
|
+
lambda {
|
|
110
|
+
eval "specs.oneb(10, &l){ 42 }"
|
|
111
|
+
}.should raise_error(SyntaxError)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "with same names as existing variables is ok" do
|
|
115
|
+
foobar = 100
|
|
116
|
+
|
|
117
|
+
def foobar; 200; end
|
|
118
|
+
|
|
119
|
+
foobar.should == 100
|
|
120
|
+
foobar().should == 200
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "with splat operator makes the object the direct arguments" do
|
|
124
|
+
a = [1,2,3]
|
|
125
|
+
specs.fooM3(*a).should == [1,2,3]
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "without parentheses works" do
|
|
129
|
+
(specs.fooM3 1,2,3).should == [1,2,3]
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it "with a space separating method name and parenthesis treats expression in parenthesis as first argument" do
|
|
133
|
+
specs.weird_parens().should == "55"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
ruby_version_is "" ... "1.9" do
|
|
137
|
+
describe "allows []=" do
|
|
138
|
+
before :each do
|
|
139
|
+
@obj = LangSendSpecs::AttrSet.new
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it "with *args in the [] expanded to individual arguments" do
|
|
143
|
+
ary = [2,3]
|
|
144
|
+
(@obj[1, *ary] = 4).should == 4
|
|
145
|
+
@obj.result.should == [1,2,3,4]
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it "with multiple *args" do
|
|
149
|
+
ary = [2,3]
|
|
150
|
+
post = [4,5]
|
|
151
|
+
(@obj[1, *ary] = *post).should == [4,5]
|
|
152
|
+
@obj.result.should == [1,2,3,[4,5]]
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it "with multiple *args and unwraps the last splat" do
|
|
156
|
+
ary = [2,3]
|
|
157
|
+
post = [4]
|
|
158
|
+
(@obj[1, *ary] = *post).should == 4
|
|
159
|
+
@obj.result.should == [1,2,3,4]
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it "with a *args and multiple rhs args" do
|
|
163
|
+
ary = [2,3]
|
|
164
|
+
(@obj[1, *ary] = 4, 5).should == [4,5]
|
|
165
|
+
@obj.result.should == [1,2,3,[4,5]]
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it "passes literal hashes without curly braces as the last parameter" do
|
|
171
|
+
specs.fooM3('abc', 456, 'rbx' => 'cool',
|
|
172
|
+
'specs' => 'fail sometimes', 'oh' => 'weh').should == \
|
|
173
|
+
['abc', 456, {'rbx' => 'cool', 'specs' => 'fail sometimes', 'oh' => 'weh'}]
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it "passes a literal hash without curly braces or parens" do
|
|
177
|
+
(specs.fooM3 'abc', 456, 'rbx' => 'cool',
|
|
178
|
+
'specs' => 'fail sometimes', 'oh' => 'weh').should == \
|
|
179
|
+
['abc', 456, { 'rbx' => 'cool', 'specs' => 'fail sometimes', 'oh' => 'weh'}]
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it "allows to literal hashes without curly braces as the only parameter" do
|
|
183
|
+
specs.fooM1(:rbx => :cool, :specs => :fail_sometimes).should ==
|
|
184
|
+
[{ :rbx => :cool, :specs => :fail_sometimes }]
|
|
185
|
+
|
|
186
|
+
(specs.fooM1 :rbx => :cool, :specs => :fail_sometimes).should ==
|
|
187
|
+
[{ :rbx => :cool, :specs => :fail_sometimes }]
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
describe "when the method is not available" do
|
|
191
|
+
it "invokes method_missing" do
|
|
192
|
+
o = LangSendSpecs::MethodMissing.new
|
|
193
|
+
o.not_there(1,2)
|
|
194
|
+
o.message.should == :not_there
|
|
195
|
+
o.args.should == [1,2]
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
describe "Invoking a private setter method" do
|
|
202
|
+
describe "permits self as a receiver" do
|
|
203
|
+
it "for normal assignment" do
|
|
204
|
+
receiver = LangSendSpecs::PrivateSetter.new
|
|
205
|
+
receiver.call_self_foo_equals(42)
|
|
206
|
+
receiver.foo.should == 42
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
it "for multiple assignment" do
|
|
210
|
+
receiver = LangSendSpecs::PrivateSetter.new
|
|
211
|
+
receiver.call_self_foo_equals_masgn(42)
|
|
212
|
+
receiver.foo.should == 42
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
describe "Invoking a private getter method" do
|
|
218
|
+
it "does not permit self as a receiver" do
|
|
219
|
+
receiver = LangSendSpecs::PrivateGetter.new
|
|
220
|
+
lambda { receiver.call_self_foo }.should raise_error(NoMethodError)
|
|
221
|
+
lambda { receiver.call_self_foo_or_equals(6) }.should raise_error(NoMethodError)
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# language_version __FILE__, "send"
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
describe "Ruby character strings" do
|
|
2
|
+
it "are produced from character shortcuts" do
|
|
3
|
+
?z.should == 'z'
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
it "should parse string into %[]" do
|
|
7
|
+
%[foo].should == "foo"
|
|
8
|
+
%|bar|.should == "bar"
|
|
9
|
+
%'baz'.should == "baz"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "interpolate string" do
|
|
13
|
+
a = 1
|
|
14
|
+
%[#{a}23].should == "123"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should not process escape characters in single-quoted heredocs" do
|
|
18
|
+
s = <<'EOD'
|
|
19
|
+
hey\now\brown\cow
|
|
20
|
+
EOD
|
|
21
|
+
s.strip.should == 'hey\now\brown\cow'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should ignore single-quote escapes in single-quoted heredocs" do
|
|
25
|
+
s = <<'EOD'
|
|
26
|
+
they\'re greeeeaaat!
|
|
27
|
+
EOD
|
|
28
|
+
s.strip.should == 'they\\\'re greeeeaaat!'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should process escape characters in double quoted heredocs" do
|
|
32
|
+
s = <<"EOD"
|
|
33
|
+
hey\now\brown\cow
|
|
34
|
+
EOD
|
|
35
|
+
s.strip.should == "hey\now\brown\cow"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should treat bare-word heredoc identifiers as double-quoted" do
|
|
39
|
+
s = <<EOD
|
|
40
|
+
hey\now\brown\cow
|
|
41
|
+
EOD
|
|
42
|
+
s.strip.should == "hey\now\brown\cow"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
describe "A Symbol literal" do
|
|
2
|
+
it "is a ':' followed by any number of valid characters" do
|
|
3
|
+
a = :foo
|
|
4
|
+
a.should be_kind_of(Symbol)
|
|
5
|
+
# FIXME: this doesnt work as Symbols are Strings
|
|
6
|
+
#a.inspect.should == ':foo'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "is a ':' followed by any valid variable, method, or constant name" do
|
|
10
|
+
# Add more of these?
|
|
11
|
+
[ :Foo,
|
|
12
|
+
:foo,
|
|
13
|
+
:@foo,
|
|
14
|
+
:@@foo,
|
|
15
|
+
:$foo,
|
|
16
|
+
:_,
|
|
17
|
+
:~,
|
|
18
|
+
:-,
|
|
19
|
+
:FOO,
|
|
20
|
+
:_Foo,
|
|
21
|
+
:&,
|
|
22
|
+
:_9
|
|
23
|
+
].each { |s| s.should be_kind_of(Symbol) }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "is a ':' followed by a single- or double-quoted string that may contain otherwise invalid characters" do
|
|
27
|
+
[ [:'foo bar', ':"foo bar"'],
|
|
28
|
+
[:'++', ':"++"'],
|
|
29
|
+
[:'9', ':"9"'],
|
|
30
|
+
[:"foo #{1 + 1}", ':"foo 2"']
|
|
31
|
+
].each {
|
|
32
|
+
# FIXME: Symbols are Strings, so #inspect wont work
|
|
33
|
+
1.should == 1
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "may contain '::' in the string" do
|
|
38
|
+
:'Some::Class'.should be_kind_of(Symbol)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,1366 @@
|
|
|
1
|
+
require File.expand_path('../fixtures/variables', __FILE__)
|
|
2
|
+
|
|
3
|
+
# TODO: partition these specs into distinct cases based on the
|
|
4
|
+
# real parsed forms, not the superficial code forms.
|
|
5
|
+
describe "Basic assignment" do
|
|
6
|
+
it "allows the rhs to be assigned to the lhs" do
|
|
7
|
+
a = nil
|
|
8
|
+
a.should == nil
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "assigns nil to lhs when rhs is an empty expression" do
|
|
12
|
+
a = ()
|
|
13
|
+
a.should be_nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
ruby_version_is "" ... "1.9" do
|
|
17
|
+
it "assigns nil to lhs when rhs is an empty splat expression" do
|
|
18
|
+
a = *()
|
|
19
|
+
a.should be_nil
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
ruby_version_is "1.9" do
|
|
24
|
+
it "assigns [] to lhs when rhs is an empty splat expression" do
|
|
25
|
+
a = *()
|
|
26
|
+
a.should == []
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
ruby_version_is "" ... "1.9" do
|
|
31
|
+
it "allows the assignment of the rhs to the lhs using the rhs splat operator" do
|
|
32
|
+
a = *nil; a.should == nil
|
|
33
|
+
a = *1; a.should == 1
|
|
34
|
+
a = *[]; a.should == nil
|
|
35
|
+
a = *[1]; a.should == 1
|
|
36
|
+
a = *[nil]; a.should == nil
|
|
37
|
+
a = *[[]]; a.should == []
|
|
38
|
+
a = *[1,2]; a.should == [1,2]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
ruby_version_is "1.9" do
|
|
43
|
+
it "allows the assignment of the rhs to the lhs using the rhs splat operator" do
|
|
44
|
+
a = *nil; a.should == []
|
|
45
|
+
a = *1; a.should == [1]
|
|
46
|
+
a = *[]; a.should == []
|
|
47
|
+
a = *[1]; a.should == [1]
|
|
48
|
+
a = *[nil]; a.should == [nil]
|
|
49
|
+
a = *[[]]; a.should == [[]]
|
|
50
|
+
a = *[1,2]; a.should == [1,2]
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
ruby_version_is "" ... "1.9" do
|
|
55
|
+
it "allows the assignment of the rhs to the lhs using the lhs splat operator" do
|
|
56
|
+
# * = 1,2 # Valid syntax, but pretty useless! Nothing to test
|
|
57
|
+
*a = nil; a.should == [nil]
|
|
58
|
+
*a = 1; a.should == [1]
|
|
59
|
+
*a = []; a.should == [[]]
|
|
60
|
+
*a = [1]; a.should == [[1]]
|
|
61
|
+
*a = [1,2]; a.should == [[1,2]]
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
ruby_version_is "1.9" do
|
|
66
|
+
it "allows the assignment of the rhs to the lhs using the lhs splat operator" do
|
|
67
|
+
# * = 1,2 # Valid syntax, but pretty useless! Nothing to test
|
|
68
|
+
*a = nil; a.should == [nil]
|
|
69
|
+
*a = 1; a.should == [1]
|
|
70
|
+
*a = []; a.should == []
|
|
71
|
+
*a = [1]; a.should == [1]
|
|
72
|
+
*a = [1,2]; a.should == [1,2]
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
ruby_version_is "" ... "1.9" do
|
|
77
|
+
it "allows the assignment of rhs to the lhs using the lhs and rhs splat operators simultaneously" do
|
|
78
|
+
*a = *nil; a.should == [nil]
|
|
79
|
+
*a = *1; a.should == [1]
|
|
80
|
+
*a = *[]; a.should == []
|
|
81
|
+
*a = *[1]; a.should == [1]
|
|
82
|
+
*a = *[nil]; a.should == [nil]
|
|
83
|
+
*a = *[1,2]; a.should == [1,2]
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
ruby_version_is "1.9" do
|
|
88
|
+
it "allows the assignment of rhs to the lhs using the lhs and rhs splat operators simultaneously" do
|
|
89
|
+
*a = *nil; a.should == []
|
|
90
|
+
*a = *1; a.should == [1]
|
|
91
|
+
*a = *[]; a.should == []
|
|
92
|
+
*a = *[1]; a.should == [1]
|
|
93
|
+
*a = *[nil]; a.should == [nil]
|
|
94
|
+
*a = *[1,2]; a.should == [1,2]
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "sets unavailable values to nil" do
|
|
99
|
+
ary = []
|
|
100
|
+
a, b, c = ary
|
|
101
|
+
|
|
102
|
+
a.should be_nil
|
|
103
|
+
b.should be_nil
|
|
104
|
+
c.should be_nil
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "sets the splat to an empty Array if there are no more values" do
|
|
108
|
+
ary = []
|
|
109
|
+
a, b, *c = ary
|
|
110
|
+
|
|
111
|
+
a.should be_nil
|
|
112
|
+
b.should be_nil
|
|
113
|
+
c.should == []
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it "allows multiple values to be assigned" do
|
|
117
|
+
a,b,*c = nil; [a,b,c].should == [nil, nil, []]
|
|
118
|
+
a,b,*c = 1; [a,b,c].should == [1, nil, []]
|
|
119
|
+
a,b,*c = []; [a,b,c].should == [nil, nil, []]
|
|
120
|
+
a,b,*c = [1]; [a,b,c].should == [1, nil, []]
|
|
121
|
+
a,b,*c = [nil]; [a,b,c].should == [nil, nil, []]
|
|
122
|
+
a,b,*c = [[]]; [a,b,c].should == [[], nil, []]
|
|
123
|
+
a,b,*c = [1,2]; [a,b,c].should == [1,2,[]]
|
|
124
|
+
|
|
125
|
+
a,b,*c = *nil; [a,b,c].should == [nil, nil, []]
|
|
126
|
+
a,b,*c = *1; [a,b,c].should == [1, nil, []]
|
|
127
|
+
a,b,*c = *[]; [a,b,c].should == [nil, nil, []]
|
|
128
|
+
a,b,*c = *[1]; [a,b,c].should == [1, nil, []]
|
|
129
|
+
a,b,*c = *[nil]; [a,b,c].should == [nil, nil, []]
|
|
130
|
+
a,b,*c = *[[]]; [a,b,c].should == [[], nil, []]
|
|
131
|
+
a,b,*c = *[1,2]; [a,b,c].should == [1,2,[]]
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "calls to_a on the given argument when using a splat" do
|
|
135
|
+
a,b = *VariablesSpecs::ArrayLike.new([1,2]); [a,b].should == [1,2]
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "supports the {|r,| } form of block assignment" do
|
|
139
|
+
f = lambda {|r,| r.should == []}
|
|
140
|
+
f.call([], *[])
|
|
141
|
+
|
|
142
|
+
f = lambda{|x,| x}
|
|
143
|
+
f.call(42).should == 42
|
|
144
|
+
f.call([42]).should == [42]
|
|
145
|
+
f.call([[42]]).should == [[42]]
|
|
146
|
+
f.call([42,55]).should == [42,55]
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it "allows assignment through lambda" do
|
|
150
|
+
f = lambda {|r,*l| r.should == []; l.should == [1]}
|
|
151
|
+
f.call([], *[1])
|
|
152
|
+
|
|
153
|
+
f = lambda{|x| x}
|
|
154
|
+
f.call(42).should == 42
|
|
155
|
+
f.call([42]).should == [42]
|
|
156
|
+
f.call([[42]]).should == [[42]]
|
|
157
|
+
f.call([42,55]).should == [42,55]
|
|
158
|
+
|
|
159
|
+
f = lambda{|*x| x}
|
|
160
|
+
f.call(42).should == [42]
|
|
161
|
+
f.call([42]).should == [[42]]
|
|
162
|
+
f.call([[42]]).should == [[[42]]]
|
|
163
|
+
f.call([42,55]).should == [[42,55]]
|
|
164
|
+
f.call(42,55).should == [42,55]
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it "allows chained assignment" do
|
|
168
|
+
(a = 1 + b = 2 + c = 4 + d = 8).should == 15
|
|
169
|
+
d.should == 8
|
|
170
|
+
c.should == 12
|
|
171
|
+
b.should == 14
|
|
172
|
+
a.should == 15
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
describe "Assignment using expansion" do
|
|
177
|
+
ruby_version_is "" ... "1.9" do
|
|
178
|
+
it "succeeds without conversion" do
|
|
179
|
+
*x = (1..7).to_a
|
|
180
|
+
x.should == [[1, 2, 3, 4, 5, 6, 7]]
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
ruby_version_is "1.9" do
|
|
185
|
+
it "succeeds without conversion" do
|
|
186
|
+
*x = (1..7).to_a
|
|
187
|
+
x.should == [1, 2, 3, 4, 5, 6, 7]
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
describe "Basic multiple assignment" do
|
|
193
|
+
describe "with a single RHS value" do
|
|
194
|
+
it "does not call #to_ary on an Array instance" do
|
|
195
|
+
x = [1, 2]
|
|
196
|
+
x.should_not_receive(:to_ary)
|
|
197
|
+
|
|
198
|
+
a, b = x
|
|
199
|
+
a.should == 1
|
|
200
|
+
b.should == 2
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
it "does not call #to_a on an Array instance" do
|
|
204
|
+
x = [1, 2]
|
|
205
|
+
x.should_not_receive(:to_a)
|
|
206
|
+
|
|
207
|
+
a, b = x
|
|
208
|
+
a.should == 1
|
|
209
|
+
b.should == 2
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it "does not call #to_ary on an Array subclass instance" do
|
|
213
|
+
x = VariablesSpecs::ArraySubclass.new [1, 2]
|
|
214
|
+
x.should_not_receive(:to_ary)
|
|
215
|
+
|
|
216
|
+
a, b = x
|
|
217
|
+
a.should == 1
|
|
218
|
+
b.should == 2
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
it "does not call #to_a on an Array subclass instance" do
|
|
222
|
+
x = VariablesSpecs::ArraySubclass.new [1, 2]
|
|
223
|
+
x.should_not_receive(:to_a)
|
|
224
|
+
|
|
225
|
+
a, b = x
|
|
226
|
+
a.should == 1
|
|
227
|
+
b.should == 2
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
it "calls #to_ary on an object" do
|
|
231
|
+
x = mock("single rhs value for masgn")
|
|
232
|
+
x.should_receive(:to_ary).and_return([1, 2])
|
|
233
|
+
|
|
234
|
+
a, b = x
|
|
235
|
+
a.should == 1
|
|
236
|
+
b.should == 2
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
it "does not call #to_a on an object if #to_ary is not defined" do
|
|
240
|
+
x = mock("single rhs value for masgn")
|
|
241
|
+
x.should_not_receive(:to_a)
|
|
242
|
+
|
|
243
|
+
a, b = x
|
|
244
|
+
a.should == x
|
|
245
|
+
b.should be_nil
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it "does not call #to_a on a String" do
|
|
249
|
+
x = "one\ntwo"
|
|
250
|
+
|
|
251
|
+
a, b = x
|
|
252
|
+
a.should == x
|
|
253
|
+
b.should be_nil
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
describe "with a splatted single RHS value" do
|
|
258
|
+
it "does not call #to_ary on an Array instance" do
|
|
259
|
+
x = [1, 2]
|
|
260
|
+
x.should_not_receive(:to_ary)
|
|
261
|
+
|
|
262
|
+
a, b = *x
|
|
263
|
+
a.should == 1
|
|
264
|
+
b.should == 2
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
it "does not call #to_a on an Array instance" do
|
|
268
|
+
x = [1, 2]
|
|
269
|
+
x.should_not_receive(:to_a)
|
|
270
|
+
|
|
271
|
+
a, b = *x
|
|
272
|
+
a.should == 1
|
|
273
|
+
b.should == 2
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
it "does not call #to_ary on an Array subclass instance" do
|
|
277
|
+
x = VariablesSpecs::ArraySubclass.new [1, 2]
|
|
278
|
+
x.should_not_receive(:to_ary)
|
|
279
|
+
|
|
280
|
+
a, b = *x
|
|
281
|
+
a.should == 1
|
|
282
|
+
b.should == 2
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
it "does not call #to_a on an Array subclass instance" do
|
|
286
|
+
x = VariablesSpecs::ArraySubclass.new [1, 2]
|
|
287
|
+
x.should_not_receive(:to_a)
|
|
288
|
+
|
|
289
|
+
a, b = *x
|
|
290
|
+
a.should == 1
|
|
291
|
+
b.should == 2
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
it "calls #to_a on an object if #to_ary is not defined" do
|
|
295
|
+
x = mock("single splatted rhs value for masgn")
|
|
296
|
+
x.should_receive(:to_a).and_return([1, 2])
|
|
297
|
+
|
|
298
|
+
a, b = *x
|
|
299
|
+
a.should == 1
|
|
300
|
+
b.should == 2
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
ruby_version_is ""..."1.9" do
|
|
304
|
+
it "calls #to_ary on an object" do
|
|
305
|
+
x = mock("single splatted rhs value for masgn")
|
|
306
|
+
x.should_receive(:to_ary).and_return([1, 2])
|
|
307
|
+
|
|
308
|
+
a, b = *x
|
|
309
|
+
a.should == 1
|
|
310
|
+
b.should == 2
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
it "calls #to_a on a String" do
|
|
314
|
+
x = "one\ntwo"
|
|
315
|
+
|
|
316
|
+
a, b = *x
|
|
317
|
+
a.should == "one\n"
|
|
318
|
+
b.should == "two"
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
ruby_version_is "1.9" do
|
|
323
|
+
it "does not call #to_ary on an object" do
|
|
324
|
+
x = mock("single splatted rhs value for masgn")
|
|
325
|
+
x.should_not_receive(:to_ary)
|
|
326
|
+
|
|
327
|
+
a, b = *x
|
|
328
|
+
a.should == x
|
|
329
|
+
b.should be_nil
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
it "does not call #to_a on a String" do
|
|
333
|
+
x = "one\ntwo"
|
|
334
|
+
|
|
335
|
+
a, b = *x
|
|
336
|
+
a.should == x
|
|
337
|
+
b.should be_nil
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
describe "Assigning multiple values" do
|
|
344
|
+
it "allows parallel assignment" do
|
|
345
|
+
a, b = 1, 2
|
|
346
|
+
a.should == 1
|
|
347
|
+
b.should == 2
|
|
348
|
+
|
|
349
|
+
# a, = 1,2
|
|
350
|
+
a.should == 1
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
it "allows safe parallel swapping" do
|
|
354
|
+
a, b = 1, 2
|
|
355
|
+
a, b = b, a
|
|
356
|
+
a.should == 2
|
|
357
|
+
b.should == 1
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
not_compliant_on :rubinius do
|
|
361
|
+
it "returns the rhs values used for assignment as an array" do
|
|
362
|
+
# x = begin; a, b, c = 1, 2, 3; end
|
|
363
|
+
x.should == [1,2,3]
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
ruby_version_is "" ... "1.9" do
|
|
368
|
+
it "wraps a single value in an Array" do
|
|
369
|
+
*a = 1
|
|
370
|
+
a.should == [1]
|
|
371
|
+
|
|
372
|
+
b = [1]
|
|
373
|
+
*a = b
|
|
374
|
+
a.should == [b]
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
ruby_version_is "1.9" do
|
|
379
|
+
it "wraps a single value in an Array if it's not already one" do
|
|
380
|
+
*a = 1
|
|
381
|
+
a.should == [1]
|
|
382
|
+
|
|
383
|
+
b = [1]
|
|
384
|
+
*a = b
|
|
385
|
+
a.should == b
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
it "evaluates rhs left-to-right" do
|
|
390
|
+
a = VariablesSpecs::ParAsgn.new
|
|
391
|
+
d, e ,f = a.inc, a.inc, a.inc
|
|
392
|
+
d.should == 1
|
|
393
|
+
e.should == 2
|
|
394
|
+
f.should == 3
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
it "supports parallel assignment to lhs args via object.method=" do
|
|
398
|
+
a = VariablesSpecs::ParAsgn.new
|
|
399
|
+
a.x, b = 1, 2
|
|
400
|
+
|
|
401
|
+
a.x.should == 1
|
|
402
|
+
b.should == 2
|
|
403
|
+
|
|
404
|
+
c = VariablesSpecs::ParAsgn.new
|
|
405
|
+
c.x, a.x = a.x, b
|
|
406
|
+
|
|
407
|
+
c.x.should == 1
|
|
408
|
+
a.x.should == 2
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
it "supports parallel assignment to lhs args using []=" do
|
|
412
|
+
a = [1,2,3]
|
|
413
|
+
a[3], b = 4,5
|
|
414
|
+
|
|
415
|
+
a.should == [1,2,3,4]
|
|
416
|
+
b.should == 5
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
it "bundles remaining values to an array when using the splat operator" do
|
|
420
|
+
a, *b = 1, 2, 3
|
|
421
|
+
a.should == 1
|
|
422
|
+
b.should == [2, 3]
|
|
423
|
+
|
|
424
|
+
*a = 1, 2, 3
|
|
425
|
+
a.should == [1, 2, 3]
|
|
426
|
+
|
|
427
|
+
*a = 4
|
|
428
|
+
a.should == [4]
|
|
429
|
+
|
|
430
|
+
*a = nil
|
|
431
|
+
a.should == [nil]
|
|
432
|
+
|
|
433
|
+
a, = *[1]
|
|
434
|
+
a.should == 1
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
ruby_version_is ""..."1.9" do
|
|
438
|
+
it "calls #to_ary on rhs arg if rhs has only a single arg" do
|
|
439
|
+
x = VariablesSpecs::ParAsgn.new
|
|
440
|
+
a,b,c = x
|
|
441
|
+
a.should == 1
|
|
442
|
+
b.should == 2
|
|
443
|
+
c.should == 3
|
|
444
|
+
|
|
445
|
+
a,b,c = x,5
|
|
446
|
+
a.should == x
|
|
447
|
+
b.should == 5
|
|
448
|
+
c.should == nil
|
|
449
|
+
|
|
450
|
+
a,b,c = 5,x
|
|
451
|
+
a.should == 5
|
|
452
|
+
b.should == x
|
|
453
|
+
c.should == nil
|
|
454
|
+
|
|
455
|
+
a,b,*c = x,5
|
|
456
|
+
a.should == x
|
|
457
|
+
b.should == 5
|
|
458
|
+
c.should == []
|
|
459
|
+
|
|
460
|
+
# a,(b,c) = 5,x
|
|
461
|
+
a.should == 5
|
|
462
|
+
b.should == 1
|
|
463
|
+
c.should == 2
|
|
464
|
+
|
|
465
|
+
# a,(b,*c) = 5,x
|
|
466
|
+
a.should == 5
|
|
467
|
+
b.should == 1
|
|
468
|
+
c.should == [2,3,4]
|
|
469
|
+
|
|
470
|
+
# a,(b,(*c)) = 5,x
|
|
471
|
+
a.should == 5
|
|
472
|
+
b.should == 1
|
|
473
|
+
c.should == [2]
|
|
474
|
+
|
|
475
|
+
# a,(b,(*c),(*d)) = 5,x
|
|
476
|
+
a.should == 5
|
|
477
|
+
b.should == 1
|
|
478
|
+
c.should == [2]
|
|
479
|
+
d.should == [3]
|
|
480
|
+
|
|
481
|
+
# a,(b,(*c),(d,*e)) = 5,x
|
|
482
|
+
a.should == 5
|
|
483
|
+
b.should == 1
|
|
484
|
+
c.should == [2]
|
|
485
|
+
d.should == 3
|
|
486
|
+
e.should == []
|
|
487
|
+
end
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
ruby_version_is "1.9" do
|
|
491
|
+
it "calls #to_ary on RHS arg if the corresponding LHS var is a splat" do
|
|
492
|
+
x = VariablesSpecs::ParAsgn.new
|
|
493
|
+
|
|
494
|
+
# a,(*b),c = 5,x
|
|
495
|
+
a.should == 5
|
|
496
|
+
b.should == x.to_ary
|
|
497
|
+
c.should == nil
|
|
498
|
+
end
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
ruby_version_is ""..."1.9" do
|
|
502
|
+
it "doen't call #to_ary on RHS arg when the corresponding LHS var is a splat" do
|
|
503
|
+
x = VariablesSpecs::ParAsgn.new
|
|
504
|
+
|
|
505
|
+
# a,(*b),c = 5,x
|
|
506
|
+
a.should == 5
|
|
507
|
+
b.should == [x]
|
|
508
|
+
c.should == nil
|
|
509
|
+
end
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
it "allows complex parallel assignment" do
|
|
513
|
+
# a, (b, c), d = 1, [2, 3], 4
|
|
514
|
+
a.should == 1
|
|
515
|
+
b.should == 2
|
|
516
|
+
c.should == 3
|
|
517
|
+
d.should == 4
|
|
518
|
+
|
|
519
|
+
# x, (y, z) = 1, 2, 3
|
|
520
|
+
[x,y,z].should == [1,2,nil]
|
|
521
|
+
# x, (y, z) = 1, [2,3]
|
|
522
|
+
[x,y,z].should == [1,2,3]
|
|
523
|
+
# x, (y, z) = 1, [2]
|
|
524
|
+
[x,y,z].should == [1,2,nil]
|
|
525
|
+
|
|
526
|
+
# a,(b,c,*d),(e,f),*g = 0,[1,2,3,4],[5,6],7,8
|
|
527
|
+
a.should == 0
|
|
528
|
+
b.should == 1
|
|
529
|
+
c.should == 2
|
|
530
|
+
d.should == [3,4]
|
|
531
|
+
e.should == 5
|
|
532
|
+
f.should == 6
|
|
533
|
+
g.should == [7,8]
|
|
534
|
+
|
|
535
|
+
x = VariablesSpecs::ParAsgn.new
|
|
536
|
+
# a,(b,c,*d),(e,f),*g = 0,x,[5,6],7,8
|
|
537
|
+
a.should == 0
|
|
538
|
+
b.should == 1
|
|
539
|
+
c.should == 2
|
|
540
|
+
d.should == [3,4]
|
|
541
|
+
e.should == 5
|
|
542
|
+
f.should == 6
|
|
543
|
+
g.should == [7,8]
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
it "allows a lhs arg to be used in another lhs args parallel assignment" do
|
|
547
|
+
c = [4,5,6]
|
|
548
|
+
a,b,c[a] = 1,2,3
|
|
549
|
+
a.should == 1
|
|
550
|
+
b.should == 2
|
|
551
|
+
c.should == [4,3,6]
|
|
552
|
+
|
|
553
|
+
c[a],b,a = 7,8,9
|
|
554
|
+
a.should == 9
|
|
555
|
+
b.should == 8
|
|
556
|
+
c.should == [4,7,6]
|
|
557
|
+
end
|
|
558
|
+
end
|
|
559
|
+
|
|
560
|
+
describe "Conditional assignment" do
|
|
561
|
+
it "assigns the lhs if previously unassigned" do
|
|
562
|
+
a=[]
|
|
563
|
+
a[0] ||= "bar"
|
|
564
|
+
a[0].should == "bar"
|
|
565
|
+
|
|
566
|
+
h={}
|
|
567
|
+
h["foo"] ||= "bar"
|
|
568
|
+
h["foo"].should == "bar"
|
|
569
|
+
|
|
570
|
+
h["foo".to_sym] ||= "bar"
|
|
571
|
+
h["foo".to_sym].should == "bar"
|
|
572
|
+
|
|
573
|
+
aa = 5
|
|
574
|
+
aa ||= 25
|
|
575
|
+
aa.should == 5
|
|
576
|
+
|
|
577
|
+
bb ||= 25
|
|
578
|
+
bb.should == 25
|
|
579
|
+
|
|
580
|
+
cc &&=33
|
|
581
|
+
cc.should == nil
|
|
582
|
+
|
|
583
|
+
cc = 5
|
|
584
|
+
cc &&=44
|
|
585
|
+
cc.should == 44
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
it "checks for class variable definition before fetching its value" do
|
|
589
|
+
class VariableSpecCVarSpec
|
|
590
|
+
@@cvarspec ||= 5
|
|
591
|
+
@@cvarspec.should == 5
|
|
592
|
+
end
|
|
593
|
+
end
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
describe "Unconditional operator assignment 'var op= expr'" do
|
|
597
|
+
it "is equivalent to 'var = var op expr'" do
|
|
598
|
+
x = 13
|
|
599
|
+
(x += 5).should == 18
|
|
600
|
+
x.should == 18
|
|
601
|
+
|
|
602
|
+
x = 17
|
|
603
|
+
(x -= 11).should == 6
|
|
604
|
+
x.should == 6
|
|
605
|
+
|
|
606
|
+
x = 2
|
|
607
|
+
(x *= 5).should == 10
|
|
608
|
+
x.should == 10
|
|
609
|
+
|
|
610
|
+
x = 36
|
|
611
|
+
(x /= 9).should == 4
|
|
612
|
+
x.should == 4
|
|
613
|
+
|
|
614
|
+
x = 23
|
|
615
|
+
(x %= 5).should == 3
|
|
616
|
+
x.should == 3
|
|
617
|
+
(x %= 3).should == 0
|
|
618
|
+
x.should == 0
|
|
619
|
+
|
|
620
|
+
x = 2
|
|
621
|
+
(x **= 3).should == 8
|
|
622
|
+
x.should == 8
|
|
623
|
+
|
|
624
|
+
x = 4
|
|
625
|
+
(x |= 3).should == 7
|
|
626
|
+
x.should == 7
|
|
627
|
+
(x |= 4).should == 7
|
|
628
|
+
x.should == 7
|
|
629
|
+
|
|
630
|
+
x = 6
|
|
631
|
+
(x &= 3).should == 2
|
|
632
|
+
x.should == 2
|
|
633
|
+
(x &= 4).should == 0
|
|
634
|
+
x.should == 0
|
|
635
|
+
|
|
636
|
+
# XOR
|
|
637
|
+
x = 2
|
|
638
|
+
(x ^= 3).should == 1
|
|
639
|
+
x.should == 1
|
|
640
|
+
(x ^= 4).should == 5
|
|
641
|
+
x.should == 5
|
|
642
|
+
|
|
643
|
+
# Bit-shift left
|
|
644
|
+
x = 17
|
|
645
|
+
(x <<= 3).should == 136
|
|
646
|
+
x.should == 136
|
|
647
|
+
|
|
648
|
+
# Bit-shift right
|
|
649
|
+
x = 5
|
|
650
|
+
(x >>= 1).should == 2
|
|
651
|
+
x.should == 2
|
|
652
|
+
end
|
|
653
|
+
end
|
|
654
|
+
|
|
655
|
+
describe "Conditional operator assignment 'var op= expr'" do
|
|
656
|
+
it "assigns the lhs if its truthiness is false for ||, true for &&" do
|
|
657
|
+
x = nil
|
|
658
|
+
(x ||= 17).should == 17
|
|
659
|
+
x.should == 17
|
|
660
|
+
(x ||= 2).should == 17
|
|
661
|
+
x.should == 17
|
|
662
|
+
|
|
663
|
+
x = false
|
|
664
|
+
(x &&= true).should == false
|
|
665
|
+
x.should == false
|
|
666
|
+
(x &&= false).should == false
|
|
667
|
+
x.should == false
|
|
668
|
+
x = true
|
|
669
|
+
(x &&= true).should == true
|
|
670
|
+
x.should == true
|
|
671
|
+
(x &&= false).should == false
|
|
672
|
+
x.should == false
|
|
673
|
+
end
|
|
674
|
+
|
|
675
|
+
it "may not assign at all, depending on the truthiness of lhs" do
|
|
676
|
+
Object.new.instance_eval do
|
|
677
|
+
@falsey = false
|
|
678
|
+
@truthy = true
|
|
679
|
+
freeze
|
|
680
|
+
# lambda{ @truthy ||= 42 }.should_not raise_error
|
|
681
|
+
# lambda{ @falsey &&= 42 }.should_not raise_error
|
|
682
|
+
end
|
|
683
|
+
end
|
|
684
|
+
|
|
685
|
+
it "uses short-circuit arg evaluation" do
|
|
686
|
+
x = 8
|
|
687
|
+
y = VariablesSpecs::OpAsgn.new
|
|
688
|
+
(x ||= y.do_side_effect).should == 8
|
|
689
|
+
y.side_effect.should == nil
|
|
690
|
+
|
|
691
|
+
x = nil
|
|
692
|
+
(x &&= y.do_side_effect).should == nil
|
|
693
|
+
y.side_effect.should == nil
|
|
694
|
+
|
|
695
|
+
y.a = 5
|
|
696
|
+
(x ||= y.do_side_effect).should == 5
|
|
697
|
+
y.side_effect.should == true
|
|
698
|
+
end
|
|
699
|
+
end
|
|
700
|
+
|
|
701
|
+
describe "Unconditional operator assignment 'obj.meth op= expr'" do
|
|
702
|
+
it "is equivalent to 'obj.meth = obj.meth op expr'" do
|
|
703
|
+
@x = VariablesSpecs::OpAsgn.new
|
|
704
|
+
@x.a = 13
|
|
705
|
+
(@x.a += 5).should == 18
|
|
706
|
+
@x.a.should == 18
|
|
707
|
+
|
|
708
|
+
@x.a = 17
|
|
709
|
+
(@x.a -= 11).should == 6
|
|
710
|
+
@x.a.should == 6
|
|
711
|
+
|
|
712
|
+
@x.a = 2
|
|
713
|
+
(@x.a *= 5).should == 10
|
|
714
|
+
@x.a.should == 10
|
|
715
|
+
|
|
716
|
+
@x.a = 36
|
|
717
|
+
(@x.a /= 9).should == 4
|
|
718
|
+
@x.a.should == 4
|
|
719
|
+
|
|
720
|
+
@x.a = 23
|
|
721
|
+
(@x.a %= 5).should == 3
|
|
722
|
+
@x.a.should == 3
|
|
723
|
+
(@x.a %= 3).should == 0
|
|
724
|
+
@x.a.should == 0
|
|
725
|
+
|
|
726
|
+
@x.a = 2
|
|
727
|
+
(@x.a **= 3).should == 8
|
|
728
|
+
@x.a.should == 8
|
|
729
|
+
|
|
730
|
+
@x.a = 4
|
|
731
|
+
(@x.a |= 3).should == 7
|
|
732
|
+
@x.a.should == 7
|
|
733
|
+
(@x.a |= 4).should == 7
|
|
734
|
+
@x.a.should == 7
|
|
735
|
+
|
|
736
|
+
@x.a = 6
|
|
737
|
+
(@x.a &= 3).should == 2
|
|
738
|
+
@x.a.should == 2
|
|
739
|
+
(@x.a &= 4).should == 0
|
|
740
|
+
@x.a.should == 0
|
|
741
|
+
|
|
742
|
+
# XOR
|
|
743
|
+
@x.a = 2
|
|
744
|
+
(@x.a ^= 3).should == 1
|
|
745
|
+
@x.a.should == 1
|
|
746
|
+
(@x.a ^= 4).should == 5
|
|
747
|
+
@x.a.should == 5
|
|
748
|
+
|
|
749
|
+
@x.a = 17
|
|
750
|
+
(@x.a <<= 3).should == 136
|
|
751
|
+
@x.a.should == 136
|
|
752
|
+
|
|
753
|
+
@x.a = 5
|
|
754
|
+
(@x.a >>= 1).should == 2
|
|
755
|
+
@x.a.should == 2
|
|
756
|
+
end
|
|
757
|
+
end
|
|
758
|
+
|
|
759
|
+
describe "Conditional operator assignment 'obj.meth op= expr'" do
|
|
760
|
+
it "is equivalent to 'obj.meth op obj.meth = expr'" do
|
|
761
|
+
@x = VariablesSpecs::OpAsgn.new
|
|
762
|
+
@x.a = nil
|
|
763
|
+
(@x.a ||= 17).should == 17
|
|
764
|
+
@x.a.should == 17
|
|
765
|
+
(@x.a ||= 2).should == 17
|
|
766
|
+
@x.a.should == 17
|
|
767
|
+
|
|
768
|
+
@x.a = false
|
|
769
|
+
(@x.a &&= true).should == false
|
|
770
|
+
@x.a.should == false
|
|
771
|
+
(@x.a &&= false).should == false
|
|
772
|
+
@x.a.should == false
|
|
773
|
+
@x.a = true
|
|
774
|
+
(@x.a &&= true).should == true
|
|
775
|
+
@x.a.should == true
|
|
776
|
+
(@x.a &&= false).should == false
|
|
777
|
+
@x.a.should == false
|
|
778
|
+
end
|
|
779
|
+
|
|
780
|
+
it "may not assign at all, depending on the truthiness of lhs" do
|
|
781
|
+
m = mock("object")
|
|
782
|
+
m.should_receive(:foo).and_return(:truthy)
|
|
783
|
+
m.should_not_receive(:foo=)
|
|
784
|
+
# m.foo ||= 42
|
|
785
|
+
|
|
786
|
+
m.should_receive(:bar).and_return(false)
|
|
787
|
+
m.should_not_receive(:bar=)
|
|
788
|
+
# m.bar &&= 42
|
|
789
|
+
end
|
|
790
|
+
|
|
791
|
+
it "uses short-circuit arg evaluation" do
|
|
792
|
+
x = 8
|
|
793
|
+
y = VariablesSpecs::OpAsgn.new
|
|
794
|
+
(x ||= y.do_side_effect).should == 8
|
|
795
|
+
y.side_effect.should == nil
|
|
796
|
+
|
|
797
|
+
x = nil
|
|
798
|
+
(x &&= y.do_side_effect).should == nil
|
|
799
|
+
y.side_effect.should == nil
|
|
800
|
+
|
|
801
|
+
y.a = 5
|
|
802
|
+
(x ||= y.do_side_effect).should == 5
|
|
803
|
+
y.side_effect.should == true
|
|
804
|
+
end
|
|
805
|
+
end
|
|
806
|
+
|
|
807
|
+
describe "Operator assignment 'obj.meth op= expr'" do
|
|
808
|
+
it "evaluates lhs one time" do
|
|
809
|
+
x = VariablesSpecs::OpAsgn.new
|
|
810
|
+
x.a = 5
|
|
811
|
+
(x.do_more_side_effects.a += 5).should == 15
|
|
812
|
+
x.a.should == 15
|
|
813
|
+
|
|
814
|
+
x.a = 5
|
|
815
|
+
(x.do_more_side_effects.a -= 4).should == 6
|
|
816
|
+
x.a.should == 6
|
|
817
|
+
|
|
818
|
+
x.a = 2
|
|
819
|
+
(x.do_more_side_effects.a *= 5).should == 35
|
|
820
|
+
x.a.should == 35
|
|
821
|
+
|
|
822
|
+
x.a = 31
|
|
823
|
+
(x.do_more_side_effects.a /= 9).should == 4
|
|
824
|
+
x.a.should == 4
|
|
825
|
+
|
|
826
|
+
x.a = 18
|
|
827
|
+
(x.do_more_side_effects.a %= 5).should == 3
|
|
828
|
+
x.a.should == 3
|
|
829
|
+
|
|
830
|
+
x.a = 0
|
|
831
|
+
(x.do_more_side_effects.a **= 3).should == 125
|
|
832
|
+
x.a.should == 125
|
|
833
|
+
|
|
834
|
+
x.a = -1
|
|
835
|
+
(x.do_more_side_effects.a |= 3).should == 7
|
|
836
|
+
x.a.should == 7
|
|
837
|
+
|
|
838
|
+
x.a = 1
|
|
839
|
+
(x.do_more_side_effects.a &= 3).should == 2
|
|
840
|
+
x.a.should == 2
|
|
841
|
+
|
|
842
|
+
# XOR
|
|
843
|
+
x.a = -3
|
|
844
|
+
(x.do_more_side_effects.a ^= 3).should == 1
|
|
845
|
+
x.a.should == 1
|
|
846
|
+
|
|
847
|
+
x.a = 12
|
|
848
|
+
(x.do_more_side_effects.a <<= 3).should == 136
|
|
849
|
+
x.a.should == 136
|
|
850
|
+
|
|
851
|
+
x.a = 0
|
|
852
|
+
(x.do_more_side_effects.a >>= 1).should == 2
|
|
853
|
+
x.a.should == 2
|
|
854
|
+
|
|
855
|
+
x.a = nil
|
|
856
|
+
x.b = 0
|
|
857
|
+
(x.do_bool_side_effects.a ||= 17).should == 17
|
|
858
|
+
x.a.should == 17
|
|
859
|
+
x.b.should == 1
|
|
860
|
+
|
|
861
|
+
x.a = false
|
|
862
|
+
x.b = 0
|
|
863
|
+
(x.do_bool_side_effects.a &&= true).should == false
|
|
864
|
+
x.a.should == false
|
|
865
|
+
x.b.should == 1
|
|
866
|
+
(x.do_bool_side_effects.a &&= false).should == false
|
|
867
|
+
x.a.should == false
|
|
868
|
+
x.b.should == 2
|
|
869
|
+
x.a = true
|
|
870
|
+
x.b = 0
|
|
871
|
+
(x.do_bool_side_effects.a &&= true).should == true
|
|
872
|
+
x.a.should == true
|
|
873
|
+
x.b.should == 1
|
|
874
|
+
(x.do_bool_side_effects.a &&= false).should == false
|
|
875
|
+
x.a.should == false
|
|
876
|
+
x.b.should == 2
|
|
877
|
+
end
|
|
878
|
+
end
|
|
879
|
+
|
|
880
|
+
describe "Unconditional operator assignment 'obj[idx] op= expr'" do
|
|
881
|
+
it "is equivalent to 'obj[idx] = obj[idx] op expr'" do
|
|
882
|
+
# x = [2,13,7]
|
|
883
|
+
# (x[1] += 5).should == 18
|
|
884
|
+
# x.should == [2,18,7]
|
|
885
|
+
|
|
886
|
+
# x = [17,6]
|
|
887
|
+
# (x[0] -= 11).should == 6
|
|
888
|
+
# x.should == [6,6]
|
|
889
|
+
|
|
890
|
+
# x = [nil,2,28]
|
|
891
|
+
# (x[2] *= 2).should == 56
|
|
892
|
+
# x.should == [nil,2,56]
|
|
893
|
+
|
|
894
|
+
# x = [3,9,36]
|
|
895
|
+
# (x[2] /= x[1]).should == 4
|
|
896
|
+
# x.should == [3,9,4]
|
|
897
|
+
|
|
898
|
+
# x = [23,4]
|
|
899
|
+
# (x[0] %= 5).should == 3
|
|
900
|
+
# x.should == [3,4]
|
|
901
|
+
# (x[0] %= 3).should == 0
|
|
902
|
+
# x.should == [0,4]
|
|
903
|
+
|
|
904
|
+
# x = [1,2,3]
|
|
905
|
+
# (x[1] **= 3).should == 8
|
|
906
|
+
# x.should == [1,8,3]
|
|
907
|
+
|
|
908
|
+
# x = [4,5,nil]
|
|
909
|
+
# (x[0] |= 3).should == 7
|
|
910
|
+
# x.should == [7,5,nil]
|
|
911
|
+
# (x[0] |= 4).should == 7
|
|
912
|
+
# x.should == [7,5,nil]
|
|
913
|
+
|
|
914
|
+
# x = [3,6,9]
|
|
915
|
+
# (x[1] &= 3).should == 2
|
|
916
|
+
# x.should == [3,2,9]
|
|
917
|
+
# (x[1] &= 4).should == 0
|
|
918
|
+
# x.should == [3,0,9]
|
|
919
|
+
|
|
920
|
+
# # XOR
|
|
921
|
+
# x = [0,1,2]
|
|
922
|
+
# (x[2] ^= 3).should == 1
|
|
923
|
+
# x.should == [0,1,1]
|
|
924
|
+
# (x[2] ^= 4).should == 5
|
|
925
|
+
# x.should == [0,1,5]
|
|
926
|
+
|
|
927
|
+
# x = [17]
|
|
928
|
+
# (x[0] <<= 3).should == 136
|
|
929
|
+
# x.should == [136]
|
|
930
|
+
|
|
931
|
+
# x = [nil,5,8]
|
|
932
|
+
# (x[1] >>= 1).should == 2
|
|
933
|
+
# x.should == [nil,2,8]
|
|
934
|
+
end
|
|
935
|
+
end
|
|
936
|
+
|
|
937
|
+
describe "Conditional operator assignment 'obj[idx] op= expr'" do
|
|
938
|
+
it "is equivalent to 'obj[idx] op obj[idx] = expr'" do
|
|
939
|
+
# x = [1,nil,12]
|
|
940
|
+
# (x[1] ||= 17).should == 17
|
|
941
|
+
# x.should == [1,17,12]
|
|
942
|
+
# (x[1] ||= 2).should == 17
|
|
943
|
+
# x.should == [1,17,12]
|
|
944
|
+
|
|
945
|
+
# x = [true, false, false]
|
|
946
|
+
# (x[1] &&= true).should == false
|
|
947
|
+
# x.should == [true, false, false]
|
|
948
|
+
# (x[1] &&= false).should == false
|
|
949
|
+
# x.should == [true, false, false]
|
|
950
|
+
# (x[0] &&= true).should == true
|
|
951
|
+
# x.should == [true, false, false]
|
|
952
|
+
# (x[0] &&= false).should == false
|
|
953
|
+
# x.should == [false, false, false]
|
|
954
|
+
end
|
|
955
|
+
|
|
956
|
+
it "may not assign at all, depending on the truthiness of lhs" do
|
|
957
|
+
# m = mock("object")
|
|
958
|
+
# m.should_receive(:[]).and_return(:truthy)
|
|
959
|
+
# m.should_not_receive(:[]=)
|
|
960
|
+
# m[:foo] ||= 42
|
|
961
|
+
|
|
962
|
+
# m = mock("object")
|
|
963
|
+
# m.should_receive(:[]).and_return(false)
|
|
964
|
+
# m.should_not_receive(:[]=)
|
|
965
|
+
# m[:bar] &&= 42
|
|
966
|
+
end
|
|
967
|
+
|
|
968
|
+
it "uses short-circuit arg evaluation" do
|
|
969
|
+
# x = 8
|
|
970
|
+
# y = VariablesSpecs::OpAsgn.new
|
|
971
|
+
# (x ||= y.do_side_effect).should == 8
|
|
972
|
+
# y.side_effect.should == nil
|
|
973
|
+
|
|
974
|
+
# x = nil
|
|
975
|
+
# (x &&= y.do_side_effect).should == nil
|
|
976
|
+
# y.side_effect.should == nil
|
|
977
|
+
|
|
978
|
+
# y.a = 5
|
|
979
|
+
# (x ||= y.do_side_effect).should == 5
|
|
980
|
+
# y.side_effect.should == true
|
|
981
|
+
end
|
|
982
|
+
end
|
|
983
|
+
|
|
984
|
+
describe "Operator assignment 'obj[idx] op= expr'" do
|
|
985
|
+
class ArrayWithDefaultIndex < Array
|
|
986
|
+
def [](index=nil)
|
|
987
|
+
super(index || 0)
|
|
988
|
+
end
|
|
989
|
+
|
|
990
|
+
def []=(first_arg, second_arg=nil)
|
|
991
|
+
if second_arg
|
|
992
|
+
index = fist_arg
|
|
993
|
+
value = second_arg
|
|
994
|
+
else
|
|
995
|
+
index = 0
|
|
996
|
+
value = first_arg
|
|
997
|
+
end
|
|
998
|
+
|
|
999
|
+
super(index, value)
|
|
1000
|
+
end
|
|
1001
|
+
end
|
|
1002
|
+
|
|
1003
|
+
it "handles empty index (idx) arguments" do
|
|
1004
|
+
# array = ArrayWithDefaultIndex.new
|
|
1005
|
+
# array << 1
|
|
1006
|
+
# (array[] += 5).should == 6
|
|
1007
|
+
end
|
|
1008
|
+
|
|
1009
|
+
it "handles complex index (idx) arguments" do
|
|
1010
|
+
# x = [1,2,3,4]
|
|
1011
|
+
# (x[0,2] += [5]).should == [1,2,5]
|
|
1012
|
+
# x.should == [1,2,5,3,4]
|
|
1013
|
+
# (x[0,2] += [3,4]).should == [1,2,3,4]
|
|
1014
|
+
# x.should == [1,2,3,4,5,3,4]
|
|
1015
|
+
|
|
1016
|
+
# (x[2..3] += [8]).should == [3,4,8]
|
|
1017
|
+
# x.should == [1,2,3,4,8,5,3,4]
|
|
1018
|
+
|
|
1019
|
+
# y = VariablesSpecs::OpAsgn.new
|
|
1020
|
+
# y.a = 1
|
|
1021
|
+
# (x[y.do_side_effect] *= 2).should == 4
|
|
1022
|
+
# x.should == [1,4,3,4,8,5,3,4]
|
|
1023
|
+
|
|
1024
|
+
# h = {'key1' => 23, 'key2' => 'val'}
|
|
1025
|
+
# (h['key1'] %= 5).should == 3
|
|
1026
|
+
# (h['key2'] += 'ue').should == 'value'
|
|
1027
|
+
# h.should == {'key1' => 3, 'key2' => 'value'}
|
|
1028
|
+
end
|
|
1029
|
+
|
|
1030
|
+
it "handles empty splat index (idx) arguments" do
|
|
1031
|
+
# array = ArrayWithDefaultIndex.new
|
|
1032
|
+
# array << 5
|
|
1033
|
+
# splat_index = []
|
|
1034
|
+
|
|
1035
|
+
# (array[*splat_index] += 5).should == 10
|
|
1036
|
+
# array.should== [10]
|
|
1037
|
+
end
|
|
1038
|
+
|
|
1039
|
+
it "handles single splat index (idx) arguments" do
|
|
1040
|
+
# array = [1,2,3,4]
|
|
1041
|
+
# splat_index = [0]
|
|
1042
|
+
|
|
1043
|
+
# (array[*splat_index] += 5).should == 6
|
|
1044
|
+
# array.should == [6,2,3,4]
|
|
1045
|
+
end
|
|
1046
|
+
|
|
1047
|
+
it "handles multiple splat index (idx) arguments" do
|
|
1048
|
+
# array = [1,2,3,4]
|
|
1049
|
+
# splat_index = [0,2]
|
|
1050
|
+
|
|
1051
|
+
# (array[*splat_index] += [5]).should == [1,2,5]
|
|
1052
|
+
# array.should == [1,2,5,3,4]
|
|
1053
|
+
end
|
|
1054
|
+
|
|
1055
|
+
it "handles splat index (idx) arguments with normal arguments" do
|
|
1056
|
+
# array = [1,2,3,4]
|
|
1057
|
+
# splat_index = [2]
|
|
1058
|
+
|
|
1059
|
+
# (array[0, *splat_index] += [5]).should == [1,2,5]
|
|
1060
|
+
# array.should == [1,2,5,3,4]
|
|
1061
|
+
end
|
|
1062
|
+
|
|
1063
|
+
# This example fails on 1.9 because of bug #2050
|
|
1064
|
+
it "returns result of rhs not result of []=" do
|
|
1065
|
+
# a = VariablesSpecs::Hashalike.new
|
|
1066
|
+
|
|
1067
|
+
# (a[123] = 2).should == 2
|
|
1068
|
+
# (a[123] += 2).should == 125
|
|
1069
|
+
# (a[123] -= 2).should == 121
|
|
1070
|
+
# (a[123] *= 2).should == 246
|
|
1071
|
+
# # Guard against the Mathn library
|
|
1072
|
+
# # TODO: Make these specs not rely on specific behaviour / result values
|
|
1073
|
+
# # by using mocks.
|
|
1074
|
+
# conflicts_with :Prime do
|
|
1075
|
+
# (a[123] /= 2).should == 61
|
|
1076
|
+
# end
|
|
1077
|
+
# (a[123] %= 2).should == 1
|
|
1078
|
+
# (a[123] **= 2).should == 15129
|
|
1079
|
+
# (a[123] |= 2).should == 123
|
|
1080
|
+
# (a[123] &= 2).should == 2
|
|
1081
|
+
# (a[123] ^= 2).should == 121
|
|
1082
|
+
# (a[123] <<= 2).should == 492
|
|
1083
|
+
# (a[123] >>= 2).should == 30
|
|
1084
|
+
# (a[123] ||= 2).should == 123
|
|
1085
|
+
# (a[nil] ||= 2).should == 2
|
|
1086
|
+
# (a[123] &&= 2).should == 2
|
|
1087
|
+
# (a[nil] &&= 2).should == nil
|
|
1088
|
+
end
|
|
1089
|
+
end
|
|
1090
|
+
|
|
1091
|
+
describe "Single assignment" do
|
|
1092
|
+
it "Assignment does not modify the lhs, it reassigns its reference" do
|
|
1093
|
+
a = 'Foobar'
|
|
1094
|
+
b = a
|
|
1095
|
+
b = 'Bazquux'
|
|
1096
|
+
a.should == 'Foobar'
|
|
1097
|
+
b.should == 'Bazquux'
|
|
1098
|
+
end
|
|
1099
|
+
|
|
1100
|
+
it "Assignment does not copy the object being assigned, just creates a new reference to it" do
|
|
1101
|
+
a = []
|
|
1102
|
+
b = a
|
|
1103
|
+
b << 1
|
|
1104
|
+
a.should == [1]
|
|
1105
|
+
end
|
|
1106
|
+
|
|
1107
|
+
it "If rhs has multiple arguments, lhs becomes an Array of them" do
|
|
1108
|
+
a = 1, 2, 3
|
|
1109
|
+
a.should == [1, 2, 3]
|
|
1110
|
+
|
|
1111
|
+
a = 1, (), 3
|
|
1112
|
+
a.should == [1, nil, 3]
|
|
1113
|
+
end
|
|
1114
|
+
end
|
|
1115
|
+
|
|
1116
|
+
describe "Multiple assignment without grouping or splatting" do
|
|
1117
|
+
it "An equal number of arguments on lhs and rhs assigns positionally" do
|
|
1118
|
+
a, b, c, d = 1, 2, 3, 4
|
|
1119
|
+
a.should == 1
|
|
1120
|
+
b.should == 2
|
|
1121
|
+
c.should == 3
|
|
1122
|
+
d.should == 4
|
|
1123
|
+
end
|
|
1124
|
+
|
|
1125
|
+
it "If rhs has too few arguments, the missing ones on lhs are assigned nil" do
|
|
1126
|
+
a, b, c = 1, 2
|
|
1127
|
+
a.should == 1
|
|
1128
|
+
b.should == 2
|
|
1129
|
+
c.should == nil
|
|
1130
|
+
end
|
|
1131
|
+
|
|
1132
|
+
it "If rhs has too many arguments, the extra ones are silently not assigned anywhere" do
|
|
1133
|
+
a, b = 1, 2, 3
|
|
1134
|
+
a.should == 1
|
|
1135
|
+
b.should == 2
|
|
1136
|
+
end
|
|
1137
|
+
|
|
1138
|
+
it "The assignments are done in parallel so that lhs and rhs are independent of eachother without copying" do
|
|
1139
|
+
o_of_a, o_of_b = mock('a'), mock('b')
|
|
1140
|
+
a, b = o_of_a, o_of_b
|
|
1141
|
+
a, b = b, a
|
|
1142
|
+
a.should equal(o_of_b)
|
|
1143
|
+
b.should equal(o_of_a)
|
|
1144
|
+
end
|
|
1145
|
+
end
|
|
1146
|
+
|
|
1147
|
+
describe "Multiple assignments with splats" do
|
|
1148
|
+
ruby_version_is ""..."1.9" do
|
|
1149
|
+
it "* on the lhs has to be applied to the last parameter" do
|
|
1150
|
+
lambda { eval 'a, *b, c = 1, 2, 3' }.should raise_error(SyntaxError)
|
|
1151
|
+
end
|
|
1152
|
+
end
|
|
1153
|
+
|
|
1154
|
+
it "* on the lhs collects all parameters from its position onwards as an Array or an empty Array" do
|
|
1155
|
+
a, *b = 1, 2
|
|
1156
|
+
c, *d = 1
|
|
1157
|
+
e, *f = 1, 2, 3
|
|
1158
|
+
g, *h = 1, [2, 3]
|
|
1159
|
+
*i = 1, [2,3]
|
|
1160
|
+
*k = 1,2,3
|
|
1161
|
+
|
|
1162
|
+
a.should == 1
|
|
1163
|
+
b.should == [2]
|
|
1164
|
+
c.should == 1
|
|
1165
|
+
d.should == []
|
|
1166
|
+
e.should == 1
|
|
1167
|
+
f.should == [2, 3]
|
|
1168
|
+
g.should == 1
|
|
1169
|
+
h.should == [[2, 3]]
|
|
1170
|
+
i.should == [1, [2, 3]]
|
|
1171
|
+
k.should == [1,2,3]
|
|
1172
|
+
end
|
|
1173
|
+
|
|
1174
|
+
ruby_version_is ""..."1.9" do
|
|
1175
|
+
it "* on the LHS returns the Array on the RHS enclosed in an Array" do
|
|
1176
|
+
*j = [1,2,3]
|
|
1177
|
+
j.should == [[1,2,3]]
|
|
1178
|
+
end
|
|
1179
|
+
end
|
|
1180
|
+
|
|
1181
|
+
ruby_version_is "1.9" do
|
|
1182
|
+
it "* on the LHS returns the Array on the RHS without enclosing it in an Array" do
|
|
1183
|
+
*j = [1,2,3]
|
|
1184
|
+
j.should == [1,2,3]
|
|
1185
|
+
end
|
|
1186
|
+
end
|
|
1187
|
+
end
|
|
1188
|
+
|
|
1189
|
+
describe "Multiple assignments with grouping" do
|
|
1190
|
+
it "A group on the lhs is considered one position and treats its corresponding rhs position like an Array" do
|
|
1191
|
+
# a, (b, c), d = 1, 2, 3, 4
|
|
1192
|
+
# e, (f, g), h = 1, [2, 3, 4], 5
|
|
1193
|
+
# i, (j, k), l = 1, 2, 3
|
|
1194
|
+
a.should == 1
|
|
1195
|
+
b.should == 2
|
|
1196
|
+
c.should == nil
|
|
1197
|
+
d.should == 3
|
|
1198
|
+
e.should == 1
|
|
1199
|
+
f.should == 2
|
|
1200
|
+
g.should == 3
|
|
1201
|
+
h.should == 5
|
|
1202
|
+
i.should == 1
|
|
1203
|
+
j.should == 2
|
|
1204
|
+
k.should == nil
|
|
1205
|
+
l.should == 3
|
|
1206
|
+
end
|
|
1207
|
+
|
|
1208
|
+
it "supports multiple levels of nested groupings" do
|
|
1209
|
+
# a,(b,(c,d)) = 1,[2,[3,4]]
|
|
1210
|
+
a.should == 1
|
|
1211
|
+
b.should == 2
|
|
1212
|
+
c.should == 3
|
|
1213
|
+
d.should == 4
|
|
1214
|
+
|
|
1215
|
+
# a,(b,(c,d)) = [1,[2,[3,4]]]
|
|
1216
|
+
a.should == 1
|
|
1217
|
+
b.should == 2
|
|
1218
|
+
c.should == 3
|
|
1219
|
+
d.should == 4
|
|
1220
|
+
|
|
1221
|
+
x = [1,[2,[3,4]]]
|
|
1222
|
+
# a,(b,(c,d)) = x
|
|
1223
|
+
a.should == 1
|
|
1224
|
+
b.should == 2
|
|
1225
|
+
c.should == 3
|
|
1226
|
+
d.should == 4
|
|
1227
|
+
end
|
|
1228
|
+
|
|
1229
|
+
it "rhs cannot use parameter grouping, it is a syntax error" do
|
|
1230
|
+
lambda { eval '(a, b) = (1, 2)' }.should raise_error(SyntaxError)
|
|
1231
|
+
end
|
|
1232
|
+
end
|
|
1233
|
+
|
|
1234
|
+
# TODO: merge the following two describe blocks and partition the specs
|
|
1235
|
+
# into distinct cases.
|
|
1236
|
+
describe "Multiple assignment" do
|
|
1237
|
+
not_compliant_on :rubinius do
|
|
1238
|
+
it "has the proper return value" do
|
|
1239
|
+
# (a,b,*c = *[5,6,7,8,9,10]).should == [5,6,7,8,9,10]
|
|
1240
|
+
# (d,e = VariablesSpecs.reverse_foo(4,3)).should == [3,4]
|
|
1241
|
+
# (f,g,h = VariablesSpecs.reverse_foo(6,7)).should == [7,6]
|
|
1242
|
+
# (i,*j = *[5,6,7]).should == [5,6,7]
|
|
1243
|
+
# (k,*l = [5,6,7]).should == [5,6,7]
|
|
1244
|
+
a.should == 5
|
|
1245
|
+
b.should == 6
|
|
1246
|
+
c.should == [7,8,9,10]
|
|
1247
|
+
d.should == 3
|
|
1248
|
+
e.should == 4
|
|
1249
|
+
f.should == 7
|
|
1250
|
+
g.should == 6
|
|
1251
|
+
h.should == nil
|
|
1252
|
+
i.should == 5
|
|
1253
|
+
j.should == [6,7]
|
|
1254
|
+
k.should == 5
|
|
1255
|
+
l.should == [6,7]
|
|
1256
|
+
end
|
|
1257
|
+
end
|
|
1258
|
+
|
|
1259
|
+
# TODO: write Rubinius versions
|
|
1260
|
+
end
|
|
1261
|
+
|
|
1262
|
+
# For now, masgn is deliberately non-compliant with MRI wrt the return val from an masgn.
|
|
1263
|
+
# Rubinius returns true as the result of the assignment, but MRI returns an array
|
|
1264
|
+
# containing all the elements on the rhs. As this result is never used, the cost
|
|
1265
|
+
# of creating and then discarding this array is avoided
|
|
1266
|
+
describe "Multiple assignment, array-style" do
|
|
1267
|
+
not_compliant_on :rubinius do
|
|
1268
|
+
it "returns an array of all rhs values" do
|
|
1269
|
+
(a,b = 5,6,7).should == [5,6,7]
|
|
1270
|
+
a.should == 5
|
|
1271
|
+
b.should == 6
|
|
1272
|
+
|
|
1273
|
+
(c,d,*e = 99,8).should == [99,8]
|
|
1274
|
+
c.should == 99
|
|
1275
|
+
d.should == 8
|
|
1276
|
+
e.should == []
|
|
1277
|
+
|
|
1278
|
+
(f,g,h = 99,8).should == [99,8]
|
|
1279
|
+
f.should == 99
|
|
1280
|
+
g.should == 8
|
|
1281
|
+
h.should == nil
|
|
1282
|
+
end
|
|
1283
|
+
end
|
|
1284
|
+
|
|
1285
|
+
deviates_on :rubinius do
|
|
1286
|
+
it "returns true" do
|
|
1287
|
+
(a,b = 5,6,7).should == true
|
|
1288
|
+
a.should == 5
|
|
1289
|
+
b.should == 6
|
|
1290
|
+
|
|
1291
|
+
(c,d,*e = 99,8).should == true
|
|
1292
|
+
c.should == 99
|
|
1293
|
+
d.should == 8
|
|
1294
|
+
e.should == []
|
|
1295
|
+
|
|
1296
|
+
(f,g,h = 99,8).should == true
|
|
1297
|
+
f.should == 99
|
|
1298
|
+
g.should == 8
|
|
1299
|
+
h.should == nil
|
|
1300
|
+
end
|
|
1301
|
+
end
|
|
1302
|
+
end
|
|
1303
|
+
|
|
1304
|
+
describe "Scope of variables" do
|
|
1305
|
+
it "instance variables not overwritten by local variable in each block" do
|
|
1306
|
+
|
|
1307
|
+
class ScopeVariables
|
|
1308
|
+
attr_accessor :v
|
|
1309
|
+
|
|
1310
|
+
def initialize
|
|
1311
|
+
@v = ['a', 'b', 'c']
|
|
1312
|
+
end
|
|
1313
|
+
|
|
1314
|
+
def check_access
|
|
1315
|
+
v.should == ['a', 'b', 'c']
|
|
1316
|
+
self.v.should == ['a', 'b', 'c']
|
|
1317
|
+
end
|
|
1318
|
+
|
|
1319
|
+
def check_local_variable
|
|
1320
|
+
v = nil
|
|
1321
|
+
self.v.should == ['a', 'b', 'c']
|
|
1322
|
+
end
|
|
1323
|
+
|
|
1324
|
+
def check_each_block
|
|
1325
|
+
self.v.each { |v|
|
|
1326
|
+
# Don't actually do anything
|
|
1327
|
+
}
|
|
1328
|
+
self.v.should == ['a', 'b', 'c']
|
|
1329
|
+
v.should == ['a', 'b', 'c']
|
|
1330
|
+
self.v.object_id.should == v.object_id
|
|
1331
|
+
end
|
|
1332
|
+
end # Class ScopeVariables
|
|
1333
|
+
|
|
1334
|
+
instance = ScopeVariables.new()
|
|
1335
|
+
instance.check_access
|
|
1336
|
+
instance.check_local_variable
|
|
1337
|
+
instance.check_each_block
|
|
1338
|
+
end
|
|
1339
|
+
end
|
|
1340
|
+
|
|
1341
|
+
describe "A local variable in a #define_method scope" do
|
|
1342
|
+
ruby_bug '#1322', '1.8.7.228' do
|
|
1343
|
+
it "shares the lexical scope containing the call to #define_method" do
|
|
1344
|
+
# We need a new scope to reproduce this bug.
|
|
1345
|
+
handle = mock("handle for containing scope method")
|
|
1346
|
+
|
|
1347
|
+
def handle.produce_bug
|
|
1348
|
+
local = 1
|
|
1349
|
+
|
|
1350
|
+
klass = Class.new
|
|
1351
|
+
klass.send :define_method, :set_local do |arg|
|
|
1352
|
+
lambda { local = 2 }.call
|
|
1353
|
+
end
|
|
1354
|
+
|
|
1355
|
+
# We must call with at least one argument to reproduce the bug.
|
|
1356
|
+
klass.new.set_local(nil)
|
|
1357
|
+
|
|
1358
|
+
local
|
|
1359
|
+
end
|
|
1360
|
+
|
|
1361
|
+
handle.produce_bug.should == 2
|
|
1362
|
+
end
|
|
1363
|
+
end
|
|
1364
|
+
end
|
|
1365
|
+
|
|
1366
|
+
language_version __FILE__, "variables"
|