-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Revamp aliases implementation (#389)
- Loading branch information
1 parent
c67f573
commit 48ee843
Showing
17 changed files
with
534 additions
and
356 deletions.
There are no files selected for viewing
44 changes: 0 additions & 44 deletions
44
src/components/dependency_injection/spec/compiler_passes/calls_spec.cr
This file was deleted.
Oops, something went wrong.
88 changes: 88 additions & 0 deletions
88
src/components/dependency_injection/spec/compiler_passes/define_getters_spec.cr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
require "../spec_helper" | ||
|
||
private def assert_success(code : String, *, line : Int32 = __LINE__) : Nil | ||
ASPEC::Methods.assert_success <<-CR, codegen: true, line: line | ||
require "../spec_helper.cr" | ||
#{code} | ||
ADI::ServiceContainer.new | ||
CR | ||
end | ||
|
||
private def assert_error(message : String, code : String, *, line : Int32 = __LINE__) : Nil | ||
ASPEC::Methods.assert_error message, <<-CR, line: line | ||
require "../spec_helper.cr" | ||
#{code} | ||
CR | ||
end | ||
|
||
private def assert_success(code : String, *, line : Int32 = __LINE__) : Nil | ||
ASPEC::Methods.assert_success <<-CR, codegen: true, line: line | ||
require "../spec_helper.cr" | ||
#{code} | ||
ADI::ServiceContainer.new | ||
CR | ||
end | ||
|
||
describe ADI::ServiceContainer::DefineGetters, tags: "compiled" do | ||
describe "compiler errors" do | ||
describe "aliases" do | ||
it "does not expose named getter for non-public string aliases" do | ||
assert_error "undefined method 'bar' for Athena::DependencyInjection::ServiceContainer", <<-CR | ||
module SomeInterface; end | ||
@[ADI::Register] | ||
@[ADI::AsAlias("bar")] | ||
class Foo | ||
include SomeInterface | ||
end | ||
ADI.container.bar | ||
CR | ||
end | ||
|
||
it "does not expose typed getter for non-public typed aliases" do | ||
assert_error "undefined method 'get' for Athena::DependencyInjection::ServiceContainer", <<-CR | ||
module SomeInterface; end | ||
@[ADI::Register] | ||
@[ADI::AsAlias] | ||
class Foo | ||
include SomeInterface | ||
end | ||
ADI.container.get SomeInterface | ||
CR | ||
end | ||
end | ||
end | ||
|
||
describe "aliases" do | ||
it "exposes named getter for public string alias" do | ||
assert_success <<-CR | ||
module SomeInterface; end | ||
@[ADI::Register] | ||
@[ADI::AsAlias("bar", public: true)] | ||
class Foo | ||
include SomeInterface | ||
end | ||
ADI.container.bar.should be_a Foo | ||
CR | ||
end | ||
|
||
it "exposes typed getter for public typed alias" do | ||
assert_success <<-CR | ||
module SomeInterface; end | ||
@[ADI::Register] | ||
@[ADI::AsAlias(public: true)] | ||
class Foo | ||
include SomeInterface | ||
end | ||
ADI.container.get(SomeInterface).should be_a Foo | ||
CR | ||
end | ||
end | ||
end |
115 changes: 0 additions & 115 deletions
115
src/components/dependency_injection/spec/compiler_passes/factory_spec.cr
This file was deleted.
Oops, something went wrong.
136 changes: 136 additions & 0 deletions
136
src/components/dependency_injection/spec/compiler_passes/process_aliases_spec.cr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
require "../spec_helper" | ||
|
||
private def assert_success(code : String, *, line : Int32 = __LINE__) : Nil | ||
ASPEC::Methods.assert_success <<-CR, codegen: true, line: line | ||
require "../spec_helper.cr" | ||
#{code} | ||
ADI::ServiceContainer.new | ||
CR | ||
end | ||
|
||
private def assert_error(message : String, code : String, *, line : Int32 = __LINE__) : Nil | ||
ASPEC::Methods.assert_error message, <<-CR, line: line | ||
require "../spec_helper.cr" | ||
#{code} | ||
ADI::ServiceContainer.new | ||
CR | ||
end | ||
|
||
describe ADI::ServiceContainer::ProcessAliases, tags: "compiled" do | ||
it "errors if unable to determine the alias name" do | ||
assert_error "Alias cannot be automatically determined for 'foo' (Foo). If the type includes multiple interfaces, provide the interface to alias as the first positional argument to `@[ADI::AsAlias]`.", <<-CR | ||
module SomeInterface; end | ||
module OtherInterface; end | ||
@[ADI::Register] | ||
@[ADI::AsAlias] | ||
class Foo | ||
include SomeInterface | ||
include OtherInterface | ||
end | ||
macro finished | ||
macro finished | ||
it { \\{{ADI::ServiceContainer::ALIASES.keys}}.should eq [SomeInterface] } | ||
it { \\{{ADI::ServiceContainer::ALIASES[SomeInterface]["id"].stringify}}.should eq %("foo") } | ||
it { \\{{ADI::ServiceContainer::ALIASES[SomeInterface]["public"]}}.should be_false } | ||
end | ||
end | ||
CR | ||
end | ||
|
||
it "allows explicit string alias name" do | ||
assert_success <<-CR | ||
@[ADI::Register] | ||
@[ADI::AsAlias("bar")] | ||
class Foo; end | ||
macro finished | ||
macro finished | ||
it { \\{{ADI::ServiceContainer::ALIASES.keys}}.should eq ["bar"] } | ||
it { \\{{ADI::ServiceContainer::ALIASES["bar"]["id"].stringify}}.should eq %("foo") } | ||
it { \\{{ADI::ServiceContainer::ALIASES["bar"]["public"]}}.should be_false } | ||
end | ||
end | ||
CR | ||
end | ||
|
||
it "allows explicit const alias name" do | ||
assert_success <<-CR | ||
BAR = "bar" | ||
@[ADI::Register] | ||
@[ADI::AsAlias(BAR)] | ||
class Foo; end | ||
macro finished | ||
macro finished | ||
it { \\{{ADI::ServiceContainer::ALIASES.keys}}.should eq ["bar"] } | ||
it { \\{{ADI::ServiceContainer::ALIASES["bar"]["id"].stringify}}.should eq %("foo") } | ||
it { \\{{ADI::ServiceContainer::ALIASES["bar"]["public"]}}.should be_false } | ||
end | ||
end | ||
CR | ||
end | ||
|
||
it "allows explicit TypeNode alias name" do | ||
assert_success <<-CR | ||
module SomeInterface; end | ||
@[ADI::Register] | ||
@[ADI::AsAlias(SomeInterface, public: true)] | ||
class Foo | ||
include SomeInterface | ||
end | ||
macro finished | ||
macro finished | ||
it { \\{{ADI::ServiceContainer::ALIASES.keys}}.should eq [SomeInterface] } | ||
it { \\{{ADI::ServiceContainer::ALIASES[SomeInterface]["id"].stringify}}.should eq %("foo") } | ||
it { \\{{ADI::ServiceContainer::ALIASES[SomeInterface]["public"]}}.should be_true } | ||
end | ||
end | ||
CR | ||
end | ||
|
||
it "uses included interface type as alias name if there is only 1" do | ||
assert_success <<-CR | ||
module SomeInterface; end | ||
@[ADI::Register] | ||
@[ADI::AsAlias] | ||
class Foo | ||
include SomeInterface | ||
end | ||
macro finished | ||
macro finished | ||
it { \\{{ADI::ServiceContainer::ALIASES.keys}}.should eq [SomeInterface] } | ||
it { \\{{ADI::ServiceContainer::ALIASES[SomeInterface]["id"].stringify}}.should eq %("foo") } | ||
it { \\{{ADI::ServiceContainer::ALIASES[SomeInterface]["public"]}}.should be_false } | ||
end | ||
end | ||
CR | ||
end | ||
|
||
it "allows aliasing more than one interface" do | ||
assert_success <<-CR | ||
module SomeInterface; end | ||
module OtherInterface; end | ||
@[ADI::Register] | ||
@[ADI::AsAlias(SomeInterface)] | ||
@[ADI::AsAlias(OtherInterface)] | ||
class Foo | ||
include SomeInterface | ||
include OtherInterface | ||
end | ||
macro finished | ||
macro finished | ||
it { \\{{ADI::ServiceContainer::ALIASES.keys}}.should eq [SomeInterface, OtherInterface] } | ||
end | ||
end | ||
CR | ||
end | ||
end |
Oops, something went wrong.