Use triple underscore instead of double
This commit is contained in:
@@ -51,19 +51,6 @@ defmodule BlankAssertions do
|
||||
end
|
||||
|
||||
defp contains_blank?(expr) do
|
||||
{_, blank} = Macro.prewalk(expr, false, &blank?/2)
|
||||
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 == :__}
|
||||
Blanks.count(expr) > 0
|
||||
end
|
||||
end
|
||||
|
@@ -7,8 +7,8 @@ defmodule Blanks do
|
||||
|> elem(0)
|
||||
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}
|
||||
|
||||
def count(ast) do
|
||||
@@ -17,7 +17,7 @@ defmodule Blanks do
|
||||
|> elem(1)
|
||||
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}
|
||||
end
|
||||
|
@@ -2,30 +2,30 @@ defmodule Equalities do
|
||||
use Koans
|
||||
|
||||
koan "We shall contemplate truth by testing reality, via equality" do
|
||||
assert true == __
|
||||
assert true == ___
|
||||
end
|
||||
|
||||
koan "Not something is the opposite of it" do
|
||||
assert !true == __
|
||||
assert !true == ___
|
||||
end
|
||||
|
||||
koan "To understand reality, we must compare our expectations against reality" do
|
||||
assert 2 == 1 + __
|
||||
assert 2 == 1 + ___
|
||||
end
|
||||
|
||||
koan "Some things may appear different, but be the same" do
|
||||
assert 1 == 2 / __
|
||||
assert 1 == 2 / ___
|
||||
end
|
||||
|
||||
koan "Unless they actually are different" do
|
||||
assert 3.2 != __
|
||||
assert 3.2 != ___
|
||||
end
|
||||
|
||||
koan "Some may be looking for bigger things" do
|
||||
assert __ > 3
|
||||
assert ___ > 3
|
||||
end
|
||||
|
||||
koan "Others are happy with less" do
|
||||
assert __ < 3
|
||||
assert ___ < 3
|
||||
end
|
||||
end
|
||||
|
@@ -2,38 +2,38 @@ defmodule Strings do
|
||||
use Koans
|
||||
|
||||
koan "Strings are there to represent text" do
|
||||
assert "hello" == __
|
||||
assert "hello" == ___
|
||||
end
|
||||
|
||||
koan "They can be put together" do
|
||||
assert "hello world" == __ <> "world"
|
||||
assert "hello world" == ___ <> "world"
|
||||
end
|
||||
|
||||
koan "Or pulled apart when needed" do
|
||||
assert __ == String.split("hello world")
|
||||
assert ___ == String.split("hello world")
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
koan "But strings never lie about themselves" do
|
||||
assert true == String.contains?("An incredible day", __)
|
||||
assert true == String.contains?("An incredible day", ___)
|
||||
end
|
||||
|
||||
koan "Sometimes you want just the opposite of what is given" do
|
||||
assert __ == String.reverse("ananab")
|
||||
assert ___ == String.reverse("ananab")
|
||||
end
|
||||
|
||||
koan "Other times a little cleaning is in order" do
|
||||
assert __ == String.strip(" \n banana\n ")
|
||||
assert ___ == String.strip(" \n banana\n ")
|
||||
end
|
||||
|
||||
koan "Repetition is the mother of learning" do
|
||||
assert "StringStringString" == String.duplicate(__, 3)
|
||||
assert "StringStringString" == String.duplicate(___, 3)
|
||||
end
|
||||
|
||||
koan "Strings can be louder when necessary" do
|
||||
assert "LISTEN" == String.upcase(__)
|
||||
assert "LISTEN" == String.upcase(___)
|
||||
end
|
||||
end
|
||||
|
@@ -2,34 +2,34 @@ defmodule Tuples do
|
||||
use Koans
|
||||
|
||||
koan "Tuples have a size" do
|
||||
assert tuple_size({:a, :b, :c}) == __
|
||||
assert tuple_size({:a, :b, :c}) == ___
|
||||
end
|
||||
|
||||
koan "Tuples can contain different things" do
|
||||
assert {:a, 1, "hi"} == __
|
||||
assert {:a, 1, "hi"} == ___
|
||||
end
|
||||
|
||||
koan "You can pull out individual elements" do
|
||||
assert elem({:a, "hi"}, 1) == __
|
||||
assert elem({:a, "hi"}, 1) == ___
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
koan "Add things at the end" do
|
||||
assert Tuple.append({"Huey", "Dewey"}, "Louie") == __
|
||||
assert Tuple.append({"Huey", "Dewey"}, "Louie") == ___
|
||||
end
|
||||
|
||||
koan "Or remove them" do
|
||||
assert Tuple.delete_at({:this, :is, :not, :awesome}, 2) == __
|
||||
assert Tuple.delete_at({:this, :is, :not, :awesome}, 2) == ___
|
||||
end
|
||||
|
||||
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
|
||||
|
@@ -2,70 +2,70 @@ defmodule Lists do
|
||||
use Koans
|
||||
|
||||
koan "We can see what is ahead" do
|
||||
assert List.first([1, 2, 3]) == __
|
||||
assert List.first([1, 2, 3]) == ___
|
||||
end
|
||||
|
||||
koan "Checking what's trailing is also simple" do
|
||||
assert List.last([1, 2, 3]) == __
|
||||
assert List.last([1, 2, 3]) == ___
|
||||
end
|
||||
|
||||
koan "Lists can store anything you throw at them" do
|
||||
assert [1, 2] ++ [:a, "b"] == __
|
||||
assert [1, 2] ++ [:a, "b"] == ___
|
||||
end
|
||||
|
||||
koan "Things can evolve" do
|
||||
assert [1, 2, 3] -- [3] == __
|
||||
assert [1, 2, 3] -- [3] == ___
|
||||
end
|
||||
|
||||
koan "Evolution can have different forms" do
|
||||
assert List.delete([1, 2, 2, 3], 2) == __
|
||||
assert List.delete([1, 2, 2, 3], 2) == ___
|
||||
end
|
||||
|
||||
koan "Precision is also valued" do
|
||||
assert List.delete_at([1, 2, 3], 1) == __
|
||||
assert List.delete_at([1, 2, 3], 1) == ___
|
||||
end
|
||||
|
||||
koan "Replication is also possible" do
|
||||
assert List.duplicate("life", 3) == __
|
||||
assert List.duplicate("life", 3) == ___
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
koan "We can also transform ourselves completely" do
|
||||
assert List.to_tuple([1, 2, 3]) == __
|
||||
assert List.to_tuple([1, 2, 3]) == ___
|
||||
end
|
||||
|
||||
koan "Wrapping other values is a handy option" do
|
||||
assert List.wrap("value") == :__
|
||||
assert List.wrap("value") == :___
|
||||
end
|
||||
|
||||
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
|
||||
|
@@ -8,55 +8,55 @@ defmodule Maps do
|
||||
}
|
||||
|
||||
koan "Maps represent structured data, like a person" do
|
||||
assert @person == %{name: __,
|
||||
assert @person == %{name: ___,
|
||||
last_name: "Snow",
|
||||
age: 27 }
|
||||
end
|
||||
|
||||
koan "A map has keys and values" do
|
||||
assert Map.keys(@person) |> Enum.sort == __
|
||||
assert Map.values(@person) |> Enum.sort == __
|
||||
assert Map.keys(@person) |> Enum.sort == ___
|
||||
assert Map.values(@person) |> Enum.sort == ___
|
||||
end
|
||||
|
||||
koan "Fetching a value returns a tuple with ok when it exists" do
|
||||
assert Map.fetch(@person, :age) == __
|
||||
assert Map.fetch(@person, :age) == ___
|
||||
end
|
||||
|
||||
koan "Or the atom :error when it doesnt" do
|
||||
assert Map.fetch(@person, :family) == __
|
||||
assert Map.fetch(@person, :family) == ___
|
||||
end
|
||||
|
||||
koan "Extending a map is a simple as putting in a new pair" do
|
||||
person_with_hobby = Map.put(@person, :hobby, "Kayaking")
|
||||
assert Map.fetch(person_with_hobby, :hobby) == __
|
||||
assert Map.fetch(person_with_hobby, :hobby) == ___
|
||||
end
|
||||
|
||||
koan "Put can also overwrite existing values" do
|
||||
older_person = Map.put(@person, :age, 37)
|
||||
assert Map.fetch(older_person, :age) == __
|
||||
assert Map.fetch(older_person, :age) == ___
|
||||
end
|
||||
|
||||
koan "Or you can use some syntactic sugar for existing elements" do
|
||||
younger_person = %{ @person | age: 16 }
|
||||
assert Map.fetch(younger_person, :age) == __
|
||||
assert Map.fetch(younger_person, :age) == ___
|
||||
end
|
||||
|
||||
koan "Can remove pairs by key" do
|
||||
without_age = Map.delete(@person, :age)
|
||||
assert Map.keys(without_age) |> Enum.sort == __
|
||||
assert Map.keys(without_age) |> Enum.sort == ___
|
||||
end
|
||||
|
||||
koan "Can merge maps" do
|
||||
assert Map.merge(%{name: "Jon"}, %{last_name: "Snow"}) == __
|
||||
assert Map.merge(%{name: "Jon"}, %{last_name: "Snow"}) == ___
|
||||
end
|
||||
|
||||
koan "When merging, the last map wins" do
|
||||
merged = Map.merge(@person, %{ last_name: "Baratheon"})
|
||||
assert Map.fetch(merged, :last_name) == __
|
||||
assert Map.fetch(merged, :last_name) == ___
|
||||
end
|
||||
|
||||
koan "You can also select sub-maps out of a larger map" do
|
||||
initial = %{ name: "Jon", last_name: "Snow", age: 15}
|
||||
assert Map.take(initial, [:name, :last_name]) == __
|
||||
assert Map.take(initial, [:name, :last_name]) == ___
|
||||
end
|
||||
end
|
||||
|
@@ -7,34 +7,34 @@ defmodule Structs do
|
||||
|
||||
koan "Structs are defined and named after a module" do
|
||||
person = %Person{}
|
||||
assert person == __
|
||||
assert person == ___
|
||||
end
|
||||
|
||||
koan "You can access the fields of a struct" do
|
||||
nobody = %Person{}
|
||||
assert nobody.age == __
|
||||
assert nobody.age == ___
|
||||
end
|
||||
|
||||
koan "You can pass initial values to structs" do
|
||||
joe = %Person{name: "Joe", age: 23}
|
||||
assert joe.name == __
|
||||
assert joe.name == ___
|
||||
end
|
||||
|
||||
koan "Update fields with the pipe '|' operator" do
|
||||
joe = %Person{name: "Joe", age: 23}
|
||||
older = %{ joe | age: joe.age + 10}
|
||||
assert older.age == __
|
||||
assert older.age == ___
|
||||
end
|
||||
|
||||
koan "The original struct is not affected by updates" do
|
||||
joe = %Person{name: "Joe", age: 23}
|
||||
assert %{ joe | age: joe.age + 10}.age == __
|
||||
assert joe.age == __
|
||||
assert %{ joe | age: joe.age + 10}.age == ___
|
||||
assert joe.age == ___
|
||||
end
|
||||
|
||||
koan "You can pattern match into the fields of a struct" do
|
||||
%Person{age: age} = %Person{age: 22, name: "Silvia"}
|
||||
assert age == __
|
||||
assert age == ___
|
||||
end
|
||||
|
||||
defmodule Plane do
|
||||
@@ -45,14 +45,14 @@ defmodule Structs do
|
||||
def plane?(_), do: false
|
||||
|
||||
koan "Or onto the type of the struct itself" do
|
||||
assert plane?(%Plane{passengers: 417, maker: :boeing}) == __
|
||||
assert plane?(%Person{}) == __
|
||||
assert plane?(%Plane{passengers: 417, maker: :boeing}) == ___
|
||||
assert plane?(%Person{}) == ___
|
||||
end
|
||||
|
||||
|
||||
koan "Are basically maps" do
|
||||
silvia = %Person{age: 22, name: "Silvia"}
|
||||
|
||||
assert Map.fetch!(silvia, :age) == __
|
||||
assert Map.fetch!(silvia, :age) == ___
|
||||
end
|
||||
end
|
||||
|
@@ -2,53 +2,53 @@ defmodule PatternMatching do
|
||||
use Koans
|
||||
|
||||
koan "One matches one" do
|
||||
assert match?(1, __)
|
||||
assert match?(1, ___)
|
||||
end
|
||||
|
||||
koan "A pattern can change" do
|
||||
a = 1
|
||||
assert a = __
|
||||
assert a = ___
|
||||
end
|
||||
|
||||
koan "A pattern can also be strict" do
|
||||
a = 1
|
||||
assert ^a = __
|
||||
assert ^a = ___
|
||||
end
|
||||
|
||||
koan "Patterns can be used to pull things apart" do
|
||||
[head | tail] = [1,2,3,4]
|
||||
|
||||
assert head == __
|
||||
assert tail == __
|
||||
assert head == ___
|
||||
assert tail == ___
|
||||
end
|
||||
|
||||
koan "And then put them back together" do
|
||||
head = 1
|
||||
tail = [2,3,4]
|
||||
|
||||
assert __ == [head | tail]
|
||||
assert ___ == [head | tail]
|
||||
end
|
||||
|
||||
koan "Some values can be ignored" do
|
||||
[_first, _second, third, _fourth] = [1,2,3,4]
|
||||
|
||||
assert third == __
|
||||
assert third == ___
|
||||
end
|
||||
|
||||
koan "Strings come apart just a easily" do
|
||||
"Shopping list: " <> items = "Shopping list: eggs, milk"
|
||||
|
||||
assert items == __
|
||||
assert items == ___
|
||||
end
|
||||
|
||||
koan "Patterns show what you really care about" do
|
||||
%{make: make} = %{type: "car", year: 2016, make: "Honda", color: "black"}
|
||||
|
||||
assert make == __
|
||||
assert make == ___
|
||||
end
|
||||
|
||||
koan "The pattern can make assertions about what it expects" do
|
||||
assert match?([1, _second, _third], __)
|
||||
assert match?([1, _second, _third], ___)
|
||||
end
|
||||
|
||||
def make_noise(%{type: "cat"}), do: "Meow"
|
||||
@@ -60,9 +60,9 @@ defmodule PatternMatching do
|
||||
cat = %{type: "cat", legs: 4, age: 3, color: "grey"}
|
||||
snake = %{type: "snake", legs: 0, age: 20, color: "black"}
|
||||
|
||||
assert make_noise(dog) == __
|
||||
assert make_noise(cat) == __
|
||||
assert make_noise(snake) == __
|
||||
assert make_noise(dog) == ___
|
||||
assert make_noise(cat) == ___
|
||||
assert make_noise(snake) == ___
|
||||
end
|
||||
|
||||
koan "Errors are shaped differently than sucessful results" do
|
||||
@@ -71,6 +71,6 @@ defmodule PatternMatching do
|
||||
_ -> flunk("I should not happen")
|
||||
end
|
||||
|
||||
assert result == __
|
||||
assert result == ___
|
||||
end
|
||||
end
|
||||
|
@@ -6,20 +6,20 @@ defmodule Functions do
|
||||
end
|
||||
|
||||
koan "Functions map arguments to outputs" do
|
||||
assert greet("World") == __
|
||||
assert greet("World") == ___
|
||||
end
|
||||
|
||||
def multiply(a, b), do: a * b
|
||||
koan "Single line functions are cool, but mind the command and the colon!" do
|
||||
assert multiply(2, __) == 6
|
||||
assert multiply(2, ___) == 6
|
||||
end
|
||||
|
||||
def first(foo, bar), do: "#{foo} and #{bar}"
|
||||
def first(foo), do: "Only #{foo}"
|
||||
|
||||
koan "Functions with the same name are distinguished by the number of arguments they take" do
|
||||
assert first("One", "Two") == __
|
||||
assert first("One") == __
|
||||
assert first("One", "Two") == ___
|
||||
assert first("One") == ___
|
||||
end
|
||||
|
||||
def repeat_again(message, times \\ 5) do
|
||||
@@ -27,49 +27,49 @@ defmodule Functions do
|
||||
end
|
||||
|
||||
koan "Not all arguments are always needed" do
|
||||
assert repeat_again("Hello ") == __
|
||||
assert repeat_again("Hello ", 2) == __
|
||||
assert repeat_again("Hello ") == ___
|
||||
assert repeat_again("Hello ", 2) == ___
|
||||
end
|
||||
|
||||
def sum_up(thing) when is_list(thing), do: :entire_list
|
||||
def sum_up(_thing), do: :single_thing
|
||||
|
||||
koan "Functions can be picky and apply to only certain types" do
|
||||
assert sum_up([1,2,3]) == __
|
||||
assert sum_up(1) == __
|
||||
assert sum_up([1,2,3]) == ___
|
||||
assert sum_up(1) == ___
|
||||
end
|
||||
|
||||
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}"
|
||||
|
||||
koan "Intricate guards are possible, but be mindful of the reader" do
|
||||
assert bigger(10, 5) == __
|
||||
assert bigger(4, 27) == __
|
||||
assert bigger(10, 5) == ___
|
||||
assert bigger(4, 27) == ___
|
||||
end
|
||||
|
||||
def the_length(0), do: "It was zero"
|
||||
def the_length(number), do: "The length was #{number}"
|
||||
|
||||
koan "For those individual one-offs, you can even guard on the arguments themselves" do
|
||||
assert the_length(0) == __
|
||||
assert the_length(5) == __
|
||||
assert the_length(0) == ___
|
||||
assert the_length(5) == ___
|
||||
end
|
||||
|
||||
koan "Little anonymous functions are common, and called with a dot" do
|
||||
multiply = fn (a,b) -> a * b end
|
||||
assert multiply.(2,3) == __
|
||||
assert multiply.(2,3) == ___
|
||||
end
|
||||
|
||||
koan "You can even go shorter, by using &(..) and positional arguments" do
|
||||
multiply = &(&1 * &2)
|
||||
assert multiply.(2,3) == __
|
||||
assert multiply.(2,3) == ___
|
||||
end
|
||||
|
||||
def times_five_and_then(number, fun), do: fun.(number*5)
|
||||
def square(number), do: number * number
|
||||
|
||||
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
|
||||
|
||||
koan "Functions can be combined elegantly with the pipe operator" do
|
||||
@@ -78,6 +78,6 @@ defmodule Functions do
|
||||
|> Enum.map(&(String.capitalize(&1)))
|
||||
|> Enum.join(" ")
|
||||
|
||||
assert result == __
|
||||
assert result == ___
|
||||
end
|
||||
end
|
||||
|
@@ -2,78 +2,78 @@ defmodule Enums do
|
||||
use Koans
|
||||
|
||||
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
|
||||
|
||||
koan "Depending on the type, it counts pairs" do
|
||||
assert Enum.count(%{ :a => :foo, :b => :bar}) == __
|
||||
assert Enum.count(%{ :a => :foo, :b => :bar}) == ___
|
||||
end
|
||||
|
||||
def less_than_five?(n), do: n < 5
|
||||
koan "Elements can have a lot in common" do
|
||||
assert Enum.all?([1,2,3], &less_than_five?/1) == __
|
||||
assert Enum.all?([6,7,8,9], &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) == ___
|
||||
end
|
||||
|
||||
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
|
||||
assert Enum.any?([1,2,3], &even?/1) == __
|
||||
assert Enum.any?([1,3,5], &even?/1) == __
|
||||
assert Enum.any?([1,2,3], &even?/1) == ___
|
||||
assert Enum.any?([1,3,5], &even?/1) == ___
|
||||
end
|
||||
|
||||
koan "Sometimes you just want to know if an element is part of the party" do
|
||||
input = [1,2,3]
|
||||
assert Enum.member?(input, 1) == __
|
||||
assert Enum.member?(input, 30) == __
|
||||
assert Enum.member?(input, 1) == ___
|
||||
assert Enum.member?(input, 30) == ___
|
||||
end
|
||||
|
||||
def multiply_by_ten(n), do: 10 * n
|
||||
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
|
||||
|
||||
def odd?(n), do: rem(n, 2) == 1
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
koan "Zip-up in pairs!" do
|
||||
numbers = [1,2,3]
|
||||
letters = [:a, :b, :c]
|
||||
assert Enum.zip(numbers, letters) == __
|
||||
assert Enum.zip(numbers, letters) == ___
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def divisible_by_five?(n), do: rem(n, 5) == 0
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
@@ -2,18 +2,18 @@ defmodule Processes do
|
||||
use Koans
|
||||
|
||||
koan "Tests run in a process" do
|
||||
assert Process.alive?(self()) == __
|
||||
assert Process.alive?(self()) == ___
|
||||
end
|
||||
|
||||
koan "You can ask a process to introduce itself" do
|
||||
information = Process.info(self())
|
||||
|
||||
assert information[:status] == __
|
||||
assert information[:status] == ___
|
||||
end
|
||||
|
||||
koan "You can send messages to any process you want" do
|
||||
send self(), "hola!"
|
||||
assert_receive __
|
||||
assert_receive ___
|
||||
end
|
||||
|
||||
koan "A common pattern is to include the sender in the message" do
|
||||
@@ -24,7 +24,7 @@ defmodule Processes do
|
||||
end)
|
||||
|
||||
send pid, {:hello, self()}
|
||||
assert_receive __
|
||||
assert_receive ___
|
||||
end
|
||||
|
||||
koan "Waiting for a message can get boring" do
|
||||
@@ -36,21 +36,21 @@ defmodule Processes do
|
||||
end
|
||||
end)
|
||||
|
||||
assert_receive __
|
||||
assert_receive ___
|
||||
end
|
||||
|
||||
koan "Killing a process will terminate it" do
|
||||
pid = spawn(fn -> Process.exit(self(), :kill) end)
|
||||
:timer.sleep(500)
|
||||
assert Process.alive?(pid) == __
|
||||
assert Process.alive?(pid) == ___
|
||||
end
|
||||
|
||||
koan "You can also terminate other processes than yourself" do
|
||||
pid = spawn(fn -> receive do end end)
|
||||
|
||||
assert Process.alive?(pid) == __
|
||||
assert Process.alive?(pid) == ___
|
||||
Process.exit(pid, :kill)
|
||||
assert Process.alive?(pid) == __
|
||||
assert Process.alive?(pid) == ___
|
||||
end
|
||||
|
||||
koan "Trapping will allow you to react to someone terminating the process" do
|
||||
@@ -65,7 +65,7 @@ defmodule Processes do
|
||||
wait()
|
||||
Process.exit(pid, :random_reason)
|
||||
|
||||
assert_receive __
|
||||
assert_receive ___
|
||||
end
|
||||
|
||||
koan "Trying to quit normally has no effect" do
|
||||
@@ -73,7 +73,7 @@ defmodule Processes do
|
||||
end
|
||||
end)
|
||||
Process.exit(pid, :normal)
|
||||
assert Process.alive?(pid) == __
|
||||
assert Process.alive?(pid) == ___
|
||||
end
|
||||
|
||||
koan "Exiting yourself on the other hand DOES terminate you" do
|
||||
@@ -84,7 +84,7 @@ defmodule Processes do
|
||||
|
||||
send pid, :bye
|
||||
:timer.sleep(100)
|
||||
assert Process.alive?(pid) == __
|
||||
assert Process.alive?(pid) == ___
|
||||
end
|
||||
|
||||
koan "Parent processes can be informed about exiting children, if they trap and link" do
|
||||
@@ -97,7 +97,7 @@ defmodule Processes do
|
||||
end
|
||||
end)
|
||||
|
||||
assert_receive __
|
||||
assert_receive ___
|
||||
end
|
||||
|
||||
koan "If you monitor your children, you'll be automatically informed for their depature" do
|
||||
@@ -109,7 +109,7 @@ defmodule Processes do
|
||||
end
|
||||
end)
|
||||
|
||||
assert_receive __
|
||||
assert_receive ___
|
||||
end
|
||||
|
||||
def wait do
|
||||
|
@@ -4,12 +4,12 @@ defmodule Tasks do
|
||||
koan "Tasks can be used for asynchronous computations with results" do
|
||||
task = Task.async(fn -> 3 *3 end)
|
||||
do_other_stuff()
|
||||
assert Task.await(task) + 1 == __
|
||||
assert Task.await(task) + 1 == ___
|
||||
end
|
||||
|
||||
koan "If you don't need a result, use start_link/1" do
|
||||
{result, _pid} = Task.start_link(fn -> 1+1 end)
|
||||
assert result == __
|
||||
assert result == ___
|
||||
end
|
||||
|
||||
koan "Yield returns nothing if the task isn't done yet" do
|
||||
@@ -17,7 +17,7 @@ defmodule Tasks do
|
||||
:timer.sleep(100)
|
||||
3 * 3
|
||||
end)
|
||||
assert Task.yield(handle, 10) == __
|
||||
assert Task.yield(handle, 10) == ___
|
||||
end
|
||||
|
||||
koan "Tasks can be aborted with shutdown" do
|
||||
@@ -25,13 +25,13 @@ defmodule Tasks do
|
||||
:timer.sleep(100)
|
||||
3 * 3
|
||||
end)
|
||||
assert Task.shutdown(handle) == __
|
||||
assert Task.shutdown(handle) == ___
|
||||
end
|
||||
|
||||
koan "Shutdown will give you an answer if it has it" do
|
||||
handle = Task.async(fn -> 3 * 3 end)
|
||||
:timer.sleep(10)
|
||||
assert Task.shutdown(handle) == {:ok, __}
|
||||
assert Task.shutdown(handle) == {:ok, ___}
|
||||
end
|
||||
|
||||
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)
|
||||
|> Enum.map(fn({_task,{:ok, result}}) -> result end)
|
||||
|
||||
assert squares == __
|
||||
assert squares == ___
|
||||
end
|
||||
|
||||
def do_other_stuff do
|
||||
|
@@ -3,7 +3,7 @@ defmodule Agents do
|
||||
|
||||
koan "Agents maintain state, so you can ask them about it" do
|
||||
Agent.start_link(fn() -> "Hi there" end, name: __MODULE__)
|
||||
assert Agent.get(__MODULE__, &(&1)) == __
|
||||
assert Agent.get(__MODULE__, &(&1)) == ___
|
||||
end
|
||||
|
||||
koan "Update to update the state" do
|
||||
@@ -12,7 +12,7 @@ defmodule Agents do
|
||||
Agent.update(__MODULE__, fn(old) ->
|
||||
String.upcase(old)
|
||||
end)
|
||||
assert Agent.get(__MODULE__, &(&1)) == __
|
||||
assert Agent.get(__MODULE__, &(&1)) == ___
|
||||
end
|
||||
|
||||
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]}
|
||||
end)
|
||||
|
||||
assert old_list == __
|
||||
assert Agent.get(__MODULE__, &(&1)) == __
|
||||
assert old_list == ___
|
||||
assert Agent.get(__MODULE__, &(&1)) == ___
|
||||
end
|
||||
|
||||
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__)
|
||||
|
||||
assert result == __
|
||||
assert result == ___
|
||||
end
|
||||
end
|
||||
|
@@ -2,7 +2,7 @@ defmodule BlanksTest do
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
test "simple replacement" do
|
||||
ast = quote do: 1 + __
|
||||
ast = quote do: 1 + ___
|
||||
|
||||
mangled = Blanks.replace(ast, 37)
|
||||
assert {:+, [context: BlanksTest, import: Kernel], [1, 37]} == mangled
|
||||
@@ -29,25 +29,25 @@ defmodule BlanksTest do
|
||||
end
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
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])
|
||||
end
|
||||
|
||||
test "counts simple blanks" do
|
||||
ast = quote do: 1 + __
|
||||
ast = quote do: 1 + ___
|
||||
|
||||
assert Blanks.count(ast) == 1
|
||||
end
|
||||
|
||||
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
|
||||
end
|
||||
|
@@ -2,7 +2,7 @@ defmodule SampleKoan do
|
||||
use Koans
|
||||
|
||||
koan "Thinking more than once" do
|
||||
assert 3 == :__
|
||||
assert 4 == :__
|
||||
assert 3 == ___
|
||||
assert 4 == ___
|
||||
end
|
||||
end
|
||||
|
Reference in New Issue
Block a user