勝田 均
- [2004/7/10]Ruby1.8のTest::Unitを使うように直しました。
- [2004/6/6]メソッド名を少しRubyらしく変更しました。
- [2004/4/7]クラス名が途中から間違っていたので訂正しました。(寺田さんありがとうございました)
- [2004/4/6]Stackクラスの作成がそれほど面白いものにならなかったので、別の課題で再挑戦してみました。
- 課題は、Pragmatic Unit TestingのExercise2が元になっています。
注文入力システムで使うクラスShoppingCartを作ります。このクラスは次の3つのメソッドを持つことが求められています。
それでは実装を始めてみましょう。
テスト成功(OK)
テスト失敗(Failure)
エラー(Error)
require 'test/unit'
class ShoppingCartTest < Test::Unit::TestCase
end
def ShoppingCart
end
class ShoppingCartTest < Test::Unit::TestCase
def test_brand_new_cart
assert(false, "no implementation")
end
end
require ShoppingCart' class ShoppingCartTest < Test::Unit::TestCase def test_brand_new_cart assert(false, "no implementation") cart = ShoppingCart.new assert_equal(0, cart.item_count) end end
class ShoppingCart
def item_count
return 0 #仮実装
end
end
class ShoppingCartTest < Test::Unit::TestCase ... def test_add_items assert(false, "no implementation") end end
class ShoppingCartTest < Test::Unit::TestCase ... def test_add_items assert(false, "no implementation") cart = ShoppingCart.new cart.add_items("item", 0) assert_equal(0, cart.item_count) end end
class ShoppingCart def item_count return 0 #仮実装 end def add_items(item, quantity) end end
class ShoppingCartTest < Test::Unit::TestCase def test_brand_new_cart cart = ShoppingCart.new assert_equal(0, cart.item_count) end def test_add_items cart = ShoppingCart.new assert_equal(0, cart.item_count) cart.add_items("item", 0) assert_equal(0, cart.item_count) end end
class ShoppingCartTest < Test::Unit::TestCase def test_add_items cart = ShoppingCart.new assert_equal(0, cart.item_count) cart.add_items("item", 0) assert_equal(0, cart.item_count) cart.add_items("item", 1) assert_equal(1, cart.item_count) end end
class ShoppingCart def initialze @item_count = 0 end def item_count return 0 #仮実装 return @item_count end def add_items(item, quantity) @item_count += 1 end end
class ShoppingCartTest < Test::Unit::TestCase def test_add_items cart = ShoppingCart.new assert_equal(0, cart.item_count) cart.add_items("item", 0) assert_equal(0, cart.item_count) cart.add_items("item", 1) assert_equal(1, cart.item_count) cart.add_items("item", 2) assert_equal(3, cart.item_count) end end
class ShoppingCart ... def add_items(item, quantity) @item_count += 1 @item_count += quantity end end
class ShoppingCartTest < Test::Unit::TestCase ... def test_add_negative_count_items assert(false, "no implementation") end end
class ShoppingCartTest < Test::Unit::TestCase ... def test_add_negative_count_items assert(false, "no implementation") cart = ShoppingCart.new ex = assert_raises(ArgumentError) { cart.add_items("item", -1) } assert_equal("negative quantity", ex.message) assert_equal(0, cart.item_count) end end
class ShoppingCart
...
def add_items(item, quantity)
raise ArgumentError.new("negative quantity") if (quantity < 0)
@item_count += quantity
end
end
class ShoppingCartTest < Test::Unit::TestCase def setup @cart = ShoppingCart.new end def test_add_items cart = ShoppingCart.new assert_equal(0, cart.item_count) assert_equal(0, @cart.item_count) cart.add_items("item", 0) @cart.add_items("item", 0) assert_equal(0, cart.item_count) assert_equal(0, @cart.item_count) cart.add_items("item", 1) @cart.add_items("item", 1) assert_equal(1, cart.item_count) assert_equal(1, @cart.item_count) cart.add_items("item", 2) @cart.add_items("item", 2) assert_equal(3, cart.item_count) assert_equal(3, @cart.item_count) end def test_add_negative_count_items cart = ShoppingCart.new ex = assert_raises(ArgumentError) { cart.add_items("item", -1) @cart.add_items("item", -1) } assert_equal("negative quantity", ex.message) assert_equal(0, cart.item_count) assert_equal(0, @cart.item_count) end end
class ShoppingCartTest < Test::Unit::TestCase ... def test_delete_items assert(false, "no implementation") end end
class ShoppingCartTest < Test::Unit::TestCase ... def test_delete_items assert(false, "no implementation") @cart.add_items("item", 1) @cart.delete_items("item", 0) assert_equal(1, @cart.item_count) end end
class ShoppingCart ... def delete_items(item, quantity) end end
class ShoppingCartTest < Test::Unit::TestCase ... def test_delete_items @cart.add_items("item", 1) @cart.delete_items("item", 0) assert_equal(1, @cart.item_count) @cart.delete_items("item", 1) assert_equal(0, @cart.item_count) end end
class ShoppingCart
...
def delete_items(item, quantity)
@item_count -= quantity
end
end
class ShoppingCartTest < Test::Unit::TestCase ... def test_delete_negative_count_items assert(false, "no implementation") end end
class ShoppingCartTest < Test::Unit::TestCase ... def test_delete_negative_count_items assert(false, "no implementation") @cart.add_items("item", 1) ex = assert_raises(ArgumentError) { @cart.delete_items("item", -1) } assert_equal("negative quantity", ex.message) assert_equal(0, cart.item_count) end end
class ShoppingCart
...
def delete_items(item, quantity)
raise ArgumentError.new("negative quantity") if (quantity < 0)
@item_count -= quantity
end
end
class ShoppingCart ... def add_items(item, quantity) raise ArgumentError.new("negative quantity") if (quantity < 0) assert_quantity_is_not_negative(quantity) @item_count += quantity end def delete_items(item, quantity) raise ArgumentError.new("negative quantity") if (quantity < 0) assert_quantity_is_not_negative(quantity) @item_count -= quantity end def assert_quantity_is_not_negative(quantity) raise ArgumentError.new("negative quantity") if (quantity < 0) end end
class ShoppingCartTest < Test::Unit::TestCase ... def test_delete_not_exist_items assert(false, "no implementation") end end
class ShoppingCartTest < Test::Unit::TestCase ... def test_delete_not_exist_items assert(false, "no implementation") ex = assert_raises(RuntimeError) { @cart.delete_items("item", 1) } assert_equal(0, cart.item_count) end end
class ShoppingCart def initialize @item_count = 0 @items = [] end ... def add_items(item, quantity) assert_quantity_is_not_negative(quantity) @items.push(item) unless @items.include?(item) @item_count += quantity end def delete_items(item, quantity) assert_quantity_is_not_negative(quantity) raise "no such item" unless @items.include?(item) @item_count -= quantity end ... end
class ShoppingCartTest < Test::Unit::TestCase ... def test_delete_not_exist_items ex = assert_raises(RuntimeError) { @cart.delete_items("item", 1) } assert_equal(0, cart.item_count) @cart.add_items("item", 1) @cart.delete_items("item", 1) ex = assert_raises(RuntimeError) { @cart.delete_items("item", 1) } assert_equal(0, cart.item_count) end end
class ShoppingCartTest < Test::Unit::TestCase ... def test_delete_not_exist_items ex = assert_raises(RuntimeError) { @cart.delete_items("item", 1) } assert_equal(0, cart.item_count) @cart.add_items("item", 1) @cart.delete_items("item", 1) ex = assert_raises(RuntimeError) { @cart.delete_items("item", 1) } assert_equal(0, cart.item_count) end end
class ShoppingCart def initialize @item_count = 0 @items = [] @itemDict = {} end ... def add_items(item, quantity) assert_quantity_is_not_negative(quantity) @items.push(item) unless @items.include?(item) unless @itemDict.has_key?(item) @itemDict[item] = quantity end @item_count += quantity end end
class ShoppingCart def initialize @item_count = 0 @items = [] @itemDict = {} end ... def add_items(item, quantity) assert_quantity_is_not_negative(quantity) @items.push(item) unless @items.include?(item) unless @itemDict.has_key?(item) @itemDict[item] = quantity end @item_count += quantity end def delete_items(item, quantity) assert_quantity_is_not_negative(quantity) raise "no such item" unless @items.include?(item) raise "no such item" unless @itemDict.has_key?(item) @item_count -= quantity end end
class ShoppingCartTest < Test::Unit::TestCase ... def test_delete_not_exist_items ex = assert_raises(RuntimeError) { @cart.delete_items("item", 1) } assert_equal(0, cart.item_count) @cart.add_items("item", 1) @cart.delete_items("item", 1) ex = assert_raises(RuntimeError) { @cart.delete_items("item", 1) } assert_equal(0, cart.item_count) end end
class ShoppingCart ... def add_items(item, quantity) assert_quantity_is_not_negative(quantity) unless @itemDict.has_key?(item) if @itemDict.has_key?(item) @itemDict[item] += quantity else @itemDict[item] = quantity end @item_count += quantity end def delete_items(item, quantity) assert_quantity_is_not_negative(quantity) raise "no such item" unless @itemDict.has_key?(item) if (@itemDict[item] == quantity) @itemDict.delete(item) else @itemDict[item] -= quantity end @item_count -= quantity end end
class ShoppingCart ... def item_count return @item_count return @itemDict.values.inject(0) {|sum, each| sum + each } end ... end
class ShoppingCart def initialize @item_count = 0 @itemDict = {} end ... def add_items(item, quantity) assert_quantity_is_not_negative(quantity) unless @itemDict.has_key?(item) if @itemDict.has_key?(item) @itemDict[item] += quantity else @itemDict[item] = quantity end @item_count += quantity end def delete_items(item, quantity) assert_quantity_is_not_negative(quantity) raise "no such item" unless @itemDict.has_key?(item) if (@itemDict[item] == quantity) @itemDict.delete(item) else @itemDict[item] -= quantity end @item_count -= quantity end end
class ShoppingCartTest < Test::Unit::TestCase ... def test_delete_too_large_count_items assert(false, "no implementation") end end
class ShoppingCartTest < Test::Unit::TestCase ... def test_delete_too_large_count_items assert(false, "no implementation") @cart.add_items("item", 1) ex = assert_raises(RuntimeError) { @cart.delete_items("item", 2) } assert_equal(1, cart.item_count) end end
class ShoppingCart
...
def delete_items(item, quantity)
assert_quantity_is_not_negative(quantity)
raise "no such item" unless @itemDict.has_key?(item)
raise "delete quantity is larger than current quantity" if (quantity > @itemDict[item])
if @itemDict[item] == quantity
@itemDict.delete(item)
else
@itemDict[item] -= quantity
end
end
end
これでおしまいです。