Use triple underscore instead of double

This commit is contained in:
Uku Taht
2016-04-20 11:23:44 +01:00
parent ea2bb8f9bf
commit ded0f11ec6
16 changed files with 148 additions and 161 deletions

View File

@@ -51,19 +51,6 @@ defmodule BlankAssertions do
end end
defp contains_blank?(expr) do defp contains_blank?(expr) do
{_, blank} = Macro.prewalk(expr, false, &blank?/2) Blanks.count(expr) > 0
blank
end
defp blank?(node, true) do
{node, true}
end
defp blank?({expr, _, _} = node, _acc) do
{node, expr == :__}
end
defp blank?(expr, _acc) do
{expr, expr == :__}
end end
end end

View File

@@ -7,8 +7,8 @@ defmodule Blanks do
|> elem(0) |> elem(0)
end end
defp pre(:__, [first | remainder]), do: {first, remainder} defp pre(:___, [first | remainder]), do: {first, remainder}
defp pre({:__, _, _}, [first | remainder]), do: {first, remainder} defp pre({:___, _, _}, [first | remainder]), do: {first, remainder}
defp pre(node, acc), do: {node, acc} defp pre(node, acc), do: {node, acc}
def count(ast) do def count(ast) do
@@ -17,7 +17,7 @@ defmodule Blanks do
|> elem(1) |> elem(1)
end end
defp count(:__, acc), do: {node, acc+1} defp count(:___, acc), do: {node, acc+1}
defp count({:__, _, _}, acc), do: {node, acc+1} defp count({:___, _, _}, acc), do: {node, acc+1}
defp count(node, acc), do: {node, acc} defp count(node, acc), do: {node, acc}
end end

View File

@@ -2,30 +2,30 @@ defmodule Equalities do
use Koans use Koans
koan "We shall contemplate truth by testing reality, via equality" do koan "We shall contemplate truth by testing reality, via equality" do
assert true == __ assert true == ___
end end
koan "Not something is the opposite of it" do koan "Not something is the opposite of it" do
assert !true == __ assert !true == ___
end end
koan "To understand reality, we must compare our expectations against reality" do koan "To understand reality, we must compare our expectations against reality" do
assert 2 == 1 + __ assert 2 == 1 + ___
end end
koan "Some things may appear different, but be the same" do koan "Some things may appear different, but be the same" do
assert 1 == 2 / __ assert 1 == 2 / ___
end end
koan "Unless they actually are different" do koan "Unless they actually are different" do
assert 3.2 != __ assert 3.2 != ___
end end
koan "Some may be looking for bigger things" do koan "Some may be looking for bigger things" do
assert __ > 3 assert ___ > 3
end end
koan "Others are happy with less" do koan "Others are happy with less" do
assert __ < 3 assert ___ < 3
end end
end end

View File

@@ -2,38 +2,38 @@ defmodule Strings do
use Koans use Koans
koan "Strings are there to represent text" do koan "Strings are there to represent text" do
assert "hello" == __ assert "hello" == ___
end end
koan "They can be put together" do koan "They can be put together" do
assert "hello world" == __ <> "world" assert "hello world" == ___ <> "world"
end end
koan "Or pulled apart when needed" do koan "Or pulled apart when needed" do
assert __ == String.split("hello world") assert ___ == String.split("hello world")
end end
koan "Be careful, a message may be altered" do koan "Be careful, a message may be altered" do
assert __ == String.replace("An awful day", "awful", "incredible") assert ___ == String.replace("An awful day", "awful", "incredible")
end end
koan "But strings never lie about themselves" do koan "But strings never lie about themselves" do
assert true == String.contains?("An incredible day", __) assert true == String.contains?("An incredible day", ___)
end end
koan "Sometimes you want just the opposite of what is given" do koan "Sometimes you want just the opposite of what is given" do
assert __ == String.reverse("ananab") assert ___ == String.reverse("ananab")
end end
koan "Other times a little cleaning is in order" do koan "Other times a little cleaning is in order" do
assert __ == String.strip(" \n banana\n ") assert ___ == String.strip(" \n banana\n ")
end end
koan "Repetition is the mother of learning" do koan "Repetition is the mother of learning" do
assert "StringStringString" == String.duplicate(__, 3) assert "StringStringString" == String.duplicate(___, 3)
end end
koan "Strings can be louder when necessary" do koan "Strings can be louder when necessary" do
assert "LISTEN" == String.upcase(__) assert "LISTEN" == String.upcase(___)
end end
end end

View File

@@ -2,34 +2,34 @@ defmodule Tuples do
use Koans use Koans
koan "Tuples have a size" do koan "Tuples have a size" do
assert tuple_size({:a, :b, :c}) == __ assert tuple_size({:a, :b, :c}) == ___
end end
koan "Tuples can contain different things" do koan "Tuples can contain different things" do
assert {:a, 1, "hi"} == __ assert {:a, 1, "hi"} == ___
end end
koan "You can pull out individual elements" do koan "You can pull out individual elements" do
assert elem({:a, "hi"}, 1) == __ assert elem({:a, "hi"}, 1) == ___
end end
koan "You can change individual elements of a tuple" do koan "You can change individual elements of a tuple" do
assert put_elem({:a, "hi"}, 1, "bye") == __ assert put_elem({:a, "hi"}, 1, "bye") == ___
end end
koan "You can also simply extend a tuple with new stuff" do koan "You can also simply extend a tuple with new stuff" do
assert Tuple.insert_at({:a, "hi"}, 1, :new_thing) == __ assert Tuple.insert_at({:a, "hi"}, 1, :new_thing) == ___
end end
koan "Add things at the end" do koan "Add things at the end" do
assert Tuple.append({"Huey", "Dewey"}, "Louie") == __ assert Tuple.append({"Huey", "Dewey"}, "Louie") == ___
end end
koan "Or remove them" do koan "Or remove them" do
assert Tuple.delete_at({:this, :is, :not, :awesome}, 2) == __ assert Tuple.delete_at({:this, :is, :not, :awesome}, 2) == ___
end end
koan "Turn it into a list in case you need it" do koan "Turn it into a list in case you need it" do
assert Tuple.to_list({:this, :can, :be, :a, :list}) == __ assert Tuple.to_list({:this, :can, :be, :a, :list}) == ___
end end
end end

View File

@@ -2,70 +2,70 @@ defmodule Lists do
use Koans use Koans
koan "We can see what is ahead" do koan "We can see what is ahead" do
assert List.first([1, 2, 3]) == __ assert List.first([1, 2, 3]) == ___
end end
koan "Checking what's trailing is also simple" do koan "Checking what's trailing is also simple" do
assert List.last([1, 2, 3]) == __ assert List.last([1, 2, 3]) == ___
end end
koan "Lists can store anything you throw at them" do koan "Lists can store anything you throw at them" do
assert [1, 2] ++ [:a, "b"] == __ assert [1, 2] ++ [:a, "b"] == ___
end end
koan "Things can evolve" do koan "Things can evolve" do
assert [1, 2, 3] -- [3] == __ assert [1, 2, 3] -- [3] == ___
end end
koan "Evolution can have different forms" do koan "Evolution can have different forms" do
assert List.delete([1, 2, 2, 3], 2) == __ assert List.delete([1, 2, 2, 3], 2) == ___
end end
koan "Precision is also valued" do koan "Precision is also valued" do
assert List.delete_at([1, 2, 3], 1) == __ assert List.delete_at([1, 2, 3], 1) == ___
end end
koan "Replication is also possible" do koan "Replication is also possible" do
assert List.duplicate("life", 3) == __ assert List.duplicate("life", 3) == ___
end end
koan "Sometimes levelling the playing field is desired" do koan "Sometimes levelling the playing field is desired" do
assert List.flatten([1, [2, 3], 4, [5]]) == __ assert List.flatten([1, [2, 3], 4, [5]]) == ___
end end
koan "Same rules apply to new members that arrive late" do koan "Same rules apply to new members that arrive late" do
assert List.flatten([1, [2, 3]], [4]) == __ assert List.flatten([1, [2, 3]], [4]) == ___
end end
koan "Order can also be specified for new members" do koan "Order can also be specified for new members" do
assert List.insert_at([1, 2, 3], 1, 4) == __ assert List.insert_at([1, 2, 3], 1, 4) == ___
end end
koan "We can replace things at specified positions" do koan "We can replace things at specified positions" do
assert List.replace_at([1, 2, 3], 0, 10) == __ assert List.replace_at([1, 2, 3], 0, 10) == ___
end end
koan "Replacing something which is not" do koan "Replacing something which is not" do
assert List.replace_at([1, 2, 3], 10, 0) == __ assert List.replace_at([1, 2, 3], 10, 0) == ___
end end
koan "Order is bound by nature's laws" do koan "Order is bound by nature's laws" do
assert List.insert_at([1, 2, 3], 10, 4) == __ assert List.insert_at([1, 2, 3], 10, 4) == ___
end end
koan "Sometimes its faster to loop around back" do koan "Sometimes its faster to loop around back" do
assert List.insert_at([1, 2, 3], -1, 4) == __ assert List.insert_at([1, 2, 3], -1, 4) == ___
end end
koan "We can also transform ourselves completely" do koan "We can also transform ourselves completely" do
assert List.to_tuple([1, 2, 3]) == __ assert List.to_tuple([1, 2, 3]) == ___
end end
koan "Wrapping other values is a handy option" do koan "Wrapping other values is a handy option" do
assert List.wrap("value") == :__ assert List.wrap("value") == :___
end end
koan "Zipping can be a useful operation" do koan "Zipping can be a useful operation" do
assert List.zip([[1, 2], [3, 4], [5, 6]]) == :__ assert List.zip([[1, 2], [3, 4], [5, 6]]) == :___
end end
end end

View File

@@ -8,55 +8,55 @@ defmodule Maps do
} }
koan "Maps represent structured data, like a person" do koan "Maps represent structured data, like a person" do
assert @person == %{name: __, assert @person == %{name: ___,
last_name: "Snow", last_name: "Snow",
age: 27 } age: 27 }
end end
koan "A map has keys and values" do koan "A map has keys and values" do
assert Map.keys(@person) |> Enum.sort == __ assert Map.keys(@person) |> Enum.sort == ___
assert Map.values(@person) |> Enum.sort == __ assert Map.values(@person) |> Enum.sort == ___
end end
koan "Fetching a value returns a tuple with ok when it exists" do koan "Fetching a value returns a tuple with ok when it exists" do
assert Map.fetch(@person, :age) == __ assert Map.fetch(@person, :age) == ___
end end
koan "Or the atom :error when it doesnt" do koan "Or the atom :error when it doesnt" do
assert Map.fetch(@person, :family) == __ assert Map.fetch(@person, :family) == ___
end end
koan "Extending a map is a simple as putting in a new pair" do koan "Extending a map is a simple as putting in a new pair" do
person_with_hobby = Map.put(@person, :hobby, "Kayaking") person_with_hobby = Map.put(@person, :hobby, "Kayaking")
assert Map.fetch(person_with_hobby, :hobby) == __ assert Map.fetch(person_with_hobby, :hobby) == ___
end end
koan "Put can also overwrite existing values" do koan "Put can also overwrite existing values" do
older_person = Map.put(@person, :age, 37) older_person = Map.put(@person, :age, 37)
assert Map.fetch(older_person, :age) == __ assert Map.fetch(older_person, :age) == ___
end end
koan "Or you can use some syntactic sugar for existing elements" do koan "Or you can use some syntactic sugar for existing elements" do
younger_person = %{ @person | age: 16 } younger_person = %{ @person | age: 16 }
assert Map.fetch(younger_person, :age) == __ assert Map.fetch(younger_person, :age) == ___
end end
koan "Can remove pairs by key" do koan "Can remove pairs by key" do
without_age = Map.delete(@person, :age) without_age = Map.delete(@person, :age)
assert Map.keys(without_age) |> Enum.sort == __ assert Map.keys(without_age) |> Enum.sort == ___
end end
koan "Can merge maps" do koan "Can merge maps" do
assert Map.merge(%{name: "Jon"}, %{last_name: "Snow"}) == __ assert Map.merge(%{name: "Jon"}, %{last_name: "Snow"}) == ___
end end
koan "When merging, the last map wins" do koan "When merging, the last map wins" do
merged = Map.merge(@person, %{ last_name: "Baratheon"}) merged = Map.merge(@person, %{ last_name: "Baratheon"})
assert Map.fetch(merged, :last_name) == __ assert Map.fetch(merged, :last_name) == ___
end end
koan "You can also select sub-maps out of a larger map" do koan "You can also select sub-maps out of a larger map" do
initial = %{ name: "Jon", last_name: "Snow", age: 15} initial = %{ name: "Jon", last_name: "Snow", age: 15}
assert Map.take(initial, [:name, :last_name]) == __ assert Map.take(initial, [:name, :last_name]) == ___
end end
end end

View File

@@ -7,34 +7,34 @@ defmodule Structs do
koan "Structs are defined and named after a module" do koan "Structs are defined and named after a module" do
person = %Person{} person = %Person{}
assert person == __ assert person == ___
end end
koan "You can access the fields of a struct" do koan "You can access the fields of a struct" do
nobody = %Person{} nobody = %Person{}
assert nobody.age == __ assert nobody.age == ___
end end
koan "You can pass initial values to structs" do koan "You can pass initial values to structs" do
joe = %Person{name: "Joe", age: 23} joe = %Person{name: "Joe", age: 23}
assert joe.name == __ assert joe.name == ___
end end
koan "Update fields with the pipe '|' operator" do koan "Update fields with the pipe '|' operator" do
joe = %Person{name: "Joe", age: 23} joe = %Person{name: "Joe", age: 23}
older = %{ joe | age: joe.age + 10} older = %{ joe | age: joe.age + 10}
assert older.age == __ assert older.age == ___
end end
koan "The original struct is not affected by updates" do koan "The original struct is not affected by updates" do
joe = %Person{name: "Joe", age: 23} joe = %Person{name: "Joe", age: 23}
assert %{ joe | age: joe.age + 10}.age == __ assert %{ joe | age: joe.age + 10}.age == ___
assert joe.age == __ assert joe.age == ___
end end
koan "You can pattern match into the fields of a struct" do koan "You can pattern match into the fields of a struct" do
%Person{age: age} = %Person{age: 22, name: "Silvia"} %Person{age: age} = %Person{age: 22, name: "Silvia"}
assert age == __ assert age == ___
end end
defmodule Plane do defmodule Plane do
@@ -45,14 +45,14 @@ defmodule Structs do
def plane?(_), do: false def plane?(_), do: false
koan "Or onto the type of the struct itself" do koan "Or onto the type of the struct itself" do
assert plane?(%Plane{passengers: 417, maker: :boeing}) == __ assert plane?(%Plane{passengers: 417, maker: :boeing}) == ___
assert plane?(%Person{}) == __ assert plane?(%Person{}) == ___
end end
koan "Are basically maps" do koan "Are basically maps" do
silvia = %Person{age: 22, name: "Silvia"} silvia = %Person{age: 22, name: "Silvia"}
assert Map.fetch!(silvia, :age) == __ assert Map.fetch!(silvia, :age) == ___
end end
end end

View File

@@ -2,53 +2,53 @@ defmodule PatternMatching do
use Koans use Koans
koan "One matches one" do koan "One matches one" do
assert match?(1, __) assert match?(1, ___)
end end
koan "A pattern can change" do koan "A pattern can change" do
a = 1 a = 1
assert a = __ assert a = ___
end end
koan "A pattern can also be strict" do koan "A pattern can also be strict" do
a = 1 a = 1
assert ^a = __ assert ^a = ___
end end
koan "Patterns can be used to pull things apart" do koan "Patterns can be used to pull things apart" do
[head | tail] = [1,2,3,4] [head | tail] = [1,2,3,4]
assert head == __ assert head == ___
assert tail == __ assert tail == ___
end end
koan "And then put them back together" do koan "And then put them back together" do
head = 1 head = 1
tail = [2,3,4] tail = [2,3,4]
assert __ == [head | tail] assert ___ == [head | tail]
end end
koan "Some values can be ignored" do koan "Some values can be ignored" do
[_first, _second, third, _fourth] = [1,2,3,4] [_first, _second, third, _fourth] = [1,2,3,4]
assert third == __ assert third == ___
end end
koan "Strings come apart just a easily" do koan "Strings come apart just a easily" do
"Shopping list: " <> items = "Shopping list: eggs, milk" "Shopping list: " <> items = "Shopping list: eggs, milk"
assert items == __ assert items == ___
end end
koan "Patterns show what you really care about" do koan "Patterns show what you really care about" do
%{make: make} = %{type: "car", year: 2016, make: "Honda", color: "black"} %{make: make} = %{type: "car", year: 2016, make: "Honda", color: "black"}
assert make == __ assert make == ___
end end
koan "The pattern can make assertions about what it expects" do koan "The pattern can make assertions about what it expects" do
assert match?([1, _second, _third], __) assert match?([1, _second, _third], ___)
end end
def make_noise(%{type: "cat"}), do: "Meow" def make_noise(%{type: "cat"}), do: "Meow"
@@ -60,9 +60,9 @@ defmodule PatternMatching do
cat = %{type: "cat", legs: 4, age: 3, color: "grey"} cat = %{type: "cat", legs: 4, age: 3, color: "grey"}
snake = %{type: "snake", legs: 0, age: 20, color: "black"} snake = %{type: "snake", legs: 0, age: 20, color: "black"}
assert make_noise(dog) == __ assert make_noise(dog) == ___
assert make_noise(cat) == __ assert make_noise(cat) == ___
assert make_noise(snake) == __ assert make_noise(snake) == ___
end end
koan "Errors are shaped differently than sucessful results" do koan "Errors are shaped differently than sucessful results" do
@@ -71,6 +71,6 @@ defmodule PatternMatching do
_ -> flunk("I should not happen") _ -> flunk("I should not happen")
end end
assert result == __ assert result == ___
end end
end end

View File

@@ -6,20 +6,20 @@ defmodule Functions do
end end
koan "Functions map arguments to outputs" do koan "Functions map arguments to outputs" do
assert greet("World") == __ assert greet("World") == ___
end end
def multiply(a, b), do: a * b def multiply(a, b), do: a * b
koan "Single line functions are cool, but mind the command and the colon!" do koan "Single line functions are cool, but mind the command and the colon!" do
assert multiply(2, __) == 6 assert multiply(2, ___) == 6
end end
def first(foo, bar), do: "#{foo} and #{bar}" def first(foo, bar), do: "#{foo} and #{bar}"
def first(foo), do: "Only #{foo}" def first(foo), do: "Only #{foo}"
koan "Functions with the same name are distinguished by the number of arguments they take" do koan "Functions with the same name are distinguished by the number of arguments they take" do
assert first("One", "Two") == __ assert first("One", "Two") == ___
assert first("One") == __ assert first("One") == ___
end end
def repeat_again(message, times \\ 5) do def repeat_again(message, times \\ 5) do
@@ -27,49 +27,49 @@ defmodule Functions do
end end
koan "Not all arguments are always needed" do koan "Not all arguments are always needed" do
assert repeat_again("Hello ") == __ assert repeat_again("Hello ") == ___
assert repeat_again("Hello ", 2) == __ assert repeat_again("Hello ", 2) == ___
end end
def sum_up(thing) when is_list(thing), do: :entire_list def sum_up(thing) when is_list(thing), do: :entire_list
def sum_up(_thing), do: :single_thing def sum_up(_thing), do: :single_thing
koan "Functions can be picky and apply to only certain types" do koan "Functions can be picky and apply to only certain types" do
assert sum_up([1,2,3]) == __ assert sum_up([1,2,3]) == ___
assert sum_up(1) == __ assert sum_up(1) == ___
end end
def bigger(a,b) when a > b, do: "#{a} is bigger than #{b}" def bigger(a,b) when a > b, do: "#{a} is bigger than #{b}"
def bigger(a,b) when a <= b, do: "#{a} is not bigger than #{b}" def bigger(a,b) when a <= b, do: "#{a} is not bigger than #{b}"
koan "Intricate guards are possible, but be mindful of the reader" do koan "Intricate guards are possible, but be mindful of the reader" do
assert bigger(10, 5) == __ assert bigger(10, 5) == ___
assert bigger(4, 27) == __ assert bigger(4, 27) == ___
end end
def the_length(0), do: "It was zero" def the_length(0), do: "It was zero"
def the_length(number), do: "The length was #{number}" def the_length(number), do: "The length was #{number}"
koan "For those individual one-offs, you can even guard on the arguments themselves" do koan "For those individual one-offs, you can even guard on the arguments themselves" do
assert the_length(0) == __ assert the_length(0) == ___
assert the_length(5) == __ assert the_length(5) == ___
end end
koan "Little anonymous functions are common, and called with a dot" do koan "Little anonymous functions are common, and called with a dot" do
multiply = fn (a,b) -> a * b end multiply = fn (a,b) -> a * b end
assert multiply.(2,3) == __ assert multiply.(2,3) == ___
end end
koan "You can even go shorter, by using &(..) and positional arguments" do koan "You can even go shorter, by using &(..) and positional arguments" do
multiply = &(&1 * &2) multiply = &(&1 * &2)
assert multiply.(2,3) == __ assert multiply.(2,3) == ___
end end
def times_five_and_then(number, fun), do: fun.(number*5) def times_five_and_then(number, fun), do: fun.(number*5)
def square(number), do: number * number def square(number), do: number * number
koan "You can pass functions around as arguments. Place and '&' before the name and state the arity" do koan "You can pass functions around as arguments. Place and '&' before the name and state the arity" do
assert times_five_and_then(2, &square/1) == __ assert times_five_and_then(2, &square/1) == ___
end end
koan "Functions can be combined elegantly with the pipe operator" do koan "Functions can be combined elegantly with the pipe operator" do
@@ -78,6 +78,6 @@ defmodule Functions do
|> Enum.map(&(String.capitalize(&1))) |> Enum.map(&(String.capitalize(&1)))
|> Enum.join(" ") |> Enum.join(" ")
assert result == __ assert result == ___
end end
end end

View File

@@ -2,78 +2,78 @@ defmodule Enums do
use Koans use Koans
koan "Knowing how many elements are in a list is important for book-keeping" do koan "Knowing how many elements are in a list is important for book-keeping" do
assert Enum.count([1,2,3]) == __ assert Enum.count([1,2,3]) == ___
end end
koan "Depending on the type, it counts pairs" do koan "Depending on the type, it counts pairs" do
assert Enum.count(%{ :a => :foo, :b => :bar}) == __ assert Enum.count(%{ :a => :foo, :b => :bar}) == ___
end end
def less_than_five?(n), do: n < 5 def less_than_five?(n), do: n < 5
koan "Elements can have a lot in common" do koan "Elements can have a lot in common" do
assert Enum.all?([1,2,3], &less_than_five?/1) == __ assert Enum.all?([1,2,3], &less_than_five?/1) == ___
assert Enum.all?([6,7,8,9], &less_than_five?/1) == __ assert Enum.all?([6,7,8,9], &less_than_five?/1) == ___
end end
def even?(n), do: rem(n, 2) == 0 def even?(n), do: rem(n, 2) == 0
koan "Sometimes you you just want to know if there are any elements fullfilling a condition" do koan "Sometimes you you just want to know if there are any elements fullfilling a condition" do
assert Enum.any?([1,2,3], &even?/1) == __ assert Enum.any?([1,2,3], &even?/1) == ___
assert Enum.any?([1,3,5], &even?/1) == __ assert Enum.any?([1,3,5], &even?/1) == ___
end end
koan "Sometimes you just want to know if an element is part of the party" do koan "Sometimes you just want to know if an element is part of the party" do
input = [1,2,3] input = [1,2,3]
assert Enum.member?(input, 1) == __ assert Enum.member?(input, 1) == ___
assert Enum.member?(input, 30) == __ assert Enum.member?(input, 30) == ___
end end
def multiply_by_ten(n), do: 10 * n def multiply_by_ten(n), do: 10 * n
koan "Map converts each element of a list by running some function with it" do koan "Map converts each element of a list by running some function with it" do
assert Enum.map([1,2,3], &multiply_by_ten/1) == __ assert Enum.map([1,2,3], &multiply_by_ten/1) == ___
end end
def odd?(n), do: rem(n, 2) == 1 def odd?(n), do: rem(n, 2) == 1
koan "Filter allows you to only keep what you really care about" do koan "Filter allows you to only keep what you really care about" do
assert Enum.filter([1,2,3], &odd?/1) == __ assert Enum.filter([1,2,3], &odd?/1) == ___
end end
koan "Reject will help you throw out unwanted cruft" do koan "Reject will help you throw out unwanted cruft" do
assert Enum.reject([1,2,3], &odd?/1) == __ assert Enum.reject([1,2,3], &odd?/1) == ___
end end
koan "You three there, follow me!" do koan "You three there, follow me!" do
assert Enum.take([1,2,3,4,5], 3) == __ assert Enum.take([1,2,3,4,5], 3) == ___
end end
koan "You can ask for a lot, but Enum won't hand you more than you give" do koan "You can ask for a lot, but Enum won't hand you more than you give" do
assert Enum.take([1,2,3,4,5], 10) == __ assert Enum.take([1,2,3,4,5], 10) == ___
end end
koan "Just like taking, you can also drop elements" do koan "Just like taking, you can also drop elements" do
assert Enum.drop([-1,0,1,2,3], 2) == __ assert Enum.drop([-1,0,1,2,3], 2) == ___
end end
koan "Zip-up in pairs!" do koan "Zip-up in pairs!" do
numbers = [1,2,3] numbers = [1,2,3]
letters = [:a, :b, :c] letters = [:a, :b, :c]
assert Enum.zip(numbers, letters) == __ assert Enum.zip(numbers, letters) == ___
end end
koan "When you want to find that one pesky element" do koan "When you want to find that one pesky element" do
assert Enum.find([1,2,3], &even?/1) == __ assert Enum.find([1,2,3], &even?/1) == ___
end end
def divisible_by_five?(n), do: rem(n, 5) == 0 def divisible_by_five?(n), do: rem(n, 5) == 0
koan "...but you don't quite find it..." do koan "...but you don't quite find it..." do
assert Enum.find([1,2,3], &divisible_by_five?/1) == __ assert Enum.find([1,2,3], &divisible_by_five?/1) == ___
end end
koan "...you can settle for a consolation prize" do koan "...you can settle for a consolation prize" do
assert Enum.find([1,2,3], :no_such_element, &divisible_by_five?/1) == __ assert Enum.find([1,2,3], :no_such_element, &divisible_by_five?/1) == ___
end end
koan "Collapse an entire list of elements down to a single one by repeating a function." do koan "Collapse an entire list of elements down to a single one by repeating a function." do
assert Enum.reduce([1,2,3], 0, fn(element, accumulator) -> element + accumulator end) == __ assert Enum.reduce([1,2,3], 0, fn(element, accumulator) -> element + accumulator end) == ___
end end
end end

View File

@@ -2,18 +2,18 @@ defmodule Processes do
use Koans use Koans
koan "Tests run in a process" do koan "Tests run in a process" do
assert Process.alive?(self()) == __ assert Process.alive?(self()) == ___
end end
koan "You can ask a process to introduce itself" do koan "You can ask a process to introduce itself" do
information = Process.info(self()) information = Process.info(self())
assert information[:status] == __ assert information[:status] == ___
end end
koan "You can send messages to any process you want" do koan "You can send messages to any process you want" do
send self(), "hola!" send self(), "hola!"
assert_receive __ assert_receive ___
end end
koan "A common pattern is to include the sender in the message" do koan "A common pattern is to include the sender in the message" do
@@ -24,7 +24,7 @@ defmodule Processes do
end) end)
send pid, {:hello, self()} send pid, {:hello, self()}
assert_receive __ assert_receive ___
end end
koan "Waiting for a message can get boring" do koan "Waiting for a message can get boring" do
@@ -36,21 +36,21 @@ defmodule Processes do
end end
end) end)
assert_receive __ assert_receive ___
end end
koan "Killing a process will terminate it" do koan "Killing a process will terminate it" do
pid = spawn(fn -> Process.exit(self(), :kill) end) pid = spawn(fn -> Process.exit(self(), :kill) end)
:timer.sleep(500) :timer.sleep(500)
assert Process.alive?(pid) == __ assert Process.alive?(pid) == ___
end end
koan "You can also terminate other processes than yourself" do koan "You can also terminate other processes than yourself" do
pid = spawn(fn -> receive do end end) pid = spawn(fn -> receive do end end)
assert Process.alive?(pid) == __ assert Process.alive?(pid) == ___
Process.exit(pid, :kill) Process.exit(pid, :kill)
assert Process.alive?(pid) == __ assert Process.alive?(pid) == ___
end end
koan "Trapping will allow you to react to someone terminating the process" do koan "Trapping will allow you to react to someone terminating the process" do
@@ -65,7 +65,7 @@ defmodule Processes do
wait() wait()
Process.exit(pid, :random_reason) Process.exit(pid, :random_reason)
assert_receive __ assert_receive ___
end end
koan "Trying to quit normally has no effect" do koan "Trying to quit normally has no effect" do
@@ -73,7 +73,7 @@ defmodule Processes do
end end
end) end)
Process.exit(pid, :normal) Process.exit(pid, :normal)
assert Process.alive?(pid) == __ assert Process.alive?(pid) == ___
end end
koan "Exiting yourself on the other hand DOES terminate you" do koan "Exiting yourself on the other hand DOES terminate you" do
@@ -84,7 +84,7 @@ defmodule Processes do
send pid, :bye send pid, :bye
:timer.sleep(100) :timer.sleep(100)
assert Process.alive?(pid) == __ assert Process.alive?(pid) == ___
end end
koan "Parent processes can be informed about exiting children, if they trap and link" do koan "Parent processes can be informed about exiting children, if they trap and link" do
@@ -97,7 +97,7 @@ defmodule Processes do
end end
end) end)
assert_receive __ assert_receive ___
end end
koan "If you monitor your children, you'll be automatically informed for their depature" do koan "If you monitor your children, you'll be automatically informed for their depature" do
@@ -109,7 +109,7 @@ defmodule Processes do
end end
end) end)
assert_receive __ assert_receive ___
end end
def wait do def wait do

View File

@@ -4,12 +4,12 @@ defmodule Tasks do
koan "Tasks can be used for asynchronous computations with results" do koan "Tasks can be used for asynchronous computations with results" do
task = Task.async(fn -> 3 *3 end) task = Task.async(fn -> 3 *3 end)
do_other_stuff() do_other_stuff()
assert Task.await(task) + 1 == __ assert Task.await(task) + 1 == ___
end end
koan "If you don't need a result, use start_link/1" do koan "If you don't need a result, use start_link/1" do
{result, _pid} = Task.start_link(fn -> 1+1 end) {result, _pid} = Task.start_link(fn -> 1+1 end)
assert result == __ assert result == ___
end end
koan "Yield returns nothing if the task isn't done yet" do koan "Yield returns nothing if the task isn't done yet" do
@@ -17,7 +17,7 @@ defmodule Tasks do
:timer.sleep(100) :timer.sleep(100)
3 * 3 3 * 3
end) end)
assert Task.yield(handle, 10) == __ assert Task.yield(handle, 10) == ___
end end
koan "Tasks can be aborted with shutdown" do koan "Tasks can be aborted with shutdown" do
@@ -25,13 +25,13 @@ defmodule Tasks do
:timer.sleep(100) :timer.sleep(100)
3 * 3 3 * 3
end) end)
assert Task.shutdown(handle) == __ assert Task.shutdown(handle) == ___
end end
koan "Shutdown will give you an answer if it has it" do koan "Shutdown will give you an answer if it has it" do
handle = Task.async(fn -> 3 * 3 end) handle = Task.async(fn -> 3 * 3 end)
:timer.sleep(10) :timer.sleep(10)
assert Task.shutdown(handle) == {:ok, __} assert Task.shutdown(handle) == {:ok, ___}
end end
koan "You can yield to multiple tasks at once and extract the results" do koan "You can yield to multiple tasks at once and extract the results" do
@@ -40,7 +40,7 @@ defmodule Tasks do
|> Task.yield_many(100) |> Task.yield_many(100)
|> Enum.map(fn({_task,{:ok, result}}) -> result end) |> Enum.map(fn({_task,{:ok, result}}) -> result end)
assert squares == __ assert squares == ___
end end
def do_other_stuff do def do_other_stuff do

View File

@@ -3,7 +3,7 @@ defmodule Agents do
koan "Agents maintain state, so you can ask them about it" do koan "Agents maintain state, so you can ask them about it" do
Agent.start_link(fn() -> "Hi there" end, name: __MODULE__) Agent.start_link(fn() -> "Hi there" end, name: __MODULE__)
assert Agent.get(__MODULE__, &(&1)) == __ assert Agent.get(__MODULE__, &(&1)) == ___
end end
koan "Update to update the state" do koan "Update to update the state" do
@@ -12,7 +12,7 @@ defmodule Agents do
Agent.update(__MODULE__, fn(old) -> Agent.update(__MODULE__, fn(old) ->
String.upcase(old) String.upcase(old)
end) end)
assert Agent.get(__MODULE__, &(&1)) == __ assert Agent.get(__MODULE__, &(&1)) == ___
end end
koan "Use get_and_update when you need read and change a value in one go" do koan "Use get_and_update when you need read and change a value in one go" do
@@ -22,8 +22,8 @@ defmodule Agents do
{old, ["Bread" | old]} {old, ["Bread" | old]}
end) end)
assert old_list == __ assert old_list == ___
assert Agent.get(__MODULE__, &(&1)) == __ assert Agent.get(__MODULE__, &(&1)) == ___
end end
koan "Somebody has to switch off the light at the end of the day" do koan "Somebody has to switch off the light at the end of the day" do
@@ -31,6 +31,6 @@ defmodule Agents do
result = Agent.stop(__MODULE__) result = Agent.stop(__MODULE__)
assert result == __ assert result == ___
end end
end end

View File

@@ -2,7 +2,7 @@ defmodule BlanksTest do
use ExUnit.Case, async: true use ExUnit.Case, async: true
test "simple replacement" do test "simple replacement" do
ast = quote do: 1 + __ ast = quote do: 1 + ___
mangled = Blanks.replace(ast, 37) mangled = Blanks.replace(ast, 37)
assert {:+, [context: BlanksTest, import: Kernel], [1, 37]} == mangled assert {:+, [context: BlanksTest, import: Kernel], [1, 37]} == mangled
@@ -29,25 +29,25 @@ defmodule BlanksTest do
end end
test "complex example" do test "complex example" do
ast = [do: {:assert, [line: 5], [{:==, [line: 5], [true, {:__, [], __MODULE__}]}]}] ast = [do: {:assert, [line: 5], [{:==, [line: 5], [true, {:___, [], __MODULE__}]}]}]
assert [do: {:assert, [line: 5], [{:==, [line: 5], [true, true]}]}] == Blanks.replace(ast, true) assert [do: {:assert, [line: 5], [{:==, [line: 5], [true, true]}]}] == Blanks.replace(ast, true)
end end
test "multiple arguments" do test "multiple arguments" do
ast = [do: {:assert, [line: 5], [{:==, [line: 5], [{:__, [], __MODULE__}, {:__, [], __MODULE__}]}]}] ast = [do: {:assert, [line: 5], [{:==, [line: 5], [{:___, [], __MODULE__}, {:___, [], __MODULE__}]}]}]
assert [do: {:assert, [line: 5], [{:==, [line: 5], [true, false]}]}] == Blanks.replace(ast, [true, false]) assert [do: {:assert, [line: 5], [{:==, [line: 5], [true, false]}]}] == Blanks.replace(ast, [true, false])
end end
test "counts simple blanks" do test "counts simple blanks" do
ast = quote do: 1 + __ ast = quote do: 1 + ___
assert Blanks.count(ast) == 1 assert Blanks.count(ast) == 1
end end
test "counts multiple blanks" do test "counts multiple blanks" do
ast = [do: {:assert, [line: 5], [{:==, [line: 5], [{:__, [], __MODULE__}, {:__, __MODULE__}]}]}] ast = [do: {:assert, [line: 5], [{:==, [line: 5], [{:___, [], __MODULE__}, {:___, __MODULE__}]}]}]
assert Blanks.count(ast) == 2 assert Blanks.count(ast) == 2
end end

View File

@@ -2,7 +2,7 @@ defmodule SampleKoan do
use Koans use Koans
koan "Thinking more than once" do koan "Thinking more than once" do
assert 3 == :__ assert 3 == ___
assert 4 == :__ assert 4 == ___
end end
end end