From c2d9d48871c3131b5337fefad54ab35458c514bb Mon Sep 17 00:00:00 2001 From: Laurent Sansonetti Date: Thu, 10 Apr 2014 00:39:44 +0200 Subject: [PATCH] remove test suite, start integrating rubyspec --- test/test-android/Rakefile | 5 + test/test-android/app/language/if_spec.rb | 305 ++++++++++++++++++ test/test-android/app/language/unless_spec.rb | 41 +++ test/test-android/app/main.rb | 158 +++------ 4 files changed, 396 insertions(+), 113 deletions(-) create mode 100644 test/test-android/app/language/if_spec.rb create mode 100644 test/test-android/app/language/unless_spec.rb diff --git a/test/test-android/Rakefile b/test/test-android/Rakefile index d66937be..6afab157 100644 --- a/test/test-android/Rakefile +++ b/test/test-android/Rakefile @@ -8,4 +8,9 @@ Motion::Project::App.setup do |app| app.api_version = '18' app.sdk_path = File.expand_path('~/src/android-sdk-macosx') app.ndk_path = File.expand_path('~/src/android-ndk-r9d') + + # Make sure the main file is compiled and executed first. + ary = app.files + ary.delete('./app/main.rb') + ary.unshift('./app/main.rb') end diff --git a/test/test-android/app/language/if_spec.rb b/test/test-android/app/language/if_spec.rb new file mode 100644 index 00000000..e3dff3bc --- /dev/null +++ b/test/test-android/app/language/if_spec.rb @@ -0,0 +1,305 @@ +describe "The if expression" do + it "evaluates body if expression is true" do + a = [] + if true + a << 123 + end + a.should == [123] + end + + it "does not evaluate body if expression is false" do + a = [] + if false + a << 123 + end + a.should == [] + end + + it "does not evaluate body if expression is empty" do + a = [] + if () + a << 123 + end + a.should == [] + end + + it "does not evaluate else-body if expression is true" do + a = [] + if true + a << 123 + else + a << 456 + end + a.should == [123] + end + + it "evaluates only else-body if expression is false" do + a = [] + if false + a << 123 + else + a << 456 + end + a.should == [456] + end + + it "returns result of then-body evaluation if expression is true" do + if true + 123 + end.should == 123 + end + + it "returns result of last statement in then-body if expression is true" do + if true + 'foo' + 'bar' + 'baz' + end.should == 'baz' + end + + it "returns result of then-body evaluation if expression is true and else part is present" do + if true + 123 + else + 456 + end.should == 123 + end + + it "returns result of else-body evaluation if expression is false" do + if false + 123 + else + 456 + end.should == 456 + end + + it "returns nil if then-body is empty and expression is true" do + if true + end.should == nil + end + + it "returns nil if then-body is empty, expression is true and else part is present" do + if true + else + 456 + end.should == nil + end + + it "returns nil if then-body is empty, expression is true and else part is empty" do + if true + else + end.should == nil + end + + it "returns nil if else-body is empty and expression is false" do + if false + 123 + else + end.should == nil + end + + it "returns nil if else-body is empty, expression is false and then-body is empty" do + if false + else + end.should == nil + end + + it "considers an expression with nil result as false" do + if nil + 123 + else + 456 + end.should == 456 + end + + it "considers a non-nil and non-boolean object in expression result as true" do + if mock('x') + 123 + else + 456 + end.should == 123 + end + + it "considers a zero integer in expression result as true" do + if 0 + 123 + else + 456 + end.should == 123 + end + + it "allows starting else-body on the same line" do + if false + 123 + else 456 + end.should == 456 + end + + it "evaluates subsequent elsif statements and execute body of first matching" do + if false + 123 + elsif false + 234 + elsif true + 345 + elsif true + 456 + end.should == 345 + end + + it "evaluates else-body if no if/elsif statements match" do + if false + 123 + elsif false + 234 + elsif false + 345 + else + 456 + end.should == 456 + end + + it "allows 'then' after expression when then-body is on the next line" do + if true then + 123 + end.should == 123 + + if true then ; 123; end.should == 123 + end + + it "allows then-body on the same line separated with 'then'" do + if true then 123 + end.should == 123 + + if true then 123; end.should == 123 + end + + it "returns nil when then-body on the same line separated with 'then' and expression is false" do + if false then 123 + end.should == nil + + if false then 123; end.should == nil + end + + it "returns nil when then-body separated by 'then' is empty and expression is true" do + if true then + end.should == nil + + if true then ; end.should == nil + end + + it "returns nil when then-body separated by 'then', expression is false and no else part" do + if false then + end.should == nil + + if false then ; end.should == nil + end + + it "evaluates then-body when then-body separated by 'then', expression is true and else part is present" do + if true then 123 + else 456 + end.should == 123 + + if true then 123; else 456; end.should == 123 + end + + it "evaluates else-body when then-body separated by 'then' and expression is false" do + if false then 123 + else 456 + end.should == 456 + + if false then 123; else 456; end.should == 456 + end + + describe "with a boolean range ('flip-flop' operator)" do + before :each do + ScratchPad.record [] + end + + after :each do + ScratchPad.clear + end + + it "mimics an awk conditional with a single-element inclusive-end range" do + 10.times { |i| ScratchPad << i if (i == 4)..(i == 4) } + ScratchPad.recorded.should == [4] + end + + it "mimics an awk conditional with a many-element inclusive-end range" do + 10.times { |i| ScratchPad << i if (i == 4)..(i == 7) } + ScratchPad.recorded.should == [4, 5, 6, 7] + end + + it "mimics a sed conditional with a zero-element exclusive-end range" do + 10.times { |i| ScratchPad << i if (i == 4)...(i == 4) } + ScratchPad.recorded.should == [4, 5, 6, 7, 8, 9] + end + + it "mimics a sed conditional with a many-element exclusive-end range" do + 10.times { |i| ScratchPad << i if (i == 4)...(i == 5) } + ScratchPad.recorded.should == [4, 5] + end + end +end + +describe "The postfix if form" do + it "evaluates statement if expression is true" do + a = [] + a << 123 if true + a.should == [123] + end + + it "does not evaluate statement if expression is false" do + a = [] + a << 123 if false + a.should == [] + end + + it "returns result of expression if value is true" do + (123 if true).should == 123 + end + + it "returns nil if expression is false" do + (123 if false).should == nil + end + + it "considers a nil expression as false" do + (123 if nil).should == nil + end + + it "considers a non-nil object as true" do + (123 if mock('x')).should == 123 + end + + it "evaluates then-body in containing scope" do + a = 123 + if true + b = a+1 + end + b.should == 124 + end + + it "evaluates else-body in containing scope" do + a = 123 + if false + b = a+1 + else + b = a+2 + end + b.should == 125 + end + + it "evaluates elsif-body in containing scope" do + a = 123 + if false + b = a+1 + elsif false + b = a+2 + elsif true + b = a+3 + else + b = a+4 + end + b.should == 126 + end +end diff --git a/test/test-android/app/language/unless_spec.rb b/test/test-android/app/language/unless_spec.rb new file mode 100644 index 00000000..d32d12f2 --- /dev/null +++ b/test/test-android/app/language/unless_spec.rb @@ -0,0 +1,41 @@ +describe "The unless expression" do + it "evaluates the unless body when the expression is false" do + unless false + a = true + else + a = false + end + + a.should == true + end + + it "returns the last statement in the body" do + unless false + 'foo' + 'bar' + 'baz' + end.should == 'baz' + end + + it "evaluates the else body when the expression is true" do + unless true + 'foo' + else + 'bar' + end.should == 'bar' + end + + it "takes an optional then after the expression" do + unless false then + 'baz' + end.should == 'baz' + end + + it "does not return a value when the expression is true" do + unless true; end.should == nil + end + + it "allows expression and body to be on one line (using 'then')" do + unless false then 'foo'; else 'bar'; end.should == 'foo' + end +end diff --git a/test/test-android/app/main.rb b/test/test-android/app/main.rb index f03d7772..9ce3fbed 100644 --- a/test/test-android/app/main.rb +++ b/test/test-android/app/main.rb @@ -1,119 +1,51 @@ +$specs = [] +$describe = nil +$expectations_total = 0 +$expectations_failures = 0 + +class ShouldResult < Java::Lang::Object + def set_object(obj) + @obj = obj + end + + def ==(x) + if @obj != x + puts "Expectation failed (expected `#{self}' == `#{x}')" + $expectations_failures += 1 + end + $expectations_total += 1 + end +end + +class Object + def describe(msg, &block) + $specs << [msg, block] + end + + def it(msg) + puts "#{$describe} #{msg}" + yield + end + + def should + res = ShouldResult.new + res.set_object self + res + end + + def mock(obj) + # XXX we probably should be smarter here. + obj + end +end + class MainActivity < Android::App::Activity def onCreate(savedInstanceState) super - @tests = @failures = 0 - test_class - test_object - test_boolean - test_fixnum - test_string - test_array - puts "Test suite finished: #{@tests} tests, #{@failures} failure(s)." - end - - def test(msg, res) - if res - puts "OK : #{msg}" - else - puts "!! : #{msg}" - @failures += 1 + $specs.each do |ary| + $describe = ary[0] + ary[1].call end - @tests += 1 - end - - def test_class - test 'Class#inspect returns the Java class name', Java::Lang::Object.inspect == 'java.lang.Object' - - test 'Class#== returns true if both objects are equal', Java::Lang::Object == Java::Lang::Object - test 'Class#== returns false if operand is a wrong class', (Java::Lang::Object == Java::Lang::String) == false - test 'Class#== returns false if operand is not a class', (Java::Lang::Object == 42) == false - end - - def test_object - obj = Java::Lang::Object.new - test 'Object#class returns Java::Lang::Object', obj.class == Java::Lang::Object - test 'Object#inspect returns a string description', obj.inspect.class == Java::Lang::String # TODO test for actual content - test 'Object.ancestors returns a correct array', obj.class.ancestors == [Java::Lang::Object] - - test 'Object#== returns true if both objects are equal', obj == obj - test 'Object#== returns false if operand is not equal', (obj == Java::Lang::Object.new) == false - - test '!Object returns false', (!obj) == false - end - - def test_boolean - test 'true.class returns Java::Lang::Boolean', true.class == Java::Lang::Boolean - test 'false.class returns Java::Lang::Boolean', false.class == Java::Lang::Boolean - test '{true,false}.class.ancestors returns a correct array', true.class.ancestors == [Java::Lang::Boolean, Java::Lang::Object] - test 'true.inspect returns \"true\"', true.inspect == 'true' - test 'false.inspect returns \"false\"', false.inspect == 'false' - - test 'true#== returns true if operand is true', true == true - test 'true#== returns false if operand is not true', (true == false) == false - test 'false#== returns true if operand is false', false == false - test 'false#== returns false if operand is not false', (false == true) == false - - test '!true returns false', !(true) == false - test '!false returns true', !(false) - end - - def test_fixnum - test 'Fixnum#class returns Java::Lang::Long', 42.class == Java::Lang::Long - test 'Fixnum.ancestors returns a correct array', 42.class.ancestors == [Java::Lang::Long, Java::Lang::Number, Java::Lang::Object] - test 'Fixnum#inspect returns a string representation of the receiver', 42.inspect == '42' - - test 'Fixnum#== returns true if both objects are equal', 42 == 42 - test 'Fixnum#== returns false if operand is a wrong fixnum', (42 == 100) == false - test 'Fixnum#== returns false if operand is not a fixnum', (42 == '123') == false - - test 'Fixnum#+ returns the addition of the receiver and the operand', 31 + 11 == 42 - test 'Fixnum#- returns the substraction of the receiver and the operand', 63 - 21 == 42 - test 'Fixnum#* returns the multiplication of the receiver and the operand', 21 * 2 == 42 - test 'Fixnum#* returns the division of the receiver and the operand', 84 / 2 == 42 - - test 'Fixnum#> returns true if the receiver is greater than the operand', 42 > 41 - test 'Fixnum#> returns false if the receiver is not greater than the operand', (41 > 42) == false - test 'Fixnum#>= returns true if the receiver is greater or equal than the operand', 42 >= 42 - test 'Fixnum#>= returns false if the receiver is not greater or equal than the operand', (41 >= 42) == false - - test 'Fixnum#< returns true if the receiver is lesser than the operand', 41 < 42 - test 'Fixnum#< returns false if the receiver is not lesser than the operand', (42 < 41) == false - test 'Fixnum#<= returns true if the receiver is lesser or equal than the operand', 42 <= 42 - test 'Fixnum#<= returns false if the receiver is not lesser or equal than the operand', (42 <= 41) == false - - test '!fixnum returns false', (!42) == false - end - - def test_string - test 'String#class returns Java::Lang::String', 'foo'.class == Java::Lang::String - test 'String.ancestors returns a correct array', 'foo'.class.ancestors == [Java::Lang::String, Java::Lang::Object] - test 'String#inspect returns an escaped string representation of the receiver', 'foo "hello world" bar'.inspect == "\"foo \\\"hello world\\\" bar\"" - test 'String#dup returns a copy of the receiver', 'foo'.dup == 'foo' - - test 'String#== returns true if both objects are equal', 'foo' == 'foo' - test 'String#== returns false if operand is a wrong string', ('foo' == 'bar') == false - test 'String#== returns false if operand is not a string', ('foo' == 42) == false - - test 'Literal strings can be interpolated', "foo #{'bar'}" == 'foo bar' - x = 'foo' - test '!string returns false', (!x) == false - end - - def test_array - test 'Array#class returns Java::Util::ArrayList', [].class == Java::Util::ArrayList - test 'Array.ancestors returns a correct array', [].class.ancestors == [Java::Util::ArrayList, Java::Util::AbstractList, Java::Util::AbstractCollection, Java::Lang::Object] - test 'Array#inspect returns a string representation of the receiver', [1, 2, 3].inspect == "[1, 2, 3]" - test 'Array#dup returns a copy of the receiver', [1, 2, 3].dup == [1, 2, 3] - - test 'Array#== returns true if both objects are equal', [1, 2, 3] == [1, 1+1, 4-1] - test 'Array#== returns false if operand is a wrong string', ([1, 2, 3] == [1, 2, 4]) == false - test 'Array#== returns false if operand is not a string', ([1, 2, 3] == 42) == false - - a = [1, 2, 3] - sum = 0 - a.each { |x| sum += x } - test 'Array#each yields the block with each element', sum == 6 - - test '!array returns false', (![42]) == false + puts "Spec suite finished: #{$expectations_total} expectations, #{$expectations_failures} failure(s)." end end