Merge pull request #51 from ukutaht/improve_descriptions_6-12

Improve descriptions Part 2
This commit is contained in:
Uku Taht
2016-03-21 21:43:55 +00:00
7 changed files with 117 additions and 127 deletions

View File

@@ -5,12 +5,12 @@ defmodule Structs do
defstruct [:name, :age ]
end
koan "structs are defined and named after a module" do
koan "Structs are defined and named after a module" do
person = %Person{}
assert person == :__
end
koan "you can access the fields of a struct" do
koan "You can access the fields of a struct" do
nobody = %Person{}
assert nobody.age == :__
end
@@ -20,19 +20,19 @@ defmodule Structs do
assert joe.name == :__
end
koan "update fields with the pipe '|' operator" do
koan "Update fields with the pipe '|' operator" do
joe = %Person{name: "Joe", age: 23}
older = %{ joe | age: joe.age + 10}
assert older.age == :__
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}
assert %{ joe | age: joe.age + 10}.age == 33
assert %{ joe | age: joe.age + 10}.age == :__
assert joe.age == :__
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"}
assert age == :__
end
@@ -41,13 +41,16 @@ defmodule Structs do
defstruct passengers: 0, maker: :boeing
end
koan "or onto the type of the struct itself" do
assert is_a_plane(%Plane{passengers: 417, maker: :boeing}) == :__
def plane?(%Plane{}), do: true
def plane?(_), do: false
koan "Or onto the type of the struct itself" do
assert plane?(%Plane{passengers: 417, maker: :boeing}) == :__
assert plane?(%Person{}) == :__
end
def is_a_plane(%Plane{}), do: true
koan "are basically maps" do
koan "Are basically maps" do
silvia = %Person{age: 22, name: "Silvia"}
assert Map.fetch!(silvia, :age) == :__

View File

@@ -1,84 +1,71 @@
defmodule PatternMatching do
use Koans
koan "one matches one" do
koan "One matches one" do
assert match?(1, :__)
end
koan "a pattern can change" do
koan "A pattern can change" do
a = 1
assert a = :__
end
# TODO not sure about this koan?
koan "a pattern can also be strict" do
koan "A pattern can also be strict" do
a = 1
assert ^a = :__
end
koan "patterns can be used to pull things apart" do
[head | _tail] = [1,2,3,4]
koan "Patterns can be used to pull things apart" do
[head | tail] = [1,2,3,4]
assert head == :__
end
koan "...whichever side you actually need" do
[_head | tail] = [1,2,3,4]
assert tail == :__
end
koan "and then put them back together" do
koan "And then put them back together" do
head = 1
tail = [2,3,4]
assert :__ == [head | tail]
end
koan "Some values can be irrelevant" do
koan "Some values can be ignored" do
[_first, _second, third, _fourth] = [1,2,3,4]
assert third == :__
end
koan "strings come apart just a easily" do
koan "Strings come apart just a easily" do
"Shopping list: " <> items = "Shopping list: eggs, milk"
assert items == :__
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"}
assert make == :__
end
koan "the pattern can make assertions about what it expects" do
assert match?([1, _, _], :__)
koan "The pattern can make assertions about what it expects" do
assert match?([1, _second, _third], :__)
end
def make_noise(%{type: "cat"}), do: "Meow"
def make_noise(%{type: "dog"}), do: "Woof"
def make_noise(_anything), do: "Eh?"
koan "functions can declare what kind of arguments they accept" do
koan "Functions can declare what kind of arguments they accept" do
dog = %{type: "dog", legs: 4, age: 9, color: "brown"}
cat = %{type: "cat", legs: 4, age: 3, color: "grey"}
snake = %{type: "snake", legs: 0, age: 20, color: "black"}
assert make_noise(dog) == :__
end
koan "...and for cats..." do
cat = %{type: "cat", legs: 4, age: 3, color: "grey"}
assert make_noise(cat) == :__
end
koan "...and for snakes..." do
snake = %{type: "snake", legs: 0, age: 20, color: "black"}
assert make_noise(snake) == :__
end
koan "errors are shaped differently than sucessful results" do
koan "Errors are shaped differently than sucessful results" do
result = case Map.fetch(%{}, :obviously_not_a_key) do
:error -> "not present"
_ -> flunk("I should not happen")

View File

@@ -1,20 +1,20 @@
defmodule Functions do
use Koans
def inside() do
:light
def greet(name) do
"Hello, #{name}!"
end
# A function starts with 'def', has a 'do-end' pair
koan "it returns the last statement that was called" do
assert inside() == :__
koan "Functions take arguments and return values" do
assert greet("World") == :__
end
def quick_inline_product(a, b), do: a * b
koan "Short functions can be defined in a single line, but mind the comman and colon!" do
koan "Short functions can be defined in a single line, but mind the comman and colon" do
assert quick_inline_product(2,:__) == 6
end
# A function can have an argument between parentheses, after the name
def will_change(choice) do
if choice do
:it_was_truthy
@@ -23,11 +23,8 @@ defmodule Functions do
end
end
koan "Can return atoms..." do
koan "Functions can return different things" do
assert will_change(true) == :__
end
koan "..or strings from the same function!" do
assert will_change(false) == :__
end
@@ -49,37 +46,35 @@ defmodule Functions do
def first(foo, bar), do: "#{foo} and #{bar}"
def first(foo), do: "only #{foo}"
koan "functions with the same name are distinguished by arity" do
koan "Functions with the same name are distinguished by the number of arguments they take" do
assert first("One", "Two") == :__
end
koan "the name stays - the number of arguments varies" do
assert first("One") == :__
end
def sum_up(thing) when is_list(thing), do: :entire_list
def sum_up(_thing), do: :single_thing
koan "You can 'guard' functions from their arguments" do
assert sum_up([1,2,3]) == :__
end
koan "no guard means just that - anything" do
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 "You can also create intricate guards based on the values..." do
koan "You can also create intricate guards based on the values" do
assert bigger(10, 5) == :__
end
koan "...to make the body of the function clearer" do
assert bigger(4, 27) == :__
end
def the_length(0), do: "It was zero"
def the_length(number), do: "The length was #{number}"
koan "You can also 'guard' with concrete values" do
assert the_length(0) == :__
end
koan "Or just let the argument roll" do
assert the_length(5) == :__
end
@@ -101,11 +96,12 @@ defmodule Functions do
def multiply_then_call(number, fun), do: fun.(number*5)
def square(number), do: number * number
koan "You can 'capture' functions if you want to pass them around as values" do
koan "You can 'capture' functions if you want to pass them around as values. Mind the ampersand '&' and the slash followed by the number of args" do
assert multiply_then_call(2, &square/1) == :__
end
koan "functions can be combined elegantly with the pipe operator" do
koan "Functions can be combined elegantly with the pipe operator" do
result = "full-name"
|> String.split("-")
|> Enum.map(&(String.capitalize(&1)))

View File

@@ -1,32 +1,38 @@
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,4]) == :__
koan "Knowing how many elements are in a list is important for book-keeping" do
assert Enum.count([1,2,3]) == :__
end
koan "..the same applies for counting elements in a map..." do
assert Enum.count(%{ :a => 1, :b => 2, :c => 3, :d => 4}) == :__
koan "The same applies for counting elements in a map" do
assert Enum.count(%{ :a => :foo, :b => :bar}) == :__
end
koan "..or a keyword list..." do
assert Enum.count([a: 1, b: 2, c: 3, d: 4]) == :__
koan "Or a keyword list" do
assert Enum.count([a: 77, b: 23, c: 12, d: 33, e: 90, f: 113]) == :__
end
def less_than_five?(n), do: n < 5
koan "Elements can have a lot in common" do
assert Enum.all?([1,2,3], fn element -> element < 5 end) == :__
assert Enum.all?([1,2,3], &less_than_five?/1) == :__
end
def less_than_two?(n), do: n < 2
koan "If one if different, all elements are not alike" do
assert Enum.all?([1, 2, 3], fn element -> element <= 2 end) == :__
assert Enum.all?([1, 2, 3, 2], &less_than_two?/1) == :__
end
koan "sometimes you you just want to know if there are any elements with a certain trait" do
assert Enum.any?([1,2,3], fn element -> rem(element, 2) == 0 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) == :__
end
def divisible_by_five?(n), do: rem(n, 5) == 0
koan "if not a single element fits the bill, any? returns false" do
assert Enum.any?([1,2,3], fn element -> rem(element, 5) == 0 end) == :__
assert Enum.any?([1,2,3], &divisible_by_five?/1) == :__
end
koan "Sometimes you just want to know if an element is part of the party" do
@@ -37,26 +43,30 @@ defmodule Enums do
assert Enum.member?([1,2,3], 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], fn element -> element * 10 end) == :__
assert Enum.map([1,2,3], &multiply_by_ten/1) == :__
end
koan "You can even return a list with entirely different types" do
assert Enum.map([1,2,3], fn element -> rem(element, 2) == 0 end) == :__
assert Enum.map([1,2,3], &even?/1) == :__
end
koan "But keep in mind that the original list remains unchanged" do
input = [1,2,3]
assert Enum.map(input, fn element -> rem(element, 2) == 0 end) == [false, true, false]
input = [1,2,3,4]
assert Enum.map(input, &even?/1) == :__
assert input == :__
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], fn element -> rem(element, 2) == 1 end) == :__
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], fn element -> rem(element, 2) == 1 end) == :__
koan "Reject will help you throw out unwanted cruft" do
assert Enum.reject([1,2,3], &odd?/1) == :__
end
koan "You three there, follow me!" do
@@ -68,15 +78,16 @@ defmodule Enums do
end
koan "Take what you can..." do
assert Enum.take_while([1,2,3,4,5], fn element -> element < 4 end) == :__
assert Enum.take_while([1,2,3,4,5,6,7], &less_than_five?/1) == :__
end
koan "Just like taking, you can also drop elements" do
assert Enum.drop([-1,0,1,2,3], 2) == :__
end
def negative?(n), do: n < 0
koan "Drop elements until you are happy" do
assert Enum.drop_while([-1,0,1,2,3], fn element -> element <= 0 end) == :__
assert Enum.drop_while([-1,0,1,2,3], &negative?/1) == :__
end
koan "Forming groups makes uns stronger" do
@@ -87,7 +98,6 @@ defmodule Enums do
koan "You get as many groups as you can have different results" do
assert Enum.group_by([1,2,3,4,5,6], fn element -> rem(element, 3) end) == :__
end
koan "Zip-up in pairs!" do
@@ -103,15 +113,15 @@ defmodule Enums do
end
koan "When you want to find that one pesky element" do
assert Enum.find([1,2,3], fn element -> rem(element,2) == 0 end) == :__
assert Enum.find([1,2,3], &even?/1) == :__
end
koan "...but you don't quite find it..." do
assert Enum.find([1,2,3], fn element -> rem(element,5) == 0 end) == :__
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, fn element -> rem(element,5) == 0 end) == :__
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

View File

@@ -1,22 +1,22 @@
defmodule Processes do
use Koans
koan "tests run in a process!" do
assert Process.alive?(:__)
koan "Tests run in a process" do
assert Process.alive?(self()) == :__
end
koan "can spew out information about a process" do
information = Process.info(self)
koan "You can ask a process to introduce itself" do
information = Process.info(self())
assert information[:status] == :__
end
koan "process can send messages to itself" do
koan "You can send messages to any process you want" do
send self(), "hola!"
assert_receive :__
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
pid = spawn(fn -> receive do
{:hello, sender} -> send sender, :how_are_you?
_ -> assert false
@@ -27,7 +27,7 @@ defmodule Processes do
assert_receive :__
end
koan "you don't have to wait forever for messages" do
koan "Waiting for a message can get boring" do
parent = self()
spawn(fn -> receive do
_anything -> flunk "I really wasn't expecting messages"
@@ -39,20 +39,21 @@ defmodule Processes do
assert_receive :__
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)
:timer.sleep(500)
assert Process.alive?(pid) == :__
end
koan "killing a process kills it for good" do
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) == :__
end
koan "can trap a signal in a child process" do
koan "Trapping will allow you to react to someone terminating the process" do
parent = self()
pid = spawn(fn ->
Process.flag(:trap_exit, true)
@@ -67,7 +68,7 @@ defmodule Processes do
assert_receive :__
end
koan "quitting normally has no effect" do
koan "Trying to quit normally has no effect" do
pid = spawn(fn -> receive do
end
end)
@@ -75,7 +76,7 @@ defmodule Processes do
assert Process.alive?(pid) == :__
end
koan "quititing your own process normally does terminate it though" do
koan "Exiting yourself on the other hand DOES terminate you" do
pid = spawn(fn -> receive do
:bye -> Process.exit(self(), :normal)
end
@@ -86,7 +87,7 @@ defmodule Processes do
assert Process.alive?(pid) == :__
end
koan "linked processes are informed about exit signals of children when trapping those signals" do
koan "Parent processes can be informed about exiting children, if they trap and link" do
parent = self()
spawn(fn ->
Process.flag(:trap_exit, true)
@@ -99,7 +100,7 @@ defmodule Processes do
assert_receive :__
end
koan "monitoring processes are informed via messages without having trapping" do
koan "If you monitor your children, you'll be automatically informed for their depature" do
parent = self()
spawn(fn ->
spawn_monitor(fn -> Process.exit(self(), :normal) end)

View File

@@ -7,12 +7,12 @@ defmodule Tasks do
assert Task.await(task) + 1 == :__
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)
assert result == :__
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
handle = Task.async(fn ->
:timer.sleep(100)
3 * 3
@@ -20,7 +20,7 @@ defmodule Tasks do
assert Task.yield(handle, 10) == :__
end
koan "tasks can be aborted with shutdown" do
koan "Tasks can be aborted with shutdown" do
handle = Task.async(fn ->
:timer.sleep(100)
3 * 3
@@ -34,7 +34,7 @@ defmodule Tasks do
assert Task.shutdown(handle) == {:ok, :__}
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
squares = [1,2,3,4]
|> Enum.map(fn(number) -> Task.async(fn -> number * number end) end)
|> Task.yield_many(100)

View File

@@ -110,9 +110,9 @@ defmodule KoansHarnessTest do
nil,
"Joe",
33,
23,
{:multiple, [33, 23]},
22,
true,
{:multiple, [true, false]},
22,
]
@@ -124,16 +124,13 @@ defmodule KoansHarnessTest do
1,
2,
1,
1,
[2,3,4],
{:multiple, [1, [2,3,4]]},
[1,2,3,4],
3,
"eggs, milk",
"Honda",
[1,2,3],
"Woof",
"Meow",
"Eh?",
{:multiple, ["Woof", "Meow", "Eh?",]},
"not present"
]
@@ -142,18 +139,14 @@ defmodule KoansHarnessTest do
test "Functions" do
answers = [
:light,
"Hello, World!",
3,
:it_was_truthy,
"It really wasn't",
{:multiple, [:it_was_truthy, "It really wasn't"]},
"Hello Hello Hello ",
"Hello Hello Hello Hello Hello ",
"One and Two",
"only One",
:entire_list,
:single_thing,
"10 is bigger than 5",
"4 is not bigger than 27",
{:multiple, ["One and Two", "only One"]},
{:multiple, [:entire_list, :single_thing]},
{:multiple, ["10 is bigger than 5", "4 is not bigger than 27"]},
"It was zero",
"The length was 5",
6,
@@ -168,9 +161,9 @@ defmodule KoansHarnessTest do
test "Enums" do
answers = [
4,
4,
4,
3,
2,
6,
true,
false,
true,
@@ -179,14 +172,14 @@ defmodule KoansHarnessTest do
false,
[10,20,30],
[false, true, false],
[1,2,3],
{:multiple, [ [false, true, false, true], [1,2,3,4] ] },
[1,3],
[2],
[1,2,3],
[1,2,3,4,5],
[1,2,3,4],
[1,2,3],
[1,2,3],
[1,2,3],
[0,1,2,3],
%{ :odd => [3,1], :even => [4,2] },
%{ 0 => [6, 3], 1 => [4, 1], 2 => [5, 2]},
[{1, :a}, {2, :b}, {3, :c}],
@@ -202,13 +195,13 @@ defmodule KoansHarnessTest do
test "Processes" do
answers = [
self,
true,
:running,
"hola!",
:how_are_you?,
{:waited_too_long, "I am inpatient"},
false,
false,
{:multiple, [true, false]},
{:exited, :random_reason},
true,
false,