test/test_vm.rb in jsonnet-0.1.1 vs test/test_vm.rb in jsonnet-0.2.0

- old
+ new

@@ -108,17 +108,60 @@ rescue Jsonnet::EvaluationError => e assert_equal Encoding::SJIS, e.message.encoding end end - test "Jsonnet::VM#ext_var binds a variable" do + test "Jsonnet::VM#ext_var binds a variable to a string value" do vm = Jsonnet::VM.new vm.ext_var("var1", "foo") result = vm.evaluate('[std.extVar("var1")]') assert_equal JSON.parse('["foo"]'), JSON.parse(result) end + test "Jsonnet::VM#ext_code binds a variable to a code fragment" do + vm = Jsonnet::VM.new + vm.ext_code("var1", "{a:1}") + result = vm.evaluate('[std.extVar("var1")]') + assert_equal JSON.parse(<<-EOS), JSON.parse(result) + [ + { + "a": 1 + } + ] + EOS + end + + test "Jsonnet::VM#tla_var binds a top-level variable to a string value" do + vm = Jsonnet::VM.new + vm.tla_var("var1", "foo") + result = vm.evaluate('function(var1) [var1, var1]') + assert_equal JSON.parse('["foo", "foo"]'), JSON.parse(result) + end + + test "Jsonnet::VM#tla_var binds a top-level argument to a string value" do + vm = Jsonnet::VM.new + vm.tla_var("var1", "foo") + result = vm.evaluate('function(var1) [var1, var1]') + assert_equal JSON.parse('["foo", "foo"]'), JSON.parse(result) + end + + test "Jsonnet::VM#tla_code binds a top-level argument to a code fragment" do + vm = Jsonnet::VM.new + vm.tla_code("var1", "{a:1}") + result = vm.evaluate('function(var1) [var1, var1]') + assert_equal JSON.parse(<<-EOS), JSON.parse(result) + [ + { + "a": 1 + }, + { + "a": 1 + } + ] + EOS + end + test 'Jsonnet::VM#evaluate returns a JSON per filename on multi mode' do vm = Jsonnet::VM.new [ [ "{}", {} ], [ @@ -253,9 +296,183 @@ vm.evaluate(<<-EOS) (import "a.jsonnet") + {} EOS } assert_true called + end + + test "Jsonnet::VM#handle_import treats global escapes as define_method does" do + num_eval = 0 + begin + bodies = [ + proc {|rel, base| return 'null', '/x.libsonnet' }, + lambda {|rel, base| return 'null', '/x.libsonnet' }, + proc {|rel, base| next 'null', '/x.libsonnet' }, + lambda {|rel, base| next 'null', '/x.libsonnet' }, + proc {|rel, base| break 'null', '/x.libsonnet' }, + lambda {|rel, base| break 'null', '/x.libsonnet' }, + ] + bodies.each do |prc| + vm = Jsonnet::VM.new + vm.handle_import(&prc) + + result = vm.evaluate('import "a.jsonnet"') + assert_nil JSON.load(result) + + num_eval += 1 + end + ensure + assert_equal bodies.size, num_eval + end + end + + test "Jsonnet::VM#handle_import is safe on throw" do + [ + proc {|rel, base| throw :dummy }, + lambda {|rel, base| throw :dummy }, + ].each do |prc| + vm = Jsonnet::VM.new + vm.handle_import(&prc) + + catch(:dummy) { + vm.evaluate('import "a.jsonnet"') + flunk "never reach here" + } + end + end + + test "Jsonnet::VM#jpath_add adds a library search path" do + vm = Jsonnet::VM.new + snippet = "(import 'jpath.libsonnet') {b: 2}" + assert_raise(Jsonnet::EvaluationError) { + vm.evaluate(snippet) + } + + vm.jpath_add(File.join(__dir__, 'fixtures')) + result = vm.evaluate(snippet) + assert_equal JSON.parse(<<-EOS), JSON.parse(result) + { + "a": 1, + "b": 2 + } + EOS + end + + test "Jsonnet::VM#define_function adds a new native extension" do + vm = Jsonnet::VM.new + called = false + + vm.define_function("myPow") do |x, y| + called = true + x ** y + end + + result = vm.evaluate("std.native('myPow')(3, 4)") + assert_equal 3**4, JSON.load(result) + assert_true called + end + + test "Jsonnet::VM#define_function passes various types of arguments" do + [ + [%q(null), nil], + [%q("abc"), "abc"], + [%q(1), 1.0], + [%q(1.25), 1.25], + [%q(true), true], + [%q(false), false], + ].each do |expr, value| + vm = Jsonnet::VM.new + vm.define_function("myFunc") do |x| + assert_equal value, x + next nil + end + vm.evaluate("std.native('myFunc')(#{expr})") + end + end + + test "Jsonnet::VM#define_function returns various types of values" do + [ + [nil, nil], + ["abc", "abc"], + [1, 1.0], + [1.25, 1.25], + [true, true], + [false, false], + ].each do |retval, expected| + vm = Jsonnet::VM.new + vm.define_function("myFunc") { retval } + + result = vm.evaluate("std.native('myFunc')()") + assert_equal expected, JSON.load(result) + end + end + + test "Jsonnet::VM#define_function translates an exception in a native function into an error" do + vm = Jsonnet::VM.new + vm.define_function("myFunc") do |x| + raise "something wrong" + end + assert_raise(Jsonnet::EvaluationError) { + vm.evaluate("std.native('myFunc')(1)") + } + end + + test "Jsonnet::VM#define_function let the function return a compound object" do + vm = Jsonnet::VM.new + vm.define_function("myCompound") do |x, y| + { + x => y, + y => [x, y, y, x], + } + end + + result = vm.evaluate("std.native('myCompound')('abc', 'def')") + assert_equal JSON.parse(<<-EOS), JSON.parse(result) + { + "abc": "def", + "def": ["abc", "def", "def", "abc"] + } + EOS + end + + test "Jsonnet::VM#define_function treats global escapes as define_method does" do + num_eval = 0 + begin + bodies = [ + proc {|x| return x }, + lambda {|x| return x }, + proc {|x| next x }, + lambda {|x| next x }, + proc {|x| break x }, + lambda {|x| break x }, + ] + bodies.each do |prc| + vm = Jsonnet::VM.new + vm.define_function(:myFunc, prc) + + result = vm.evaluate('std.native("myFunc")(1.25) + 0.25') + assert_equal 1.25 + 0.25, JSON.load(result) + + num_eval += 1 + end + ensure + assert_equal bodies.size, num_eval + end + end + + test "Jsonnet::VM#define_function is safe on throw" do + [ + proc {|x| throw :dummy }, + lambda {|x| throw :dummy }, + ].each do |prc| + vm = Jsonnet::VM.new + vm.define_function(:myFunc, prc) + + catch(:dummy) { + vm.evaluate('std.native("myFunc")(1.234)') + flunk "never reach here" + } + end end private def with_example_file(content) Tempfile.open("example.jsonnet") {|f|