diff --git a/lib/koans/16_protocols.ex b/lib/koans/16_protocols.ex new file mode 100644 index 0000000..b8d5b4d --- /dev/null +++ b/lib/koans/16_protocols.ex @@ -0,0 +1,51 @@ +defmodule Protocols do + use Koans + + @intro "Wan't to follow the rules? Adhere to the protocol!" + + defprotocol School, do: def enrol(person) + + defimpl School, for: Any do + def enrol(_) do + "Pupil enrolled at school" + end + end + + defmodule Student do + @derive School + defstruct name: "" + end + + defmodule Musician, do: defstruct name: "", instrument: "" + defmodule Dancer, do: defstruct name: "", dance_style: "" + defmodule Baker, do: defstruct name: "" + + defimpl School, for: Musician do + def enrol(musician) do + "#{musician.name} signed up for #{musician.instrument}" + end + end + + defimpl School, for: Dancer do + def enrol(dancer), do: "#{dancer.name} enrolled for #{dancer.dance_style}" + end + + koan "Sharing an interface is the secret at school" do + musician = %Musician{name: "Andre", instrument: "violin"} + dancer = %Dancer{name: "Darcy", dance_style: "ballet"} + + assert School.enrol(musician) == ___ + assert School.enrol(dancer) == ___ + end + + koan "Sometimes we all use the same" do + student = %Student{name: "Emily"} + assert School.enrol(student) == ___ + end + + koan "If you don't comply you can't get in" do + assert_raise ___, fn -> + School.enrol(%Baker{name: "Delia"}) + end + end +end diff --git a/lib/runner.ex b/lib/runner.ex index 046ed9e..870ed25 100644 --- a/lib/runner.ex +++ b/lib/runner.ex @@ -16,6 +16,7 @@ defmodule Runner do Processes, Tasks, Agents, + Protocols, ] def koan?(koan), do: Enum.member?(@modules, koan) diff --git a/mix.lock b/mix.lock index e28c9aa..0a97bce 100644 --- a/mix.lock +++ b/mix.lock @@ -1,2 +1,2 @@ -%{"exfswatch": {:hex, :exfswatch, "0.1.1"}, - "fs": {:hex, :fs, "0.9.2"}} +%{"exfswatch": {:hex, :exfswatch, "0.1.1", "7ccf6fc9b443d04dada3e50b21f910b4d0e4546ce7772dc6d4181fb929ea186f", [:mix], [{:fs, "~> 0.9", [hex: :fs, optional: false]}]}, + "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], []}} diff --git a/test/koans/protocols_koans_test.exs b/test/koans/protocols_koans_test.exs new file mode 100644 index 0000000..88dcbb7 --- /dev/null +++ b/test/koans/protocols_koans_test.exs @@ -0,0 +1,14 @@ +defmodule ProtocolsTests do + use ExUnit.Case + import TestHarness + + test "Protocols" do + answers = [ + {:multiple, ["Andre signed up for violin", "Darcy enrolled for ballet"]}, + "Pupil enrolled at school", + Protocol.UndefinedError + ] + + test_all(Protocols, answers) + end +end