Continue the previous factoring out of the comparison and
test function, by adding _cmp_ok() for other types
---
 runtime/parrot/library/Test/More.pir |  233 +++++++++++++++++++++++++++-------
 t/library/test_more.t                |   39 ++++++
 2 files changed, 222 insertions(+), 50 deletions(-)

diff --git a/runtime/parrot/library/Test/More.pir 
b/runtime/parrot/library/Test/More.pir
index dea010c..f9f6673 100644
--- a/runtime/parrot/library/Test/More.pir
+++ b/runtime/parrot/library/Test/More.pir
@@ -32,10 +32,12 @@ Test::More - Parrot extension for testing modules
     isnt( 200, 100, 'passing integer negative compare' )
 
     is( 1.001, 1.001, 'passing float compare with diagnostic' )
+    isnt( 1.001, 1.001, 'failing float negative compare with diag' )
     is( 8.008, 4.004 )
 
     is( 'foo', 'foo', 'passing string compare with diagnostic' )
     is( 'foo', 'bar', 'failing string compare with diagnostic' )
+    isnt( 'foo', 'bar', 'passing string negative compare with diag' )
 
     is( some_pmc, another_pmc, 'pmc comparison uses "eq" op' )
 
@@ -194,22 +196,17 @@ add more.
     .return($I0)
 .end
 
-.sub is :multi( float, float )
+.sub _cmp_ok :multi( float, float, pmc )
     .param float  left
     .param float  right
+    .param pmc    comp
     .param string description :optional
 
     .local pmc test
     find_global test, 'Test::More', '_test'
 
     .local int pass
-    pass = 0
-
-    eq left, right, pass_it
-    goto report
-
-  pass_it:
-    pass = 1
+    pass = comp(left, right)
 
   report:
     test.ok( pass, description )
@@ -227,22 +224,46 @@ add more.
   done:
 .end
 
-.sub is :multi( string, string )
+.sub is :multi( float, float )
+    .param float    left
+    .param float    right
+    .param string description :optional
+    .local pmc comp
+    comp = find_name "_eq_float"
+    _cmp_ok(left,right,comp,description)
+.end
+
+.sub _eq_float
+    .param float    left
+    .param float    right
+    $I0 = 0
+    if left == right goto pass_it
+
+       # XXX - significant places?  I don't care :)
+       .local float diff
+       diff = left - right
+       abs diff
+
+       if diff < 0.000000000001 goto pass_it
+
+       goto out
+pass_it:
+       $I0 = 1
+out:   
+    .return($I0)
+.end
+
+.sub _cmp_ok :multi( string, string, pmc )
     .param string left
     .param string right
+    .param pmc    comp
     .param string description :optional
 
     .local pmc test
     find_global test, 'Test::More', '_test'
 
     .local int pass
-    pass = 0
-
-    eq left, right, pass_it
-    goto report
-
-  pass_it:
-    pass = 1
+    pass = comp(left, right)
 
   report:
     test.ok( pass, description )
@@ -260,63 +281,128 @@ add more.
   done:
 .end
 
-.sub is :multi()
+.sub is :multi( string, string )
+    .param string    left
+    .param string    right
+    .param string description :optional
+    .local pmc comp
+    comp = find_name "_eq_string"
+    _cmp_ok(left,right,comp,description)
+.end
+
+.sub _eq_string
+    .param string    left
+    .param string    right
+    $I0 = iseq left, right
+    .return($I0)
+.end
+
+.sub _ne_string
+    .param string    left
+    .param string    right
+    $I0 = isne left, right
+    .return($I0)
+.end
+
+.sub _cmp_ok :multi()
     .param pmc    left
     .param pmc    right
+    .param pmc    comp
     .param string description :optional
 
     .local pmc test
     find_global test, 'Test::More', '_test'
 
     .local int pass
-    pass = 0
+    pass = comp(left, right)
+
+  report:
+    test.ok( pass, description )
+    if pass goto done
+
+    .local string diagnostic
+    .local string l_string
+    .local string r_string
+
+    l_string    = left
+    r_string    = right
+
+    diagnostic = _make_diagnostic( l_string, r_string )
+    test.diag( diagnostic )
+  done:
+.end
 
-       .local string r_type
-       r_type = typeof right
+.sub _is_or_isnt :multi()
+    .param pmc    left
+    .param pmc    right
+    .param string which
+    .param string description :optional
 
-       if r_type == 'Float' goto num_compare
-       if r_type == 'Int'   goto num_compare
-       goto string_compare
+    .local string func
+    func = "_" . which
+    func = func . "_"
 
-  num_compare:
+    .local string r_type
+    r_type = typeof right
+
+    .local pmc    comp
+    if r_type == 'Float'  goto float_compare
+    if r_type == 'Int'    goto int_compare
+    if r_type == 'String' goto string_compare
+    goto object_compare
+
+  float_compare:
        .local float l_val
        .local float r_val
        l_val = left
        r_val = right
-
-    if l_val == r_val goto pass_it
-
-       # XXX - significant places?  I don't care :)
-       .local float diff
-       diff = l_val - r_val
-
-       if diff < 0.000000000001 goto pass_it
+       func = func . "float"
+       comp = find_name func
+       say "# comparing floats"
+       _cmp_ok(l_val, r_val, comp, description)
+       goto out
 
   string_compare:
        .local string l_val
        .local string r_val
        l_val = left
        r_val = right
-       eq l_val, r_val, pass_it
-       goto report
-
-  pass_it:
-    pass = 1
-
-  report:
-    test.ok( pass, description )
-    if pass goto done
+       func = func . "string"
+       comp = find_name func
+       _cmp_ok(l_val, r_val, comp, description)
+       goto out
+       
+  int_compare:
+       .local int l_val
+       .local int r_val
+       l_val = left
+       r_val = right
+       func = func . "int"
+       comp = find_name func
+       _cmp_ok(l_val, r_val, comp, description)
+       goto out
 
-    .local string diagnostic
-    .local string l_string
-    .local string r_string
+  object_compare:
+       func = func . "object"
+       comp = find_name func
+       _cmp_ok(left, right, comp, description)
+       goto out
 
-    l_string    = left
-    r_string    = right
+out:
+.end
 
-    diagnostic = _make_diagnostic( l_string, r_string )
-    test.diag( diagnostic )
-  done:
+.sub _eq_object
+    .param string    left
+    .param string    right
+    $I0 = iseq left, right
+    .return($I0)
+.end
+       
+.sub is :multi()
+    .param pmc    left
+    .param pmc    right
+    .param string description :optional
+    _is_or_isnt(left, right, "eq", description)
 .end
 
 =item C<isnt( left, right, description )>
@@ -341,6 +427,55 @@ As C<is()>, but the test passes if the arguments I<don't> 
match.
     .return($I0)
 .end
 
+.sub isnt :multi( float, float )
+    .param float    left
+    .param float    right
+    .param string description :optional
+    .local pmc comp
+    comp = find_name "_ne_float"
+    _cmp_ok(left,right,comp,description)
+.end
+
+.sub _ne_float
+    .param float    left
+    .param float    right
+    $I0 = _eq_float(left, right)
+    not $I0
+    .return($I0)
+.end
+
+.sub isnt :multi( string, string )
+    .param string    left
+    .param string    right
+    .param string description :optional
+    .local pmc comp
+    comp = find_name "_ne_string"
+    _cmp_ok(left,right,comp,description)
+.end
+
+.sub _ne_string
+    .param string    left
+    .param string    right
+    $I0 = isne left, right
+    .return($I0)
+.end
+
+.sub isnt :multi()
+    .param pmc    left
+    .param pmc    right
+    .param string description :optional
+    _is_or_isnt(left, right, "ne", description)
+.end
+
+.sub _ne_object
+    .param string    left
+    .param string    right
+    $I0 = iseq left, right
+    not $I0
+    .return($I0)
+.end
+
+
 =item C<diag( diagnostic )>
 
 Prints C<diagnostic> to the screen, without affecting test comparisons.
diff --git a/t/library/test_more.t b/t/library/test_more.t
index 4bc08b8..b7aa317 100644
--- a/t/library/test_more.t
+++ b/t/library/test_more.t
@@ -33,7 +33,7 @@
        .IMPORT( 'Test::Builder::Tester', 'test_pass' )
        .IMPORT( 'Test::Builder::Tester', 'test_test' )
 
-       plan( 49 )
+       plan( 55 )
        test_skip()
        test_ok()
        test_is()
@@ -373,4 +373,41 @@
        test_pass()
        isnt( -100, 200 )
        test_test( 'passing test isnt() for ints')
+
+       test_fail()
+       isnt( 1.001, 1.001 )
+       test_diag( 'Received: 1.001' )
+       test_diag( 'Expected: 1.001' )
+       test_test( 'failing test isnt() for floats')
+
+       test_pass()
+       # see also http://xkcd.com/c217.html
+       isnt( 19.9990999791895, 20 )
+       test_test( 'passing test isnt() for floats')
+
+       test_fail()
+       isnt( "str", "str" )
+       test_diag( 'Received: str' )
+       test_diag( 'Expected: str' )
+       test_test( 'failing test isnt() for strings')
+
+       test_pass()
+       isnt( "str", "bar" )
+       test_test( 'passing test isnt() for strings')
+
+       $P0 = new .String
+       $P0 = "cheese"
+       test_pass()
+       isnt( $P0, "eggs" )
+       test_test( 'passing test isnt() for PMC/string')
+
+       $P1 = new .String
+       $P1 = "cheese"
+       test_fail()
+       isnt( $P0, $P1 )
+       test_diag( 'Received: cheese' )
+       test_diag( 'Expected: cheese' )
+       test_test( 'failing test isnt() for PMC/string')
+
+       
 .end

Reply via email to