def test_csv_as_string(): ''' test that we can load product csv data from \n separated string and while we're at it, test that cart.__repr__ produces expected csv string representation. ''' from cart import Cart, load_product_csv products_csv = 'sample_products.csv' products = load_product_csv(products_csv) cart = Cart() # add the product,price contents to fill up the cart with # enough product to verify all spec'd discounts. cart.add_products(products) csv_str = cart.__repr__() s = lambda x: x['id'] # sort, since cart sorts and original csv sample isn't pre-sorted assert sorted(products, key=s) == sorted(load_product_csv(csv_str), key=s)
def test_buy_1_get_y_pct_off_z(): from cart import Cart, load_product_csv from cart.discounts import buy_1_get_y_pct_off_z products_csv = 'sample_products.csv' products = load_product_csv(products_csv) cart = Cart() # add the product,price contents to fill up the cart with # enough product to verify all spec'd discounts. cart.add_products(products) # should be 6 items in the cart (+1 discounts) assert len(cart._contents) == 5 # * get 20% off a Snickers bar if you buy a Mars bar at the same time discounts = buy_1_get_y_pct_off_z(cart.contents, 'mars bar', discounted='snickers bar', pct_off=0.2) # 20% of .70 (snickers bar) is discount of -0.14 assert round(discounts[0]['price'], 2) == -0.14 cart.apply_discounts(discounts) # should be 6 items in the cart (+1 discounts) assert len(cart._contents) == 6 receipt = cart.checkout() # round due to floating point resolution issues (eg, might be 18.880000002) assert receipt[-1]['id'] == 'grand_total' assert round(receipt[-1]['price'], 2) == 7.1 # discounts... assert receipt[-2]['id'] == 'discounts' assert round(receipt[-2]['price'], 2) == -0.14 # total assert receipt[-3]['id'] == 'total' assert round(receipt[-3]['price'], 2) == 7.24 print str(cart)
def test_spec(): from cart import Cart, load_product_csv from cart.discounts import buy_x_get_y, buy_1_get_y_pct_off_z products_csv = 'sample_products.csv' products = load_product_csv(products_csv) cart = Cart() # add the same contents several times to fill up the cart with # enough product to verify all spec'd discounts. cart.add_products(products) cart.add_products(products) cart.add_products(products) # should be 15 items in the cart at this point assert len(cart._contents) == 15 # discounts that should work according to spec # * "buy one get one free" on ice cream discounts = buy_x_get_y(cart.contents, 'snickers bar', buy=1, get=1) # buy 1 snickers bar 0.70 and get one free at -0.70 assert round(discounts[0]['price'], 2) == -0.70 cart.apply_discounts(discounts) # should be 16 items in the cart (+1 discount) assert len(cart._contents) == 16 # shouldn't be possible to apply the same discount twice assert 'snickers bar' in cart._discounts try: cart.apply_discounts(discounts) except RuntimeError: pass else: assert False, "shouldn't be able to apply same discount twice" # should still be 16 items in the cart (+1 discount) assert len(cart._contents) == 16 # * buy two punnets of strawberries, and get the third free discounts = buy_x_get_y(cart.contents, 'strawberries', buy=2, get=1) # buy 2 straberries at 2.00 each and get 2.00 off assert round(discounts[0]['price'], 2) == -2.00 cart.apply_discounts(discounts) assert 'strawberries' in cart._discounts # should be 17 items in the cart (+2 discounts) assert len(cart._contents) == 17 # * get 20% off a Snickers bar if you buy a Mars bar at the same time discounts = buy_1_get_y_pct_off_z( cart.contents, 'mars bar', discounted='snickers bar', pct_off=0.2) try: # should fail since we've already applied discount to 'snickers bar' in # cart cart.apply_discounts(discounts) except RuntimeError: pass else: assert False, ("shouldn't be able to apply multiple discounts " "to same product type!") # should still be 17 items in the cart (+2 discounts) assert len(cart._contents) == 17 # we shouldn't have a receipt yet assert cart._receipt == [] # we shouldn't have 'checkedout' yet assert cart._checkout is False receipt = cart.checkout() # now we should have a receipt assert cart._receipt is not None # now we should have 'checkedout' assert cart._checkout is True # cart will hold onto the receipt and return a copy assert cart.receipt == receipt # round due to floating point resolution issues (eg, might be 18.880000002) assert receipt[-1]['id'] == 'grand_total' assert round(receipt[-1]['price'], 2) == 19.02 # discounts... assert receipt[-2]['id'] == 'discounts' assert round(receipt[-2]['price'], 2) == -2.7 # total assert receipt[-3]['id'] == 'total' assert round(receipt[-3]['price'], 2) == 21.72 try: cart.checkout() except RuntimeError: pass else: assert False, "shouldn't be able to checkout more than once!" print str(cart)