Skip to content

Instantly share code, notes, and snippets.

@patmaddox
Created May 15, 2014 07:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save patmaddox/b90f206696e0affc4403 to your computer and use it in GitHub Desktop.
Save patmaddox/b90f206696e0affc4403 to your computer and use it in GitHub Desktop.
hexarch in rails
# Original Rails controller and action
class EmployeesController < ApplicationController
def create
@employee = Employee.new(employee_params)
if @employee.save
redirect_to @employee, notice: "Employee #{@employee.name} created"
else
render :new
end
end
end
describe 'persistence_adapter', shared: true do
describe '.new(options)' do
it 'returns a saveable object' do
expect(described_type.new({})).to respond_to(:save)
end
end
describe '#save' do
it 'sets the id' do
described_type.new({}).tap do |s|
expect(s.id).to be_nil
s.save
expect(s.id).to_not be_nil
end
end
end
describe '#name' do
it 'returns the name passed to initialize' do
expect(described_type.new(name: 'Pat').name).to eq('Pat')
end
end
end
describe 'view_adapter', shared: true do
describe '#redirect_to(employee, options)' do
let(:employee) { double('employee', id: 123, name: 'Pat Maddox') }
it 'accepts an employee with a notice: option' do
subject.redirect_to employee, notice: "yer on notice"
end
end
describe '#render(page)' do
it 'accepts :new' do
subject.render :new
end
end
describe '#employee_params' do
it 'returns a hash with :name' do
expect(subject.employee_params[:name]).to be_present
end
end
end
class PersistableInMemory
attr_reader :id, :name
def initialize(attributes)
@name = attributes[:name]
end
def save
@id = [Time.now, rand(1_000_000_000_000)].join
end
end
class TerminalAdapter
def redirect_to(employee, options)
puts "[LOG] redirecting to #{employee}"
puts options[:notice]
end
def render(page)
puts "Press return to create a new employee" if page == :new
end
def employee_params
print "Name? "
{ name: gets.chomp }
end
end
ApplicationController = TerminalAdapter
Employee = PersistableInMemory
class PersistableInMemory
attr_reader :id, :name
def initialize(attributes)
@name = attributes[:name]
end
def save
@id = [Time.now, rand(1_000_000_000_000)].join
end
end
class TerminalAdapter
def redirect_to(employee, options)
puts "[LOG] redirecting to #{employee}"
puts options[:notice]
end
def render(page)
puts "Press return to create a new employee" if page == :new
end
def employee_params
print "Name? "
{ name: gets.chomp }
end
end
ApplicationController = TerminalAdapter
Employee = PersistableInMemory
# Original Rails controller and action
class EmployeesController < ApplicationController
def create
@employee = Employee.new(employee_params)
if @employee.save
redirect_to @employee, notice: "Employee #{@employee.name} created"
else
render :new
end
end
end
app = EmployeesController.new
app.create
app
# Original Rails controller and action with dependencies inverted
class EmployeesController
def initialize(io, db)
@io, @db = io, db
end
def create
@employee = @db.new(@io.employee_params)
if @employee.save
@io.redirect_to @employee, notice: "Employee #{@employee.name} created"
else
@io.render :new
end
end
end
class PersistableInMemory
attr_reader :name
def initialize(attributes)
@name = attributes[:name]
end
def save
@id = [Time.now, rand(1_000_000_000_000)].join
end
end
class TerminalAdapter
def redirect_to(employee, options)
puts "[LOG] redirecting to #{employee}"
puts options[:notice]
end
def render(page)
puts "Press return to create a new employee" if page == :new
end
def employee_params
print "Name? "
{ name: gets.chomp }
end
end
app = EmployeesController.new TerminalAdapter.new, PersistableInMemory
app.create
app
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment