saturnflyer/surrounded

View on GitHub
test/example_proxy_test.rb

Summary

Maintainability
A
0 mins
Test Coverage
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