Skip to content

Instantly share code, notes, and snippets.

@Martin-Alexander
Created April 23, 2019 22:14
Show Gist options
  • Save Martin-Alexander/ef4e46e7570fd33580b1f82521a2ff26 to your computer and use it in GitHub Desktop.
Save Martin-Alexander/ef4e46e7570fd33580b1f82521a2ff26 to your computer and use it in GitHub Desktop.
begin
require_relative "../app/models/meal"
rescue LoadError => e
if e.message =~ /meal/
describe "Meal" do
it "You need a `meal.rb` file for your `Meal` model" do
fail
end
end
else
raise e
end
end
describe "Meal", :meal do
it "should be initialized with a hash of properties" do
properties = { id: 1, name: "Margherita", price: 8 }
meal = Meal.new(properties)
expect(meal).to be_a(Meal)
end
describe "#id" do
it "should return the meal id" do
meal = Meal.new({ id: 42 })
expect(meal.id).to eq(42)
end
end
describe "#id=" do
it "should set the meal id" do
meal = Meal.new({ id: 42 })
meal.id = 43
expect(meal.id).to eq(43)
end
end
describe "#name" do
it "should return the name of the meal" do
meal = Meal.new({ name: "Margherita" })
expect(meal.name).to eq("Margherita")
end
end
describe "#price" do
it "should return the price of the meal" do
meal = Meal.new({ price: 8 })
expect(meal.price).to eq(8)
end
end
end
require "fileutils"
require_relative "support/csv_helper"
begin
require_relative "../app/repositories/meal_repository"
rescue LoadError => e
if e.message =~ /meal_repository/
describe "MealRepository" do
it "You need a `meal_repository.rb` file for your `MealRepository`" do
fail
end
end
else
raise e
end
end
describe "MealRepository", :meal do
let(:meals) do
[
[ "id", "name", "price" ],
[ 1, "Margherita", 8 ],
[ 2, "Capricciosa", 11 ],
[ 3, "Napolitana", 9 ],
[ 4, "Funghi", 12 ],
[ 5, "Calzone", 10 ]
]
end
let(:csv_path) { "spec/support/meals.csv" }
before(:each) do
CsvHelper.write_csv(csv_path, meals)
end
def elements(repo)
repo.instance_variable_get(:@meals) ||
repo.instance_variable_get(:@elements)
end
describe "#initialize" do
it "should take one argument: the CSV file path to store meals" do
expect(MealRepository.instance_method(:initialize).arity).to eq(1)
end
it "should not crash if the CSV path does not exist yet. Hint: use File.exist?" do
expect { MealRepository.new('unexisting_file.csv') }.not_to raise_error
end
it "store meals in memory in an instance variable `@meals` or `@elements`" do
repo = MealRepository.new(csv_path)
expect(elements(repo)).to be_a(Array)
end
it "loads existing meals from the CSV" do
repo = MealRepository.new(csv_path)
loaded_meals = elements(repo) || []
expect(loaded_meals.length).to eq(5)
end
it "fills the `@meals` with instance of `Meal`, setting the correct types on each property" do
repo = MealRepository.new(csv_path)
loaded_meals = elements(repo) || []
fail if loaded_meals.empty?
loaded_meals.each do |meal|
expect(meal).to be_a(Meal)
expect(meal.id).to be_a(Integer)
expect(meal.price).to be_a(Integer)
end
end
end
describe "#all" do
it "should return all the meals stored by the repo" do
repo = MealRepository.new(csv_path)
expect(repo.all).to be_a(Array)
expect(repo.all[0].name).to eq("Margherita")
end
it "MealRepository should not expose the @meals through a reader/method" do
repo = MealRepository.new(csv_path)
expect(repo).not_to respond_to(:meals)
end
end
describe "#add" do
it "should add a meal to the in-memory list" do
repo = MealRepository.new(csv_path)
new_meal = Meal.new(price: 12, name: 'Hawaii')
repo.add(new_meal)
expect(repo.all.length).to eq(6)
end
it "should set the new meal id" do
repo = MealRepository.new(csv_path)
hawaii_meal = Meal.new(price: 11, name: 'Hawaii')
repo.add(hawaii_meal)
expect(hawaii_meal.id).to eq(6)
rucola_meal = Meal.new(price: 12, name: 'Rucola')
repo.add(rucola_meal)
expect(rucola_meal.id).to eq(7)
end
it "should start auto-incrementing at 1 if it is the first meal added" do
csv_path = 'unexisting_empty_meals.csv'
FileUtils.remove_file(csv_path, force: true)
repo = MealRepository.new(csv_path)
hawaii_meal = Meal.new(price: 11, name: 'Hawaii')
repo.add(hawaii_meal)
expect(hawaii_meal.id).to eq(1)
FileUtils.remove_file(csv_path, force: true)
end
it "every new added meal should be saved in a row in the CSV (first row = headers)" do
csv_path = 'spec/support/empty_meals.csv'
FileUtils.remove_file(csv_path, force: true)
repo = MealRepository.new(csv_path)
hawaii_meal = Meal.new(price: 11, name: 'Hawaii')
repo.add(hawaii_meal)
repo = MealRepository.new(csv_path)
expect(repo.all.length).to eq(1)
expect(repo.all[0].id).to eq(1)
expect(repo.all[0].name).to eq("Hawaii")
expect(repo.all[0].price).to eq(11)
rucola_meal = Meal.new(price: 12, name: 'Rucola')
repo.add(rucola_meal)
expect(rucola_meal.id).to eq(2)
repo = MealRepository.new(csv_path)
expect(repo.all.length).to eq(2)
expect(repo.all[1].id).to eq(2)
expect(repo.all[1].name).to eq("Rucola")
expect(repo.all[1].price).to eq(12)
FileUtils.remove_file(csv_path, force: true)
end
end
describe "#find" do
it "should retrieve a specific meal based on its id" do
repo = MealRepository.new(csv_path)
meal = repo.find(3)
expect(meal.id).to eq(3)
expect(meal.name).to eq("Napolitana")
end
end
end
require_relative "support/csv_helper"
begin
require_relative "../app/controllers/meals_controller"
require_relative "../app/repositories/meal_repository"
rescue LoadError => e
if e.message =~ /meal_repository/ || e.message =~ /meals_controller/
describe "MealsController" do
it "You need a `meals_controller.rb` file for your `MealsController`" do
fail
end
end
else
raise e
end
end
describe "MealsController", :meal do
let(:meals) do
[
[ "id", "name", "price" ],
[ 1, "Margherita", 8 ],
[ 2, "Capricciosa", 11 ],
[ 3, "Napolitana", 9 ],
[ 4, "Funghi", 12 ],
[ 5, "Calzone", 10 ]
]
end
let(:csv_path) { "spec/support/meals.csv" }
let(:repository) { MealRepository.new(csv_path) }
it "should be initialized with a `MealRepository` instance" do
controller = MealsController.new(repository)
expect(controller).to be_a(MealsController)
end
describe "#list" do
it "should grab meals from the repo and display them" do
controller = MealsController.new(repository)
meals.drop(1).each do |meal_array|
expect(STDOUT).to receive(:puts).with(/#{meal_array[1]}/)
end
controller.list
end
end
describe "#add" do
it "should ask the user for a name and price, then store the new meal" do
controller = MealsController.new(repository)
Object.any_instance.stub(gets: '12')
controller.add
expect(repository.all.length).to eq(6)
expect(repository.all[5].name).to eq("12")
expect(repository.all[5].price).to eq(12)
end
end
end
begin
require_relative "../app/models/customer"
rescue LoadError => e
if e.message =~ /customer/
describe "Customer" do
it "You need a `customer.rb` file for your `Customer` model" do
fail
end
end
else
raise e
end
end
describe "Customer", :customer do
it "should be initialized with a hash of properties" do
properties = { id: 1, name: "Paul McCartney", address: "Liverpool" }
customer = Customer.new(properties)
expect(customer).to be_a(Customer)
end
describe "#id" do
it "should return the customer id" do
customer = Customer.new({ id: 42 })
expect(customer.id).to eq(42)
end
end
describe "#id=" do
it "should set the customer id" do
customer = Customer.new({ id: 42 })
customer.id = 43
expect(customer.id).to eq(43)
end
end
describe "#name" do
it "should return the name of the Customer" do
customer = Customer.new({ name: "Paul McCartney" })
expect(customer.name).to eq("Paul McCartney")
end
end
describe "#address" do
it "should return the address of the Customer" do
customer = Customer.new({ address: "Liverpool" })
expect(customer.address).to eq("Liverpool")
end
end
end
require "fileutils"
require_relative "support/csv_helper"
begin
require_relative "../app/repositories/customer_repository"
rescue LoadError => e
if e.message =~ /customer_repository/
describe "CustomerRepository" do
it "You need a `customer_repository.rb` file for your `CustomerRepository`" do
fail
end
end
else
raise e
end
end
describe "CustomerRepository", :customer do
let(:customers) do
[
[ "id", "name", "address" ],
[ 1, "Paul McCartney", "Liverpool" ],
[ 2, "John Bonham", "Redditch" ],
[ 3, "John Entwistle", "Chiswick" ],
]
end
let(:csv_path) { "spec/support/customers.csv" }
before(:each) do
CsvHelper.write_csv(csv_path, customers)
end
def elements(repo)
repo.instance_variable_get(:@customers) ||
repo.instance_variable_get(:@elements)
end
describe "#initialize" do
it "should take one argument: the CSV file path to store customers" do
expect(CustomerRepository.instance_method(:initialize).arity).to eq(1)
end
it "should not crash if the CSV path does not exist yet. Hint: use File.exist?" do
expect { CustomerRepository.new('unexisting_file.csv') }.not_to raise_error
end
it "should store customers in memory in an instance variable `@customers` or `@elements`" do
repo = CustomerRepository.new(csv_path)
expect(elements(repo)).to be_a(Array)
end
it "should load existing customers from the CSV" do
repo = CustomerRepository.new(csv_path)
loaded_customers = elements(repo) || []
expect(loaded_customers.length).to eq(3)
end
it "should fill the `@customers` with instances of `Customer`, setting the correct types on each property" do
repo = CustomerRepository.new(csv_path)
loaded_customers = elements(repo) || []
fail if loaded_customers.empty?
loaded_customers.each do |customer|
expect(customer).to be_a(Customer)
expect(customer.id).to be_a(Integer)
end
end
end
describe "#all" do
it "should return all the customers stored by the repo" do
repo = CustomerRepository.new(csv_path)
expect(repo.all).to be_a(Array)
expect(repo.all[0].name).to eq("Paul McCartney")
end
it "CustomerRepository should not expose the @customers through a reader/method" do
repo = CustomerRepository.new(csv_path)
expect(repo).not_to respond_to(:customers)
end
end
describe "#add" do
it "should add a customer to the in-memory list" do
repo = CustomerRepository.new(csv_path)
new_customer = Customer.new(address: "Gary", name: 'Michael Jackson')
repo.add(new_customer)
expect(repo.all.length).to eq(4)
end
it "should set the new customer id" do
repo = CustomerRepository.new(csv_path)
hawaii_customer = Customer.new(address: "Gary", name: 'Michael Jackson')
repo.add(hawaii_customer)
expect(hawaii_customer.id).to eq(4)
rucola_customer = Customer.new(address: "Stone Town", name: 'Freddie Mercury')
repo.add(rucola_customer)
expect(rucola_customer.id).to eq(5)
end
it "should start auto-incremting at 1 if it is the first customer added" do
csv_path = 'unexisting_empty_customers.csv'
FileUtils.remove_file(csv_path, force: true)
repo = CustomerRepository.new(csv_path)
hawaii_customer = Customer.new(address: "Gary", name: 'Michael Jackson')
repo.add(hawaii_customer)
expect(hawaii_customer.id).to eq(1)
FileUtils.remove_file(csv_path, force: true)
end
it "should save each new customer in the CSV (first row = headers)" do
csv_path = 'spec/support/empty_customers.csv'
FileUtils.remove_file(csv_path, force: true)
repo = CustomerRepository.new(csv_path)
hawaii_customer = Customer.new(address: "Gary", name: 'Michael Jackson')
repo.add(hawaii_customer)
repo = CustomerRepository.new(csv_path)
expect(repo.all.length).to eq(1)
expect(repo.all[0].id).to eq(1)
expect(repo.all[0].name).to eq("Michael Jackson")
expect(repo.all[0].address).to eq("Gary")
rucola_customer = Customer.new(address: 'Stone Town', name: 'Freddie Mercury')
repo.add(rucola_customer)
expect(rucola_customer.id).to eq(2)
repo = CustomerRepository.new(csv_path)
expect(repo.all.length).to eq(2)
expect(repo.all[1].id).to eq(2)
expect(repo.all[1].name).to eq("Freddie Mercury")
expect(repo.all[1].address).to eq("Stone Town")
FileUtils.remove_file(csv_path, force: true)
end
end
describe "#find" do
it "should retrieve a specific customer based on its id" do
repo = CustomerRepository.new(csv_path)
customer = repo.find(3)
expect(customer.id).to eq(3)
expect(customer.name).to eq("John Entwistle")
end
end
end
require_relative "support/csv_helper"
begin
require_relative "../app/controllers/customers_controller"
require_relative "../app/repositories/customer_repository"
rescue LoadError => e
if e.message =~ /customer_repository/ || e.message =~ /customers_controller/
describe "CustomersController" do
it "You need a `customers_controller.rb` file for your `CustomersController`" do
fail
end
end
else
fail e
end
end
describe "CustomersController", :customer do
let(:customers) do
[
[ "id", "name", "address" ],
[ 1, "Paul McCartney", "Liverpool" ],
[ 2, "John Bonham", "Redditch" ],
[ 3, "John Entwistle", "Chiswick" ],
]
end
let(:csv_path) { "spec/support/customers.csv" }
let(:repository) { CustomerRepository.new(csv_path) }
it "should be initialized with a `CustomerRepository` instance" do
controller = CustomersController.new(repository)
expect(controller).to be_a(CustomersController)
end
describe "#list" do
it "should grab customers from the repo and display them" do
controller = CustomersController.new(repository)
customers.drop(1).each do |customer_array|
expect(STDOUT).to receive(:puts).with(/#{customer_array[1]}/)
end
controller.list
end
end
describe "#add" do
it "should ask the user for a name and address, then store the new customer" do
controller = CustomersController.new(repository)
Object.any_instance.stub(gets: "Le Wagon")
controller.add
expect(repository.all.length).to eq(4)
expect(repository.all[3].name).to eq("Le Wagon")
expect(repository.all[3].address).to eq("Le Wagon")
end
end
end
begin
require_relative "../app/models/employee"
rescue LoadError => e
if e.message =~ /employee/
describe "Employee" do
it "You need a `employee.rb` file for your `Employee` model" do
fail
end
end
else
raise e
end
end
describe "Employee", :employee do
it "should be initialized with a hash of properties" do
properties = { id: 1, username: "paul", password: 'secret', role: 'manager' }
employee = Employee.new(properties)
expect(employee).to be_a(Employee)
end
describe "#id" do
it "should return the employee id" do
employee = Employee.new({ id: 42 })
expect(employee.id).to eq(42)
end
end
describe "#id=" do
it "should set the employee id" do
employee = Employee.new({ id: 42 })
employee.id = 43
expect(employee.id).to eq(43)
end
end
describe "#username" do
it "should return the username of the Employee" do
employee = Employee.new({ username: "paul" })
expect(employee.username).to eq("paul")
end
end
describe "#password" do
it "should return the password of the Employee" do
employee = Employee.new({ password: 'secret' })
expect(employee.password).to eq('secret')
end
end
describe "#role" do
it "should return the role of the Employee" do
employee = Employee.new({ role: 'delivery_guy' })
expect(employee.role).to eq('delivery_guy')
end
end
describe "#manager?" do
it "should return true if the employee is a manager" do
employee = Employee.new({ role: 'manager' })
expect(employee.manager?).to be true
end
it "should return false if the employee is a delivery guy" do
employee = Employee.new({ role: 'delivery_guy' })
expect(employee.manager?).to be false
end
end
describe "#delivery_guy?" do
it "should return true if the employee is a delivery guy" do
employee = Employee.new({ role: 'delivery_guy' })
expect(employee.delivery_guy?).to be true
end
it "should return false if the employee is a manager" do
employee = Employee.new({ role: 'manager' })
expect(employee.delivery_guy?).to be false
end
end
end
require "fileutils"
require_relative "support/csv_helper"
begin
require_relative "../app/repositories/employee_repository"
rescue LoadError => e
if e.message =~ /employee_repository/
describe "EmployeeRepository" do
it "You need a `employee_repository.rb` file for your `EmployeeRepository`" do
fail
end
end
else
raise e
end
end
describe "EmployeeRepository", :employee do
let(:employees) do
[
[ "id", "username", "password", "role" ],
[ 1, "paul", "secret", "manager" ],
[ 2, "john", "secret", "delivery_guy" ]
]
end
let(:csv_path) { "spec/support/employees.csv" }
before(:each) do
CsvHelper.write_csv(csv_path, employees)
end
def elements(repo)
repo.instance_variable_get(:@employees) ||
repo.instance_variable_get(:@elements)
end
describe "#initialize" do
it "should take one argument: the CSV file path to store employees" do
expect(EmployeeRepository.instance_method(:initialize).arity).to eq(1)
end
it "should not crash if the CSV path does not exist yet. Hint: use File.exist?" do
expect { EmployeeRepository.new('unexisting_file.csv') }.not_to raise_error
end
it "should store employees in memory in an instance variable `@employees` or `@elements`" do
repo = EmployeeRepository.new(csv_path)
expect(elements(repo)).to be_a(Array)
end
it "should load existing employees from the CSV" do
repo = EmployeeRepository.new(csv_path)
loaded_employees = elements(repo) || []
expect(loaded_employees.length).to eq(2)
end
it "fills the `@employees` with instance of `Employee`, setting the correct types on each property" do
repo = EmployeeRepository.new(csv_path)
loaded_employees = elements(repo) || []
fail if loaded_employees.empty?
loaded_employees.each do |employee|
expect(employee).to be_a(Employee)
expect(employee.id).to be_a(Integer)
expect(employee.username).not_to be_empty
expect(employee.password).not_to be_empty
expect(employee.role).not_to be_empty
end
end
end
describe "#all_delivery_guys" do
it "should return all the delivery guys stored by the repo" do
repo = EmployeeRepository.new(csv_path)
expect(repo.all_delivery_guys).to be_a(Array)
expect(repo.all_delivery_guys.size).to eq(1)
expect(repo.all_delivery_guys[0].username).to eq("john")
end
it "EmployeeRepository should not expose the @employees through a reader/method" do
repo = EmployeeRepository.new(csv_path)
expect(repo).not_to respond_to(:employees)
end
end
it "EmployeeRepository should not implement an add method (we'll add employees manually to the CSV)" do
repo = EmployeeRepository.new(csv_path)
expect(repo).not_to respond_to(:add)
end
describe "#find" do
it "should retrieve a specific employee based on its id" do
repo = EmployeeRepository.new(csv_path)
employee = repo.find(1)
expect(employee.id).to eq(1)
expect(employee.username).to eq("paul")
end
end
describe "#find_by_username" do
it "should retrieve a specific employee based on its username" do
repo = EmployeeRepository.new(csv_path)
employee = repo.find_by_username("john")
expect(employee).not_to be_nil
expect(employee.id).to eq(2)
expect(employee.username).to eq("john")
end
end
end
# require_relative "support/csv_helper"
# begin
# require_relative "../app/controllers/sessions_controller"
# require_relative "../app/repositories/employee_repository"
# rescue LoadError => e
# if e.message =~ /employee_repository/ || e.message =~ /sessions_controller/
# describe "SessionsController" do
# it "You need a `sessions_controller.rb` file for your `SessionsController`" do
# fail
# end
# end
# else
# fail e
# end
# end
# describe "SessionsController", :session do
# let(:employees) do
# [
# [ "id", "username", "password", "role" ],
# [ 1, "paul", "secret", "manager" ],
# [ 2, "john", "secret", "delivery_guy" ]
# ]
# end
# let(:csv_path) { "spec/support/employees.csv" }
# let(:repository) { EmployeeRepository.new(csv_path) }
# before(:each) do
# CsvHelper.write_csv(csv_path, employees)
# end
# it "should be initialized with a `EmployeeRepository` instance" do
# controller = SessionsController.new(repository)
# expect(controller).to be_a(SessionsController)
# end
# describe "#sign_in" do
# module Kernel; def gets; STDIN.gets; end; end
# it "should ask for a username and a password, find the employee, say hello if the employee exists and password match + return the employee" do
# controller = SessionsController.new(repository)
# expect(STDOUT).to receive(:puts).with(/username/i)
# expect(STDOUT).to receive(:puts).with(/password/i)
# expect(STDOUT).to receive(:puts).with(/welcome/i)
# allow(STDIN).to receive(:gets).and_return("paul", "secret")
# employee = controller.sign_in
# expect(employee).not_to be_nil
# expect(employee.username).to eq("paul")
# end
# it "should ask to try again if the username does not exist (Hint: recursive call of sign_in)" do
# controller = SessionsController.new(repository)
# allow(STDIN).to receive(:gets).and_return("ringo", "secret", "paul", "secret")
# expect(STDOUT).to receive(:puts).with(/username/i).twice
# expect(STDOUT).to receive(:puts).with(/password/i).twice
# expect(STDOUT).to receive(:puts).with(/wrong credentials/i)
# expect(STDOUT).to receive(:puts).with(/welcome/i)
# employee = controller.sign_in
# end
# it "should ask to try again if the username exists but the password does not match" do
# controller = SessionsController.new(repository)
# allow(STDIN).to receive(:gets).and_return("paul", "something_else", "paul", "secret")
# expect(STDOUT).to receive(:puts).with(/username/i).twice
# expect(STDOUT).to receive(:puts).with(/password/i).twice
# expect(STDOUT).to receive(:puts).with(/wrong credentials/i)
# expect(STDOUT).to receive(:puts).with(/welcome/i)
# employee = controller.sign_in
# end
# end
# end
begin
require_relative "../app/models/order"
require_relative "../app/models/meal"
require_relative "../app/models/employee"
require_relative "../app/models/customer"
rescue LoadError => e
describe "Order" do
it "You need a `order.rb` file for your `Order` model" do
fail
end
end
end
describe "Order", :_order do
it "should be initialized with a hash of properties" do
properties = { id: 1, delivered: false }
order = Order.new(properties)
expect(order).to be_a(Order)
end
describe "#id" do
it "should return the order id" do
order = Order.new(id: 42)
expect(order.id).to eq(42)
end
end
describe "#id=" do
it "should set the order id" do
order = Order.new(id: 42)
order.id = 43
expect(order.id).to eq(43)
end
end
describe "#delivered?" do
it "should return true if the order has been delivered" do
order = Order.new(delivered: true)
expect(order.delivered?).to be true
end
it "should return false if the order has not yet been delivered" do
order = Order.new(delivered: false)
expect(order.delivered?).to be false
end
end
describe "#meal" do
it "should return the meal associated with the order" do
order = Order.new(meal: Meal.new({}))
expect(order.meal).to be_a(Meal)
end
end
describe "#employee" do
it "should return the employee associated with the order" do
order = Order.new(employee: Employee.new({}))
expect(order.employee).to be_a(Employee)
end
end
describe "#customer" do
it "should return the customer associated with the order" do
order = Order.new(customer: Customer.new({}))
expect(order.customer).to be_a(Customer)
end
end
describe "#deliver!" do
it "should mark an order as delivered" do
order = Order.new(id: 12)
expect(order.delivered?).to be false
order.deliver!
expect(order.delivered?).to be true
end
end
end
require "fileutils"
require_relative "support/csv_helper"
begin
require_relative "../app/repositories/order_repository"
require_relative "../app/repositories/meal_repository"
require_relative "../app/repositories/employee_repository"
require_relative "../app/repositories/customer_repository"
rescue LoadError => e
describe "OrderRepository" do
it "You need a `order_repository.rb` file for your `OrderRepository`" do
fail
end
end
end
describe "OrderRepository", :_order do
let(:meals) do
[
[ "id", "name", "price" ],
[ 1, "Margherita", 8 ],
[ 2, "Capricciosa", 11 ],
[ 3, "Napolitana", 9 ],
[ 4, "Funghi", 12 ],
[ 5, "Calzone", 10 ]
]
end
let(:meals_csv_path) { "spec/support/meals.csv" }
let(:meal_repository) { MealRepository.new(meals_csv_path) }
let(:employees) do
[
[ "id", "username", "password", "role" ],
[ 1, "paul", "secret", "manager" ],
[ 2, "john", "secret", "delivery_guy" ]
]
end
let(:employees_csv_path) { "spec/support/employees.csv" }
let(:employee_repository) { EmployeeRepository.new(employees_csv_path) }
let(:customers) do
[
[ "id", "name", "address" ],
[ 1, "Paul McCartney", "Liverpool" ],
[ 2, "John Bonham", "Redditch" ],
[ 3, "John Entwistle", "Chiswick" ],
]
end
let(:customers_csv_path) { "spec/support/customers.csv" }
let(:customer_repository) { CustomerRepository.new(customers_csv_path) }
let(:orders) do
[
[ "id", "delivered", "meal_id", "employee_id", "customer_id" ],
[ 1, true, 1, 2, 1 ],
[ 2, false, 1, 2, 2 ],
[ 3, false, 2, 2, 3 ],
]
end
let(:orders_csv_path) { "spec/support/orders.csv" }
let(:order_repository) { OrderRepository.new(orders_csv_path) }
before(:each) do
CsvHelper.write_csv(meals_csv_path, meals)
CsvHelper.write_csv(employees_csv_path, employees)
CsvHelper.write_csv(customers_csv_path, customers)
CsvHelper.write_csv(orders_csv_path, orders)
end
def elements(repo)
repo.instance_variable_get(:@orders) ||
repo.instance_variable_get(:@elements)
end
describe "#initialize" do
it "should take 4 arguments: the CSV file path to store orders, and 3 repository instances (meal, employee and customer)" do
expect(OrderRepository.instance_method(:initialize).arity).to eq(4)
end
it "should not crash if the CSV path does not exist yet. Hint: use File.exist?" do
expect { OrderRepository.new('unexisting_file.csv', meal_repository, employee_repository, customer_repository) }.not_to raise_error
end
it "store the 3 auxiliary repositories in instance variables" do
repo = OrderRepository.new(orders_csv_path, meal_repository, employee_repository, customer_repository)
expect(repo.instance_variable_get(:@meal_repository)).to be_a(MealRepository)
expect(repo.instance_variable_get(:@employee_repository)).to be_a(EmployeeRepository)
expect(repo.instance_variable_get(:@customer_repository)).to be_a(CustomerRepository)
end
it "store orders in memory in an instance variable `@orders` or `@elements`" do
repo = OrderRepository.new(orders_csv_path, meal_repository, employee_repository, customer_repository)
expect(elements(repo)).to be_a(Array)
end
it "should load existing orders from the CSV" do
repo = OrderRepository.new(orders_csv_path, meal_repository, employee_repository, customer_repository)
loaded_orders = elements(repo) || []
expect(loaded_orders.length).to eq(3)
end
it "should fill the `@orders` with instance of `Order`, setting the correct types on each property" do
repo = OrderRepository.new(orders_csv_path, meal_repository, employee_repository, customer_repository)
loaded_orders = elements(repo) || []
fail if loaded_orders.empty?
loaded_orders.each do |order|
expect(order).to be_a(Order)
expect(order.meal).to be_a(Meal)
expect(order.employee).to be_a(Employee)
expect(order.customer).to be_a(Customer)
end
expect(loaded_orders[0].instance_variable_get(:@delivered)).to be true
expect(loaded_orders[1].instance_variable_get(:@delivered)).to be false
expect(loaded_orders[2].instance_variable_get(:@delivered)).to be false
end
end
describe "#undelivered_orders" do
it "should return all the undelivered orders" do
repo = OrderRepository.new(orders_csv_path, meal_repository, employee_repository, customer_repository)
expect(repo.undelivered_orders).to be_a(Array)
expect(repo.undelivered_orders.length).to eq(2)
expect(repo.undelivered_orders[0]).to be_a(Order)
expect(repo.undelivered_orders[1]).to be_a(Order)
expect(repo.undelivered_orders[0].delivered?).to be false
expect(repo.undelivered_orders[1].delivered?).to be false
end
it "OrderRepository should not expose the @orders through a reader/method" do
repo = OrderRepository.new(orders_csv_path, meal_repository, employee_repository, customer_repository)
expect(repo).not_to respond_to(:orders)
end
end
describe "#add" do
it "should add an order to the in-memory list" do
repo = OrderRepository.new(orders_csv_path, meal_repository, employee_repository, customer_repository)
new_order = Order.new({
meal: meal_repository.find(1),
customer: customer_repository.find(1),
employee: employee_repository.find(1)
})
repo.add(new_order)
expect(elements(repo).length).to eq(4)
end
it "should set the new order id" do
repo = OrderRepository.new(orders_csv_path, meal_repository, employee_repository, customer_repository)
new_order = Order.new({
meal: meal_repository.find(1),
customer: customer_repository.find(1),
employee: employee_repository.find(1)
})
repo.add(new_order)
expect(new_order.id).to eq(4)
end
it "should start auto-incrementing at 1 if it is the first order added" do
orders_csv_path = 'unexisting_empty_orders.csv'
FileUtils.remove_file(orders_csv_path, force: true)
repo = OrderRepository.new(orders_csv_path, meal_repository, employee_repository, customer_repository)
new_order = Order.new({
meal: meal_repository.find(1),
customer: customer_repository.find(1),
employee: employee_repository.find(1)
})
repo.add(new_order)
expect(new_order.id).to eq(1)
FileUtils.remove_file(orders_csv_path, force: true)
end
it "should save each new order in the CSV (first row = headers)" do
orders_csv_path = 'spec/support/empty_orders.csv'
FileUtils.remove_file(orders_csv_path, force: true)
repo = OrderRepository.new(orders_csv_path, meal_repository, employee_repository, customer_repository)
new_order = Order.new({
meal: meal_repository.find(1),
customer: customer_repository.find(1),
employee: employee_repository.find(1)
})
repo.add(new_order)
# Reload from the CSV
repo = OrderRepository.new(orders_csv_path, meal_repository, employee_repository, customer_repository)
expect(repo.undelivered_orders.length).to eq(1)
expect(repo.undelivered_orders[0].id).to eq(1)
expect(repo.undelivered_orders[0].meal).to be_a(Meal)
expect(repo.undelivered_orders[0].meal.id).to eq(1)
expect(repo.undelivered_orders[0].employee).to be_a(Employee)
expect(repo.undelivered_orders[0].employee.id).to eq(1)
expect(repo.undelivered_orders[0].customer).to be_a(Customer)
expect(repo.undelivered_orders[0].customer.id).to eq(1)
FileUtils.remove_file(orders_csv_path, force: true)
end
end
end
require_relative "support/csv_helper"
begin
require_relative "../app/controllers/orders_controller"
require_relative "../app/repositories/employee_repository"
rescue LoadError => e
describe "OrdersController" do
it "You need a `orders_controller.rb` file for your `OrdersController`" do
fail
end
end
end
describe "OrdersController", :_order do
let(:meals) do
[
[ "id", "name", "price" ],
[ 1, "Margherita", 8 ],
[ 2, "Capricciosa", 11 ],
[ 3, "Napolitana", 9 ],
[ 4, "Funghi", 12 ],
[ 5, "Calzone", 10 ]
]
end
let(:meals_csv_path) { "spec/support/meals.csv" }
let(:meal_repository) { MealRepository.new(meals_csv_path) }
let(:employees) do
[
[ "id", "username", "password", "role" ],
[ 1, "paul", "secret", "manager" ],
[ 2, "john", "secret", "delivery_guy" ],
[ 3, "ringo", "secret", "delivery_guy"]
]
end
let(:employees_csv_path) { "spec/support/employees.csv" }
let(:employee_repository) { EmployeeRepository.new(employees_csv_path) }
let(:customers) do
[
[ "id", "name", "address" ],
[ 1, "Paul McCartney", "Liverpool" ],
[ 2, "John Bonham", "Redditch" ],
[ 3, "John Entwistle", "Chiswick" ],
]
end
let(:customers_csv_path) { "spec/support/customers.csv" }
let(:customer_repository) { CustomerRepository.new(customers_csv_path) }
let(:orders) do
[
[ "id", "delivered", "meal_id", "employee_id", "customer_id" ],
[ 1, true, 1, 2, 1 ],
[ 2, false, 1, 2, 2 ],
[ 3, false, 2, 2, 3 ],
[ 4, false, 5, 3, 1 ]
]
end
let(:orders_csv_path) { "spec/support/orders.csv" }
let(:order_repository) { OrderRepository.new(orders_csv_path, meal_repository, employee_repository, customer_repository) }
before(:each) do
CsvHelper.write_csv(meals_csv_path, meals)
CsvHelper.write_csv(employees_csv_path, employees)
CsvHelper.write_csv(customers_csv_path, customers)
CsvHelper.write_csv(orders_csv_path, orders)
end
it "should be initialized with 4 repository instances" do
controller = OrdersController.new(meal_repository, employee_repository, customer_repository, order_repository)
expect(controller).to be_a(OrdersController)
end
describe "#list_undelivered_orders" do
it "should list undelivered orders (with meal, employee assigned and customer info)" do
controller = OrdersController.new(meal_repository, employee_repository, customer_repository, order_repository)
orders.drop(2).each do |order|
expect(STDOUT).to receive(:puts).with(/#{customer_repository.find(order[4]).name}/)
end
controller.list_undelivered_orders
end
end
describe "#add" do
it "should ask the user for a meal id, a customer id and an employee id to be assigned" do
controller = OrdersController.new(meal_repository, employee_repository, customer_repository, order_repository)
Object.any_instance.stub(gets: '2')
controller.add
expect(order_repository.undelivered_orders.length).to eq(4)
expect(order_repository.undelivered_orders[3].meal.name).to eq("Capricciosa")
expect(order_repository.undelivered_orders[3].employee.username).to eq("john")
expect(order_repository.undelivered_orders[3].customer.name).to eq("John Bonham")
end
end
describe "#list_my_orders" do
it "should take an Employee instance as a parameter" do
expect(OrdersController.instance_method(:list_my_orders).arity).to eq(1)
end
it "should list Ringo's undelivered orders" do
controller = OrdersController.new(meal_repository, employee_repository, customer_repository, order_repository)
ringo = employee_repository.find(3) # ringo is a delivery guy
expect(STDOUT).to receive(:puts).with(/Paul McCartney.*Calzone/)
controller.list_my_orders(ringo)
end
end
describe "#mark_as_delivered" do
it "should take an Employee instance as a parameter" do
expect(OrdersController.instance_method(:mark_as_delivered).arity).to eq(1)
end
it "should ask the delivery guy for an order id and mark it as delivered" do
controller = OrdersController.new(meal_repository, employee_repository, customer_repository, order_repository)
# Ringo wants to mark as delivered number 4.
Object.any_instance.stub(gets: '4')
ringo = employee_repository.find(3) # ringo is a delivery guy
controller.mark_as_delivered(ringo)
# Reload from CSV
new_order_repository = OrderRepository.new(orders_csv_path, meal_repository, employee_repository, customer_repository)
expect(new_order_repository.undelivered_orders.map(&:id)).not_to include(4)
end
end
end
id name address
1 Paul McCartney Liverpool
2 John Bonham Redditch
3 John Entwistle Chiswick
4 Martin 123 Fake St.
id name price
1 Margherita 8
2 Capricciosa 11
3 Napolitana 9
4 Funghi 12
5 Calzone 10
6 Pizza 10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment