# New Ticket Created by  Sol Foster 
# Please include the string:  [perl #68926]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=68926 >


More-or-less complete rewrite of the rat.t tests for Rat, making them more 
thorough, more robust, and comforming to the new specs for them discussed 
today on #perl6.  Minor corresponding changes to Rat.pm as well.

-- 
Sol Foster: [email protected]
>From d98b41530782404c257e72a9c04bc63f86ead550 Mon Sep 17 00:00:00 2001
From: [email protected] <[email protected]>
Date: Tue, 1 Sep 2009 16:26:45 -0400
Subject: [PATCH] Move Rat.Str to new standard, add Rat.nude.

---
 src/setting/Rat.pm |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/setting/Rat.pm b/src/setting/Rat.pm
index c9dcdf0..7fc8329 100644
--- a/src/setting/Rat.pm
+++ b/src/setting/Rat.pm
@@ -2,12 +2,10 @@ class Rat {
     has $.numerator;
     has $.denominator;
 
-    my sub gcd(Int $a is copy, Int $b is copy)
-    {
+    my sub gcd(Int $a is copy, Int $b is copy) {
         $a = -$a if ($a < 0);
         $b = -$b if ($b < 0);
-        while $a > 0 && $b > 0
-        {
+        while $a > 0 && $b > 0 {
             ($a, $b) = ($b, $a) if ($b > $a);
             $a %= $b;
         }
@@ -27,9 +25,11 @@ class Rat {
     
     multi method perl() { "$!numerator/$!denominator"; }
 
-    multi method Str() { $.Num.Str }
-
     multi method Num() { $!numerator.Num / $!denominator.Num }
+
+    multi method Str() { $.Num.Str; }
+    
+    multi method nude() { $.numerator, $.denominator; }
 }
 
 multi sub infix:<+>(Rat $a, Rat $b) {
-- 
1.6.0.5

Index: t/spec/S32-num/rat.t
===================================================================
--- t/spec/S32-num/rat.t        (revision 28161)
+++ t/spec/S32-num/rat.t        (working copy)
@@ -7,39 +7,84 @@
 # Basic test functions specific to rational numbers.
 
 # Test ~
-is(~(Rat.new(2,3)), "2/3", "Rats stringify properly");
-is(~(Rat.new(-1,7)), "-1/7", "Rats stringify properly");
+is(~(Rat.new(1,4)), ~(0.25), "Rats stringify properly");
+is(~(Rat.new(-1,2)), ~(-0.5), "Rats stringify properly");
+is(~(Rat.new(7,4)), ~(1.75), "Rats stringify properly");
+is(~(Rat.new(7,-1)), ~(-7), "Rats stringify properly");
 
 # Test new
-is(~(Rat.new(1,-7)), "-1/7", "Negative signs move to numerator");
-is(~(Rat.new(-32,-33)), "32/33", "Double negatives cancel out");
-is(~(Rat.new(2,4)), "1/2", "Reduce to simplest form in constructor");
-is(~(Rat.new(39,33)), "13/11", "Reduce to simplest form in constructor");
-is(~(Rat.new(0,33)), "0/1", "Reduce to simplest form in constructor");
-is(~(Rat.new(1451234131,60)), "1451234131/60", "Reduce huge number to simplest 
form in constructor");
+is(Rat.new(1, -7).nude, (-1, 7), "Negative signs move to numerator");
+is(Rat.new(-32, -33).nude, (32, 33), "Double negatives cancel out");
+is(Rat.new(2, 4).nude, (1, 2), "Reduce to simplest form in constructor");
+is(Rat.new(39, 33).nude, (13, 11), "Reduce to simplest form in constructor");
+is(Rat.new(0, 33).nude, (0, 1), "Reduce to simplest form in constructor");
+is(Rat.new(1451234131, 60).nude, (1451234131, 60), "Reduce huge number to 
simplest form in constructor");
 
 # Test basic math
-is(~(1 / 4 + 1 / 4), "1/2", "1/4 + 1/4 = 1/2");
-is(~(1 / 4 + 2 / 7), "15/28", "1/4 + 2/7 = 15/28");
-is(~(1 / 4 + 1), "5/4", "1/4 + 1 = 5/4");
-is(~(1 + 1 / 4), "5/4", "1 + 1/4 = 5/4");
+is(1 / 4 + 1 / 4, 1/2, "1/4 + 1/4 = 1/2");
+isa_ok(1 / 4 + 1 / 4, Rat, "1/4 + 1/4 is a Rat");
+is(1 / 4 + 2 / 7, 15/28, "1/4 + 2/7 = 15/28");
+is(1 / 4 + 1, 5/4, "1/4 + 1 = 5/4");
+isa_ok(1 / 4 + 1, Rat, "1/4 + 1 is a Rat");
+is(1 + 1 / 4, 5/4, "1 + 1/4 = 5/4");
+isa_ok(1 + 1 / 4, Rat, "1 + 1/4 is a Rat");
+   
+is(1 / 4 - 1 / 4, 0/1, "1/4 - 1/4 = 0/1");
+is(1 / 4 - 3 / 4, -1/2, "1/4 - 3/4 = -1/2");
+is((1 / 4 - 3 / 4).nude, (-1, 2), "1/4 - 3/4 = -1/2 is simplified internally");
+isa_ok((1 / 4 - 3 / 4), Rat, "1/4 - 3/4 is a Rat");
+is(1 / 4 - 1, -3/4, "1/4 - 1 = -3/4");
+isa_ok(1 / 4 - 1, Rat, "1/4 - 1 is a Rat");
+is(1 - 1 / 4, 3/4, "1 - 1/4 = 3/4");
+isa_ok(1 - 1 / 4, Rat, "1 - 1/4 is a Rat");
+   
+is((2 / 3) * (5 / 4), 5/6, "2/3 * 5/4 = 5/6");
+is(((2 / 3) * (5 / 4)).nude, (5, 6), "2/3 * 5/4 = 5/6 is simplified 
internally");
+isa_ok((2 / 3) * (5 / 4), Rat, "2/3 * 5/4 is a Rat");
+is((2 / 3) * 2, 4/3, "2/3 * 2 = 4/3");
+isa_ok((2 / 3) * 2, Rat, "2/3 * 2 is a Rat");
+is(((2 / 3) * 3).nude, (2, 1), "2/3 * 3 = 2 is simplified internally");
+is(2 * (2 / 3), 4/3, "2 * 2/3 = 4/3");
+isa_ok(2 * (2 / 3), Rat, "2 * 2/3 is a Rat");
+is((3 * (2 / 3)).nude, (2, 1), "3 * 2/3 = 2 is simplified internally");
+   
+is((2 / 3) / (5 / 4), 8/15, "2/3 / 5/4 = 8/15");
+isa_ok((2 / 3) / (5 / 4), Rat, "2/3 / 5/4 is a Rat");
+is((2 / 3) / 2, 1/3, "2/3 / 2 = 1/3");
+is(((2 / 3) / 2).nude, (1, 3), "2/3 / 2 = 1/3 is simplified internally");
+isa_ok((2 / 3) / 2, Rat, "2/3 / 2 is a Rat");
+is(2 / (1 / 3), 6, "2 / 1/3 = 6");
+isa_ok(2 / (1 / 3), Rat, "2 / 1/3 is a Rat");
+is((2 / (2 / 3)).nude, (3, 1), "2 / 2/3 = 3 is simplified internally");
 
-is(~(1 / 4 - 1 / 4), "0/1", "1/4 - 1/4 = 0/1");
-is(~(1 / 4 - 3 / 4), "-1/2", "1/4 - 3/4 = -1/2");
-is(~(1 / 4 - 1), "-3/4", "1/4 - 1 = -3/4");
-is(~(1 - 1 / 4), "3/4", "1 - 1/4 = 3/4");
+# Give the arithmetical operators a workout
 
-is(~((2 / 3) * (5 / 4)), "5/6", "2/3 * 5/4 = 5/6");
-is(~((2 / 3) * 2), "4/3", "2/3 * 2 = 4/3");
-is(~(2 * (2 / 3)), "4/3", "2 * 2/3 = 4/3");
+for (1/2, 2/3, -1/4, 4/5, 2/7, 65/8) -> $a {
+    for (-7, -1, 0, 1, 2, 5, 7, 42) -> $b {
+        is_approx($a + $b, $a.Num + $b.Num, "Rat + Int works");
+        is_approx($b + $a, $b.Num + $a.Num, "Int + Rat works");
+        is_approx($a - $b, $a.Num - $b.Num, "Rat - Int works");
+        is_approx($b - $a, $b.Num - $a.Num, "Int - Rat works");
+        is_approx($a * $b, $a.Num * $b.Num, "Rat * Int works");
+        is_approx($b * $a, $b.Num * $a.Num, "Int * Rat works");
+        is_approx($a / $b, $a.Num / $b.Num, "Rat / Int works") if $b != 0;
+        is_approx($b / $a, $b.Num / $a.Num, "Int / Rat works");
+    }
+    
+    for (1/2, 2/3, -1/4, 4/5, 2/7, 65/8) -> $b {
+        is_approx($a + $b, $a.Num + $b.Num, "Rat + Rat works");
+        is_approx($b + $a, $b.Num + $a.Num, "Rat + Rat works");
+        is_approx($a - $b, $a.Num - $b.Num, "Rat - Rat works");
+        is_approx($b - $a, $b.Num - $a.Num, "Rat - Rat works");
+        is_approx($a * $b, $a.Num * $b.Num, "Rat * Rat works");
+        is_approx($b * $a, $b.Num * $a.Num, "Rat * Rat works");
+        is_approx($a / $b, $a.Num / $b.Num, "Rat / Rat works");
+        is_approx($b / $a, $b.Num / $a.Num, "Rat / Rat works");
+    }
+}
 
-is(~((2 / 3) / (5 / 4)), "8/15", "2/3 / 5/4 = 8/15");
-is(~((2 / 3) / 2), "1/3", "2/3 / 2 = 1/3");
-is(~(2 / (1 / 3)), "3/2", "2 / 1/3 = 3/2");
+# SHOULD: Add divide by zero / zero denominator tests
 
-
-
-
 done_testing;
 
 # vim: ft=perl6

Reply via email to