Skip to content

Instantly share code, notes, and snippets.

@MartinKnopf
Last active August 29, 2015 13:57
Show Gist options
  • Save MartinKnopf/9482746 to your computer and use it in GitHub Desktop.
Save MartinKnopf/9482746 to your computer and use it in GitHub Desktop.
Code Kata #9 'Checkout' in JavaScript (see http://codekata.com/kata/kata09-back-to-the-checkout/)
var _ = require('lodash');
module.exports = Checkout;
function Checkout(pricingRules) {
this.pricingRules = pricingRules;
this.basket = {};
}
Checkout.prototype.scan = function(item) {
this.basket[item] = ++this.basket[item] || 1;
};
Checkout.prototype.getTotal = function() {
var total = 0
, self = this;
_.forIn(this.basket, function(quantity, item) { total += self.pricingRules[item](quantity) });
return total;
};
module.exports = {
'A': bundledPricing({singlePrice: 50, bundledPrice: 130, bundleSize: 3}),
'B': bundledPricing({singlePrice: 30, bundledPrice: 45, bundleSize: 2}),
'C': singlePricing({singlePrice: 30})
};
function bundledPricing(options) {
return function(quantity) {
var bundeledQuantity = (quantity - quantity %options.bundleSize) / options.bundleSize;
quantity = quantity %options.bundleSize;
return bundeledQuantity * options.bundledPrice + quantity * options.singlePrice;
}
}
function singlePricing(options) {
return function(quantity) {
return quantity * options.singlePrice;
}
}
var chai = require('chai')
, Checkout = require('./checkout')
, PricingRules = require('./pricingRules');
chai.should();
describe('testCheckout.js', function() {
describe('When item A is scanned once and item B is scanned once', function() {
it('should return total price of 80', function() {
var checkout = new Checkout(PricingRules);
checkout.scan('A');
checkout.scan('B');
checkout.getTotal().should.equal(80);
});
});
describe('When item A is scanned three times and item B is scanned once', function() {
it('should return total price of 160', function() {
var checkout = new Checkout(PricingRules);
checkout.scan('A');
checkout.scan('A');
checkout.scan('A');
checkout.scan('B');
checkout.getTotal().should.equal(160);
});
});
describe('When item A is scanned four times and item B is scanned two times', function() {
it('should return total price of 225', function() {
var checkout = new Checkout(PricingRules);
checkout.scan('A');
checkout.scan('A');
checkout.scan('A');
checkout.scan('A');
checkout.scan('B');
checkout.scan('B');
checkout.getTotal().should.equal(225);
});
});
});
var chai = require('chai')
, PricingRules = require('./pricingRules');
chai.should();
describe('testCheckout.js', function() {
describe('When item A is scanned once', function() {
it('should return price for item A', function() {
PricingRules['A'](1).should.equal(50);
});
});
describe('When item A is scanned twice', function() {
it('should return price for 2 items A', function() {
PricingRules['A'](2).should.equal(100);
});
});
describe('When item A is scanned three times', function() {
it('should return bundel price for 3 items A', function() {
PricingRules['A'](3).should.equal(130);
});
});
describe('When item A is scanned four times', function() {
it('should return bundle price for 3 items A plus 1 single item price', function() {
PricingRules['A'](4).should.equal(180);
});
});
describe('When item B is scanned once', function() {
it('should return price for item B', function() {
PricingRules['B'](1).should.equal(30);
});
});
describe('When item B is scanned five times', function() {
it('should return bundle price for 4 items B plus 1 single item price', function() {
PricingRules['B'](5).should.equal(120);
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment