Skip to content

Instantly share code, notes, and snippets.

@minhquang4334
Last active December 22, 2020 02:24
Show Gist options
  • Save minhquang4334/ac968f752f23f833f74b30a5a5427d91 to your computer and use it in GitHub Desktop.
Save minhquang4334/ac968f752f23f833f74b30a5a5427d91 to your computer and use it in GitHub Desktop.
TestDrivenDevelopmentの研修でのやったソースコードです。
TDD研修の課題です。
課題の内容は: https://gist.github.com/twada/856c37103ebd3d1fb973ba2c2654f9d6
TODO
Product
name | price | sale_date | sale_rate
'MS WORD' | 18800 | [0] | [1]
'Excel' | 27800 | [0, 30] | [2/3, 1/3]
'SQL Server' | 919000 | [0, 60, 120] | [1/3, 1/3, 1/3]
When Init Product
- Word
- [X] Word Name should be
- [X] Word Price should be
- Excel
- [X] Excel Name should be
- [X] Excel Price should be
- SqlServer
- [X] SqlServer Name should be
- [X] SqlServer Price should be
When Sign On Product
- Word
- [X] Contract Product Name should be Word
- [X] Contract Product Name should be Today
- Excel
- [X] Contract Product Name should be Excel
- [X] Contract Product Name should be Today
- SqlServer
- [X] Contract Product Name should be SqlServer
- [X] Contract Product Name should be Today
When Check Sales On Product By Date
- Word
- [X] Sales on today should be
- [X] Sales on 30 days after should be
- [X] Sales on 120 days after should be
- [X] Sales on date before today should be
- Excel
- [X] Sales on today should be
- [X] Sales on 29 days after should be
- [X] Sales on 30 days after should be
- [X] Sales on 120 days after should be
- [X] Sales on date before today should be
- SqlServer
- [X] Sales on today should be
- [X] Sales on 59 days after should be
- [X] Sales on 60 days after should be
- [X] Sales on 119 days after should be
- [X] Sales on 120 days after should be
- [X] Sales on 121 days after should be
- [X] Sales on date before today should be
class Product
attr_reader :name, :price
attr_writer :price_code
# Product.new ('Ms Word', MsWordPrice.new)
def initialize(name, price_code)
@name = name
@price_code = price_code
@price = @price_code.price
end
def revenue_after_num_days(days_after_sale_date)
@price_code.revenue_after_num_days(days_after_sale_date)
end
end
module DefaultPrice
def price_to_int(price)
price.to_i
end
end
class MsWordPrice
include DefaultPrice
def initialize(price=18800)
@price = price
end
def revenue_after_num_days(days_after_sale_date, price)
return @price if days_after_sale_date >= 0
return 0
end
end
class ExcelPrice
include DefaultPrice
def initialize(price=27800)
@price = price
end
def revenue_after_num_days(days_after_sale_date)
return @price if days_after_sale_date >= 30
return price_to_int(@price * 2/3) if days_after_sale_date >= 0
return 0
end
end
class SqlServerPrice
include DefaultPrice
def initialize(price=919000)
@price = price
end
def revenue_after_num_days(days_after_sale_date, price)
return price if days_after_sale_date >= 120
return price_to_int(@price * 2/3) if days_after_sale_date >= 60
return price_to_int(@price * 1/3) if days_after_sale_date >= 0
return 0
end
end
class Contract
attr_reader :product, :sign_on
def initialize(product)
@product = product
@sign_on = Time.now.utc.to_date #
end
def sales_on_date(date)
num_date_after = (date - @sign_on).to_i
@product.revenue_after_num_days(num_date_after)
end
end
class Product
attr_reader :name, :sale_date, :sale_ratio_per_date
attr_accessor :price
def revenue_with_rate(rate)
@price * rate
end
end
class MsWord < Product
def initialize(price = 18800)
@name = 'Word'
@price = price
@sale_date = [0]
@sale_ratio_per_date = [1]
end
end
class Excel < Product
def initialize(price = 27800)
@name = 'Excel'
@price = price
@sale_date = [0, 30]
@sale_ratio_per_date = [2.0/3, 1.0/3]
end
end
class SqlServer < Product
def initialize(price = 919000)
@name = 'SqlServer'
@price = price
@sale_date = [0, 60, 120]
@sale_ratio_per_date = [1.0/3, 1.0/3, 1.0/3]
end
end
class Contract
def initialize(product)
@product = product
@sign_on = Time.now.utc.to_date #
end
def sign_on
@sign_on
end
def product
@product
end
def sales_on_date(date)
num_date_after = (date - @sign_on).to_i
sales_on_date_after(num_date_after)
end
def sales_on_date_after(num_date_after)
total_sales_on_date = 0
@product.sale_date.each_with_index do |sale_date, idx|
total_sales_on_date += @product.revenue_with_rate(@product.sale_ratio_per_date[idx]) if (num_date_after >= sale_date)
end
total_sales_on_date.to_i
end
end
describe Product do
let(:today_date) {Time.now.utc.to_date}
describe "Product Initization" do
context "when init Word" do
let(:word) {MsWord.new}
it "should Word name" do
expect(word.name).to eq "Word"
end
it "should Word product cost" do
expect(word.price).to eq (18800)
end
end
context "when init Excel" do
let(:excel) {Excel.new}
it "should Excel name" do
expect(excel.name).to eq "Excel"
end
it "should Excel product cost" do
expect(excel.price).to eq (27800)
end
end
context "when init SqlServer" do
let(:sql) {SqlServer.new}
it "should SqlServer name" do
expect(sql.name).to eq "SqlServer"
end
it "should SqlServer product cost" do
expect(sql.price).to eq (919000)
end
end
end
describe "sign on" do
context "when sign on with Word" do
let(:word) {MsWord.new}
let(:contract) {Contract.new(word)}
it "should Contract product is word" do
expect(contract.product.name).to eq "Word"
end
it "should Word Contract sign on today" do
expect(contract.sign_on).to eq today_date
end
end
context "when sign on with Excel" do
let(:excel) {Excel.new}
let(:contract) {Contract.new(excel)}
it "should Contract product is excel" do
expect(contract.product.name).to eq "Excel"
end
it "should Excel Contract sign on today" do
expect(contract.sign_on).to eq today_date
end
end
context "when sign on with SqlServer" do
let(:sql_server) {SqlServer.new}
let(:contract) {Contract.new(sql_server)}
it "should Contract product is sqlserver" do
expect(contract.product.name).to eq "SqlServer"
end
it "should SqlServer Contract sign on today" do
expect(contract.sign_on).to eq today_date
end
end
end
describe "sales of product on specific date" do
context "when check revenue with Word" do
let(:word) {MsWord.new(18800)}
let(:contract) {Contract.new(word)}
where(:case_name, :date, :expected_revenue) do
[
["today", 0, 18800],
["after_30_days", 30, 18800],
["after_120_days", 120, 18800],
["after_before_today", -1, 0]
]
end
with_them do
it "should revenue of Word" do
expect(contract.sales_on_date(today_date + date)).to eq expected_revenue
end
end
end
context "when check revenue with Excel" do
let(:excel) {Excel.new(27800)}
let(:contract) {Contract.new(excel)}
where(:case_name, :date, :expected_revenue) do
[
["today", 0, 18533],
["after_29_days", 29, 18533],
["after_30_days", 30, 27800],
["after_120_days", 120, 27800]
]
end
with_them do
it "should revenue of excel" do
expect(contract.sales_on_date(today_date + date)).to eq expected_revenue
end
end
end
context "when check sales with Sql Server" do
let(:sql) {SqlServer.new(919000)}
let(:contract) {Contract.new(sql)}
let(:expeted_sales) {
{
'today': (sql.price * 1/3).to_i,
'after_59_days': (sql.price * 1/3).to_i,
'after_60_days': (sql.price * 2/3).to_i,
'after_119_days': (sql.price * 2/3).to_i,
'after_120_days': sql.price,
'before_today': 0
}
}
where(:case_name, :date, :expected_revenue) do
[
["today", 0, 306333],
["after_59_days", 59, 306333],
["after_60_days", 60, 612666],
["after_119_days", 119, 612666],
["after_120_days", 120, 919000],
["before_today", -1, 0]
]
end
with_them do
it "should revenue of Sql Server" do
expect(contract.sales_on_date(today_date + date)).to eq expected_revenue
end
end
end
end
end
@hachi-eiji
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment