test/example_proxy_test.rb
require "test_helper"
class ProxyContext
extend Surrounded::Context
initialize(:admin, :task)
interface :admin do
def some_admin_method
"hello from #{name}, the admin interface!"
end
def talking_to_others
task.name
end
def combined_methods
some_admin_method
end
end
wrap :task do
end
trigger :do_something do
admin.some_admin_method
end
trigger :talking do
admin.talking_to_others
end
trigger :admin_name do
admin.name
end
trigger :admin_missing_method do
admin.method_that_does_not_exist
end
trigger :admin_responds? do
admin.respond_to?(:talking_to_others)
end
trigger :get_admin_method do
admin.method(:talking_to_others)
end
trigger :combined_interface_methods do
admin.combined_methods
end
end
ProxyUser = Class.new do
def initialize(name)
@name = name
end
attr_reader :name
end
describe ProxyContext do
let(:user) {
ProxyUser.new("Jim")
}
let(:task) {
OpenStruct.new(name: "GTD")
}
let(:context) {
ProxyContext.new(admin: user, task: task)
}
it "proxys methods between objects and its interface" do
assert_equal "hello from Jim, the admin interface!", context.do_something
end
it "forwards methods that the object responds to" do
assert_equal "Jim", context.admin_name
end
it "passes missing methods up the ancestry of the object" do
err = _ { context.admin_missing_method }.must_raise(NoMethodError)
assert_match(/ProxyUser.*name="Jim"/, err.message)
end
it "fails access to other objects in the context" do
err = _ { context.talking }.must_raise NameError
assert_match(%r{undefined local variable or method `task'}, err.message)
end
it "sets roles to respond to role methods" do
assert context.admin_responds?
end
# A Negotiator object merely applies methods to another object
# so that once the method is called, the object has no knowledge
# of the module from which the method was applied.
it "does not find other interface methods" do
assert_raises(NameError) {
context.combined_interface_methods
}
end
it "is able to grab methods from the object" do
assert_equal :talking_to_others, context.get_admin_method.name
end
it "allows Surrounded objects to interact with others" do
assert context.rebind(admin: User.new("Surrounded"), task: task).talking
end
it "works with frozen and primitive objects" do
context.rebind(admin: "brrr".freeze, task: task)
assert context.get_admin_method
context.rebind(admin: nil, task: task)
assert context.get_admin_method
context.rebind(admin: true, task: task)
assert context.get_admin_method
end
end