require 'spec_helper' module Test module Hunter class Beast; end class Bear < Beast; end class Lion < Beast; end class Grizly < Bear; end class Argumented def initialize( arg ) @arg = arg end attr_reader :arg end class Implicit; end class Zoo include Scorpion::Object depend_on do bear Bear end end class City; end class Park include Scorpion::Object depend_on do city City end initialize( zoo: Test::Hunter::Zoo ) end class City include Scorpion::Object depend_on do park Park end initialize( zoo: Test::Hunter::Zoo ) end class Singleton end end end describe Scorpion::Hunter do let( :hunter ) do Scorpion::Hunter.new do capture Test::Hunter::Lion, :tame hunt_for Test::Hunter::Bear hunt_for Test::Hunter::Lion, :male hunt_for Test::Hunter::Grizly, :female hunt_for Test::Hunter::Argumented hunt_for Test::Hunter::Zoo share do capture Test::Hunter::Singleton end end end it "spawns dependency" do expect( hunter.fetch Test::Hunter::Beast ).to be_a Test::Hunter::Beast end it "spawns a new instance for multiple requests" do first = hunter.fetch Test::Hunter::Beast expect( hunter.fetch Test::Hunter::Beast ).not_to be first end it "spawns the same instance for captured dependency" do first = hunter.fetch_by_traits Test::Hunter::Beast, :tame expect( hunter.fetch_by_traits Test::Hunter::Beast, :tame ).to be first end it "injects nested objects" do zoo = hunter.fetch Test::Hunter::Zoo expect( zoo.bear ).to be_a Test::Hunter::Bear end it "accepts arguments that are passed to constructor" do obj = hunter.fetch Test::Hunter::Argumented, :awesome expect( obj.arg ).to eq :awesome end it "implicitly spawns Class contracts" do expect( hunter.fetch Test::Hunter::Implicit ).to be_a Test::Hunter::Implicit end it "implicitly spawns Class contracts with empty traits" do expect( hunter.fetch_by_traits Test::Hunter::Implicit, [] ).to be_a Test::Hunter::Implicit end it "initialize explicit contracts" do zoo = hunter.new Test::Hunter::Zoo expect( zoo ).to be_a Test::Hunter::Zoo expect( zoo.scorpion ).to eq hunter end it "delegates hunting definitions" do hunter.hunt_for Test::Hunter::Zoo, return: :nyc expect( hunter.fetch Test::Hunter::Zoo ).to eq :nyc end context "child dependencies" do it "passes initializer args to child dependencies" do zoo = Test::Hunter::Zoo.new city = hunter.fetch Test::Hunter::City, zoo: zoo expect( city.park.zoo ).to be zoo end it "passes self to child dependencies" do zoo = Test::Hunter::Zoo.new city = hunter.fetch Test::Hunter::City, zoo: zoo expect( city.park.city ).to be city end end describe "#find_dependency" do def build_hunt( hunter ) Scorpion::Hunt.new hunter, Test::Hunter::Singleton, [] end it "finds a dependency" do expect( hunter.find_dependency( build_hunt( hunter ) ) ).to be_a Scorpion::Dependency end it "finds a parent dependency" do expect( hunter.find_dependency( build_hunt( hunter.replicate ) ) ).to be_a Scorpion::Dependency end it "finds grandparent dependency" do expect( hunter.find_dependency( build_hunt( hunter.replicate.replicate ) ) ).to be_a Scorpion::Dependency end end describe "#inspect" do it "is helpful" do expect( hunter.inspect ).to match /contracts/ expect( hunter.inspect ).not_to match /0x/ end end end