Skip to content

Instantly share code, notes, and snippets.

@calavera
Created January 21, 2011 22:41
Show Gist options
  • Save calavera/790579 to your computer and use it in GitHub Desktop.
Save calavera/790579 to your computer and use it in GitHub Desktop.
Kata de api fluida
class User
attr_reader :name, :age
def initialize(name, age)
@name, @age = name, age
end
end
class Filter
attr_reader :method, :value
def initialize(method, value)
@method, @value = method, value
end
end
class Select
instance_methods.each do |method|
undef_method method unless method.to_s =~ /(^__|^send|^object_id)/
end
def self.[](query)
Select.new(query)
end
def initialize(query)
@query = query
end
def from(list)
@from = list
self
end
def where(where)
@where = where
self
end
def is(filter)
@filter = Filter.new('==', filter)
self
end
def is_greater_than(filter)
@filter = Filter.new('>', filter)
self
end
def is_lower_than(filter)
@filter = Filter.new('<', filter)
self
end
def method_missing(method_name, *args)
result = execute
result.send(method_name, *args)
end
private
def execute
return nil if @from.nil? || @from.empty?
@from = @from.select do |e|
e.send(@where).send(@filter.method, @filter.value)
end if @where && @filter
@from.map {|e| e.send(@query) }
end
end
describe Select do
it "return nil when the list is empty" do
Select['name'].should be_nil
end
it "return the name from an element from the list" do
Select["name"].from([User.new("foo", 23)]).should == ["foo"]
end
it "return the age from an element from the list" do
Select['age'].from([User.new('foo', 23)]).should == [23]
end
it "returns the different names for all the elements in the list" do
users = [User.new('foo', 23),
User.new('bar', 34)]
Select["name"].from(users).should == ['foo', 'bar']
end
it "filters the results by the where expression" do
users = [User.new('foo', 23),
User.new('bar', 34)]
Select['name'].from(users).where("age").is(23).should == ['foo']
end
it "filters the results greater than an age" do
users = [User.new('foo', 23),
User.new('bar', 34)]
Select['name'].from(users).where('age').is_greater_than(23).should == ['bar']
end
it "filters the results lower than an age" do
users = [User.new('foo', 23),
User.new('bar', 34)]
Select['name'].from(users).where('age').is_lower_than(24).should == ['foo']
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment