diff options
| author | Kevin Newton <kddnewton@gmail.com> | 2023-09-28 09:05:16 -0400 |
|---|---|---|
| committer | Kevin Newton <kddnewton@gmail.com> | 2023-09-28 09:44:16 -0400 |
| commit | a213d2144827ab3151d3291794e87fbfb8523a2e (patch) | |
| tree | 95ea1201a7a309c645e768f46f3103046c316011 /test/ruby | |
| parent | 834560a923dcc4aa6685fb7fd7aecae1808217f1 (diff) | |
Move CRuby-specific prism files to top level
Diffstat (limited to 'test/ruby')
| -rw-r--r-- | test/ruby/test_compile_prism.rb | 349 |
1 files changed, 349 insertions, 0 deletions
diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb new file mode 100644 index 0000000000..bf36f5e1f0 --- /dev/null +++ b/test/ruby/test_compile_prism.rb @@ -0,0 +1,349 @@ +# frozen_string_literal: true + +module Prism + class TestCompilePrism < Test::Unit::TestCase + def test_empty_program + test_prism_eval("") + end + + ############################################################################ + # Literals # + ############################################################################ + + def test_FalseNode + test_prism_eval("false") + end + + def test_FloatNode + test_prism_eval("1.2") + test_prism_eval("1.2e3") + test_prism_eval("+1.2e+3") + test_prism_eval("-1.2e-3") + end + + def test_ImaginaryNode + test_prism_eval("1i") + test_prism_eval("+1.0i") + test_prism_eval("1ri") + end + + def test_IntegerNode + test_prism_eval("1") + test_prism_eval("+1") + test_prism_eval("-1") + test_prism_eval("0x10") + test_prism_eval("0b10") + test_prism_eval("0o10") + test_prism_eval("010") + end + + def test_MatchLastLineNode + test_prism_eval("if /foo/; end") + test_prism_eval("if /foo/i; end") + test_prism_eval("if /foo/x; end") + test_prism_eval("if /foo/m; end") + test_prism_eval("if /foo/im; end") + test_prism_eval("if /foo/mx; end") + test_prism_eval("if /foo/xi; end") + test_prism_eval("if /foo/ixm; end") + end + + def test_NilNode + test_prism_eval("nil") + end + + def test_RationalNode + test_prism_eval("1.2r") + test_prism_eval("+1.2r") + end + + def test_SelfNode + test_prism_eval("self") + end + + def test_TrueNode + test_prism_eval("true") + end + + ############################################################################ + # Reads # + ############################################################################ + + def test_ClassVariableReadNode + test_prism_eval("class Prism::ISeqTest; @@pit = 1; @@pit; end") + end + + def test_ConstantPathNode + test_prism_eval("Prism::ISeqTest") + end + + def test_ConstantReadNode + test_prism_eval("Prism") + end + + def test_GlobalVariableReadNode + test_prism_eval("$pit = 1; $pit") + end + + def test_InstanceVariableReadNode + test_prism_eval("class Prism::ISeqTest; @pit = 1; @pit; end") + end + + def test_LocalVariableReadNode + test_prism_eval("pit = 1; pit") + end + + ############################################################################ + # Writes # + ############################################################################ + + def test_ClassVariableTargetNode + test_prism_eval("class Prism::ISeqTest; @@pit, @@pit1 = 1; end") + end + + def test_ClassVariableWriteNode + test_prism_eval("class Prism::ISeqTest; @@pit = 1; end") + end + + def test_ClassVariableAndWriteNode + test_prism_eval("class Prism::ISeqTest; @@pit = 0; @@pit &&= 1; end") + end + + def test_ClassVariableOrWriteNode + test_prism_eval("class Prism::ISeqTest; @@pit = 1; @@pit ||= 0; end") + test_prism_eval("class Prism::ISeqTest; @@pit = nil; @@pit ||= 1; end") + end + + def test_ClassVariableOperatorWriteNode + test_prism_eval("class Prism::ISeqTest; @@pit = 0; @@pit += 1; end") + end + + def test_ConstantTargetNode + # We don't call test_prism_eval directly in this case becuase we + # don't want to assign the constant mutliple times if we run + # with `--repeat-count` + # Instead, we eval manually here, and remove the constant to + constant_names = ["YCT", "YCT2"] + source = "#{constant_names.join(",")} = 1" + prism_eval = RubyVM::InstructionSequence.compile_prism(source).eval + assert_equal prism_eval, 1 + constant_names.map { |name| + Object.send(:remove_const, name) + } + end + + def test_ConstantWriteNode + # We don't call test_prism_eval directly in this case becuase we + # don't want to assign the constant mutliple times if we run + # with `--repeat-count` + # Instead, we eval manually here, and remove the constant to + constant_name = "YCT" + source = "#{constant_name} = 1" + prism_eval = RubyVM::InstructionSequence.compile_prism(source).eval + assert_equal prism_eval, 1 + Object.send(:remove_const, constant_name) + end + + def test_ConstantPathTargetNode + verbose = $VERBOSE + # Create some temporary nested constants + Object.send(:const_set, "MyFoo", Object) + Object.const_get("MyFoo").send(:const_set, "Bar", Object) + + constant_names = ["MyBar", "MyFoo::Bar", "MyFoo::Bar::Baz"] + source = "#{constant_names.join(",")} = Object" + iseq = RubyVM::InstructionSequence.compile_prism(source) + $VERBOSE = nil + prism_eval = iseq.eval + $VERBOSE = verbose + assert_equal prism_eval, Object + + ensure + ## Teardown temp constants + Object.const_get("MyFoo").send(:remove_const, "Bar") + Object.send(:remove_const, "MyFoo") + Object.send(:remove_const, "MyBar") + $VERBOSE = verbose + end + + def test_ConstantPathWriteNode + # test_prism_eval("Prism::YCT = 1") + end + + def test_GlobalVariableTargetNode + test_prism_eval("$pit, $pit1 = 1") + end + + def test_GlobalVariableWriteNode + test_prism_eval("$pit = 1") + end + + def test_GlobalVariableAndWriteNode + test_prism_eval("$pit = 0; $pit &&= 1") + end + + def test_GlobalVariableOrWriteNode + test_prism_eval("$pit ||= 1") + end + + def test_GlobalVariableOperatorWriteNode + test_prism_eval("$pit = 0; $pit += 1") + end + + def test_InstanceVariableTargetNode + test_prism_eval("class Prism::ISeqTest; @pit, @pit1 = 1; end") + end + + def test_InstanceVariableWriteNode + test_prism_eval("class Prism::ISeqTest; @pit = 1; end") + end + + def test_InstanceVariableAndWriteNode + test_prism_eval("@pit = 0; @pit &&= 1") + end + + def test_InstanceVariableOrWriteNode + test_prism_eval("@pit ||= 1") + end + + def test_InstanceVariableOperatorWriteNode + test_prism_eval("@pit = 0; @pit += 1") + end + + def test_LocalVariableTargetNode + test_prism_eval("pit, pit1 = 1") + end + + def test_LocalVariableWriteNode + test_prism_eval("pit = 1") + end + + def test_LocalVariableAndWriteNode + test_prism_eval("pit = 0; pit &&= 1") + end + + def test_LocalVariableOrWriteNode + test_prism_eval("pit ||= 1") + end + + def test_LocalVariableOperatorWriteNode + test_prism_eval("pit = 0; pit += 1") + end + + ############################################################################ + # String-likes # + ############################################################################ + + def test_EmbeddedVariableNode + # test_prism_eval('class Prism::ISeqTest; @pit = 1; "#@pit"; end') + # test_prism_eval('class Prism::ISeqTest; @@pit = 1; "#@@pit"; end') + test_prism_eval('$pit = 1; "#$pit"') + end + + def test_InterpolatedRegularExpressionNode + test_prism_eval('$pit = 1; /1 #$pit 1/') + test_prism_eval('/1 #{1 + 2} 1/') + test_prism_eval('/1 #{"2"} #{1 + 2} 1/') + end + + def test_InterpolatedStringNode + test_prism_eval('$pit = 1; "1 #$pit 1"') + test_prism_eval('"1 #{1 + 2} 1"') + end + + def test_InterpolatedSymbolNode + test_prism_eval('$pit = 1; :"1 #$pit 1"') + test_prism_eval(':"1 #{1 + 2} 1"') + end + + def test_InterpolatedXStringNode + test_prism_eval('`echo #{1}`') + test_prism_eval('`printf #{"100"}`') + end + + def test_RegularExpressionNode + test_prism_eval('/pit/') + test_prism_eval('/pit/i') + test_prism_eval('/pit/x') + test_prism_eval('/pit/m') + test_prism_eval('/pit/im') + test_prism_eval('/pit/mx') + test_prism_eval('/pit/xi') + test_prism_eval('/pit/ixm') + end + + def test_StringConcatNode + # test_prism_eval('"Prism" "::" "ISeqTest"') + end + + def test_StringNode + test_prism_eval('"pit"') + end + + def test_SymbolNode + test_prism_eval(":pit") + end + + def test_XStringNode + # test_prism_eval(<<~RUBY) + # class Prism::ISeqTest + # def self.`(command) = command * 2 + # `pit` + # end + # RUBY + end + + ############################################################################ + # Jumps # + ############################################################################ + + def test_AndNode + test_prism_eval("true && 1") + test_prism_eval("false && 1") + end + + def test_OrNode + test_prism_eval("true || 1") + test_prism_eval("false || 1") + end + + ############################################################################ + # Calls / arugments # + ############################################################################ + + def test_BlockArgumentNode + test_prism_eval("1.then(&:to_s)") + end + + ############################################################################ + # Scopes/statements # + ############################################################################ + + def test_ParenthesesNode + test_prism_eval("()") + test_prism_eval("(1)") + end + + private + + def compare_eval(source) + ruby_eval = RubyVM::InstructionSequence.compile(source).eval + prism_eval = RubyVM::InstructionSequence.compile_prism(source).eval + + assert_equal ruby_eval, prism_eval + end + + def test_prism_eval(source) + $VERBOSE, verbose_bak = nil, $VERBOSE + + begin + compare_eval(source) + + # Test "popped" functionality + compare_eval("#{source}; 1") + ensure + $VERBOSE = verbose_bak + end + end + end +end |
