Re: C-Style Ints (#85) - not a spoiler, a test harness

Given the number of edge conditions for this quiz it seemed like a good
place for a test harness. Here is the irb session in the quiz
translated to
a test harness. It is my first use of the test framework so hopefully I
haven’t made any horrible errors. Just put this in the file quiz85.rb
and
then use “ruby quiz85.rb” to test for correctness (it works better from
the
command line than from irb - I don’t know why but someone here does).
Have
fun!

test harness for ruby quiz 85

see it at:

Ruby Quiz - C-Style Ints (#85)

require ‘test/unit’
require ‘UnsignedFixedWidthInt.rb’
require ‘SignedFixedWidthInt.rb’

class TestUnsignedFixedWidthInt < Test::Unit::TestCase
def test_quiz_example_unsigned
n = UnsignedFixedWidthInt.new(0xFF, 8)
assert_equal( n, 255 )
n += 2
assert_equal( n, 1 )
n = n << 1
assert_equal( n, 2 )
n = n >> 1
assert_equal( n, 1 )
assert_equal( ~n, 254 )
n += 12
assert_equal( n, 13 )
n = n & 0x0E
assert_equal( n, 12 )
end
def test_quiz_example_too_wide
n = UnsignedFixedWidthInt.new(0x0, 8)
assert_equal( n, 0 )
n += 0xFFEE
assert_equal( n, 238 )
end
end

class TestUnsignedFixedWidthInt < Test::Unit::TestCase
def test_quiz_example_signed
n = SignedFixedWidthInt.new(0x01, 8)
assert_equal( n, 1 )
n = n << 7
assert_equal( n, -128 )
n -= 1
assert_equal( n, 127 )
n = n >> 6
assert_equal( n, 1 )
n -= 2
assert_equal( n, -1 )
n = n ^ 0xF3
assert_equal( n, 12 )
n = n | 0x01
assert_equal( n, 13 )
end
end

On 7/1/06, John B. [email protected] wrote:

Given the number of edge conditions for this quiz it seemed like a good
place for a test harness. Here is the irb session in the quiz translated to
a test harness. It is my first use of the test framework so hopefully I
haven’t made any horrible errors.

Good idea, here are the tests i’m using. It also includes the irb
session as well as a number of other tests.
It assumes the result of any calculation with FWI’s and integers is a
FWI.
I’m using a different syntax for the FWI’s, but it should be easy
enough to convert this to whatever you’re using.

Gmail will probably mess up my indent again, so here’s a rafb link as
well:
http://rafb.net/paste/results/rwO1Kf64.html

class FWITest < Test::Unit::TestCase
def test_unsigned_8
uint8 = UnsignedFWI(8)
n=uint8.new(0xFF)
assert_equal(255 , n)
n += 2
assert_equal(1 , n)
n = n << 1
assert_equal(2 , n)
n = n >> 1
assert_equal(1 , n)
assert_equal(254 , ~n)
n += 12
assert_equal(13 , n)
n = n & 0x0E
assert_equal(12 , n)
n -= 13
assert_equal(255 , n)
end

def test_signed_8
int8 = SignedFWI(8)
n = int8.new(1)
assert_equal(n,1)
n = n << 7
assert_equal(-128 , n)
n -= 1
assert_equal(127 , n)
n = n >> 6
assert_equal(1 , n)
n -= 2
assert_equal(-1 , n)
n = n ^ 0xF3
assert_equal(12 , n)
n = n | 0x01
assert_equal(13 , n)
end

def test_too_wide
uint8 = UnsignedFWI(8)
assert_equal(238, uint8.new(0) + 0xFFEE)
end

def test_short_length_unsigned
uint3 = UnsignedFWI(3)
uint10 = UnsignedFWI(10)
n = uint3.new(8)
assert_equal(0, n)
n -= 7
assert_equal(1, n)
assert_equal(0, n**23 + 7)
m = uint3.new(8)
assert_equal(1, n + m)
assert_equal(1, m + n)
assert_equal(1, 8 + n)
l = uint10.new(11)
assert_equal(1100-1024, l100)
assert_equal(1100-1024, 100
l)
end

def test_short_length_signed
int3 = SignedFWI(3)
n = int3.new(4)
assert_equal(-4, n)
assert_equal(3 , (+n)-1)
assert_equal(n , 8+n)
assert_equal(-n, n)
n -= 1
assert_equal(3 , n)
end

def test_long_length_signed
int76 = SignedFWI(76)
n = int76.new( 1<<75 )
assert_equal(-(1<<75) , n)
n -= 1
assert_equal((1<<75)-1 , n)
n = int76.new(2)
n *= (1<<75)-1
assert_equal(-2 , n)
end

def test_power
uint3 = UnsignedFWI(3)
assert_equal(2, 2 ** uint3.new(1))
assert_equal(0, 2 ** uint3.new(3))
assert_equal(0, 2 ** uint3.new(67))
assert_equal(1, 3 ** uint3.new(2))
assert_equal(3, uint3.new(3) ** uint3.new(-1)) # 3**7 mod 8
end
end

“Sander L.” [email protected] writes:

Good idea, here are the tests i’m using. It also includes the irb
session as well as a number of other tests.
It assumes the result of any calculation with FWI’s and integers is a FWI.
I’m using a different syntax for the FWI’s, but it should be easy
enough to convert this to whatever you’re using.

I like this syntax though better than the one in the quiz and may
adopt it. Actually, it shouldn’t be too hard to support both
syntaxes…

I do take issue with one of your tests, though:

def test_power
uint3 = UnsignedFWI(3)
assert_equal(2, 2 ** uint3.new(1))
assert_equal(0, 2 ** uint3.new(3))
assert_equal(0, 2 ** uint3.new(67))
assert_equal(1, 3 ** uint3.new(2))
assert_equal(3, uint3.new(3) ** uint3.new(-1)) # 3**7 mod 8
end

That just feels wrong. (except for the last one) I would write:

def test_power
uint3 = UnsignedFWI(3)
assert_equal(2, uint3.new(2) ** 1)
assert_equal(0, uint3.new(2) ** 3)
assert_equal(0, uint3.new(2) ** 67)
assert_equal(1, uint3.new(3) ** 2)
assert_equal(3, uint3.new(3) ** uint3.new(-1)) # 3**7 mod 8
end

And maybe:

def test_power_fwi_exponent
uint3 = UnsignedFWI(3)
assert_equal(2, 2 ** uint3.new(1))
assert_equal(8, 2 ** uint3.new(3))
assert_equal(8, 2 ** uint3.new(67))
end

I really think that you want to keep exponentiation looking like
repeated multiplication of the first argument.

Of course, it would be nice if our kind quiz host would respond with a
few rulings for the edge cases I outlined before. At least then we’d
know when we were ignoring the rules of the quiz.

Daniel M. [email protected] writes:

Of course, it would be nice if our kind quiz host would respond with a
few rulings for the edge cases I outlined before. At least then we’d
know when we were ignoring the rules of the quiz.

And I see that he already did, so once again see that I should learn
to read my entire mailbox before responding to anything.

On 7/2/06, Daniel M. [email protected] wrote:

I do take issue with one of your tests, though:

That just feels wrong. (except for the last one) I would write:
def test_power

end

Agreed, the test put way too much focus on fixnum ** fwi.
This was because my implementation first assumed any binary operation
was commutative (it just switched both operands if the first was a
fixnum), so 2 ** uint3.new(1) was uint3.new(1)**2=1, and the test was
there to help me fix this.

And maybe:
assert_equal(8, 2 ** uint3.new(67))

I really think that you want to keep exponentiation looking like
repeated multiplication of the first argument.

And i really think the result should be a fwi, for consistency with
multiplication (‘repeated addition’).
Anyway, in my implementation 2 ** uint3.new(67).to_i == 8, so there’s
still a way to get those calculations done as well.

On Jul 1, 2006, at 7:39 PM, Daniel M. wrote:

repeated multiplication of the first argument.
I think that’s a good point.

Of course, it would be nice if our kind quiz host would respond with a
few rulings for the edge cases I outlined before. At least then we’d
know when we were ignoring the rules of the quiz.

The main rule: Do what you feel is right. If you explain why you
make the choices you do and convince me you are right, I’ll talk
about how clever you are in the summary. :wink:

Sorry I wasn’t around this weekend. I felt it better to be hard to
reach for a couple of days than to cancel this week’s quiz altogether.

James Edward G. II