trackler 2.0.8.11 → 2.0.8.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/common/README.md +70 -15
- data/common/canonical-schema.json +137 -0
- data/lib/trackler/version.rb +1 -1
- data/tracks/elixir/config.json +7 -0
- data/tracks/elixir/exercises/simple-linked-list/example.exs +86 -0
- data/tracks/elixir/exercises/simple-linked-list/linked_list.exs +83 -0
- data/tracks/elixir/exercises/simple-linked-list/linked_list_test.exs +154 -0
- data/tracks/factor/README.md +0 -6
- data/tracks/factor/config.json +13 -3
- data/tracks/factor/docs/INSTALLATION.md +26 -29
- data/tracks/factor/exercises/hello-world/hello-world-example.factor +2 -2
- data/tracks/factor/exercises/leap/leap-example.factor +9 -0
- data/tracks/factor/exercises/leap/leap-tests.factor +32 -0
- data/tracks/go/exercises/phone-number/phone_number_test.go +5 -2
- data/tracks/go/exercises/pig-latin/example.go +2 -0
- data/tracks/go/exercises/pig-latin/pig_latin_test.go +8 -0
- data/tracks/java/config.json +5 -0
- data/tracks/java/exercises/anagram/src/test/java/AnagramTest.java +14 -0
- data/tracks/java/exercises/ocr-numbers/build.gradle +17 -0
- data/tracks/java/exercises/ocr-numbers/src/example/java/Digit.java +63 -0
- data/tracks/java/exercises/ocr-numbers/src/example/java/OpticalCharacterReader.java +67 -0
- data/tracks/java/exercises/ocr-numbers/src/main/java/OpticalCharacterReader.java +5 -0
- data/tracks/java/exercises/ocr-numbers/src/test/java/OpticalCharacterReaderTest.java +248 -0
- data/tracks/java/exercises/perfect-numbers/src/example/java/NaturalNumber.java +1 -1
- data/tracks/java/exercises/perfect-numbers/src/test/java/NaturalNumberTest.java +52 -5
- data/tracks/java/exercises/settings.gradle +1 -0
- data/tracks/java/img/icon.png +0 -0
- data/tracks/javascript/exercises/phone-number/phone-number.spec.js +22 -2
- data/tracks/julia/exercises/bob/example.jl +1 -1
- data/tracks/julia/exercises/custom-set/HINTS.md +2 -0
- data/tracks/julia/exercises/custom-set/runtests.jl +2 -2
- data/tracks/julia/img/{logo.png → icon.png} +0 -0
- data/tracks/julia/img/{logo.svg → icon.svg} +0 -0
- data/tracks/prolog/README.md +6 -2
- data/tracks/prolog/config.json +1 -1
- data/tracks/prolog/img/icon.png +0 -0
- data/tracks/scala/exercises/simple-linked-list/build.sbt +3 -0
- data/tracks/vimscript/README.md +7 -0
- data/tracks/vimscript/img/icon.png +0 -0
- metadata +17 -5
- data/tracks/vimscript/img/.keep +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b091050fe3cc2ae73ee5a8b167c29a75da6b27e
|
4
|
+
data.tar.gz: 49cb81538e56408fc123e98514ce483560c911a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b8e27dc574836d71a6cb2755b3d314c343670c4b5e72b7e27318790e1b01443804da89aa3cffe814f63c24bea448fcc67442b9c72378abb5aab7cda3872cd87d
|
7
|
+
data.tar.gz: beaf66dfdaf976e94aa2afa88d7851295a3f6a414cd46467a46cf73788f84700f00e402be3e29b8947da4e5813cefd79ee8edcba0c3ef46ed5faf771a630ce4f
|
data/common/README.md
CHANGED
@@ -36,21 +36,76 @@ There are three metadata files:
|
|
36
36
|
## Test Data Format (canonical-data.json)
|
37
37
|
|
38
38
|
This data can be incorporated into test programs manually or extracted by a
|
39
|
-
program. The file
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
39
|
+
program. The file format is described in `canonical-schema.json`, but it
|
40
|
+
is easier to understand with a example:
|
41
|
+
|
42
|
+
```json
|
43
|
+
{ "exercise": "foobar"
|
44
|
+
, "version" : "1.0.0"
|
45
|
+
, "comments":
|
46
|
+
[ " Comments are always optional and can be used almost anywhere. "
|
47
|
+
, " "
|
48
|
+
, " They usually document how the exercise's readme ('description.md') "
|
49
|
+
, " is generally interpreted in test programs across different "
|
50
|
+
, " languages. "
|
51
|
+
, " "
|
52
|
+
, " In addition to a mainstream implementation path, this information "
|
53
|
+
, " can also document significant variations. "
|
54
|
+
]
|
55
|
+
, "cases":
|
56
|
+
[ { "comments":
|
57
|
+
[ " A test case must have a 'description' and a 'property'. "
|
58
|
+
, " Anything else is optional. "
|
59
|
+
, " "
|
60
|
+
, " The 'property' is a string in lowerCamelCase identifying "
|
61
|
+
, " the type of test, but most of the times it is just the "
|
62
|
+
, " name of a function being tested. "
|
63
|
+
, " "
|
64
|
+
, " Test cases can have any number of additional keys, and "
|
65
|
+
, " most of them also have an 'expected' one, defining the "
|
66
|
+
, " value a test should return. "
|
67
|
+
]
|
68
|
+
, "description": "Foo'ing a word returns it reversed"
|
69
|
+
, "property" : "foo"
|
70
|
+
, "input" : "lion"
|
71
|
+
, "expected" : "noil"
|
72
|
+
}
|
73
|
+
, { "description": "Bar'ing a name returns its parts combined"
|
74
|
+
, "property" : "bar"
|
75
|
+
, "firstName" : "Alan"
|
76
|
+
, "lastName" : "Smithee"
|
77
|
+
, "expected" : "ASlmainthee"
|
78
|
+
}
|
79
|
+
, { "comments":
|
80
|
+
[ " Test cases can be arbitrarily grouped with a description "
|
81
|
+
, " to make organization easier. "
|
82
|
+
]
|
83
|
+
, "description": "Abnormal inputs: numbers"
|
84
|
+
, "cases":
|
85
|
+
[ { "description": "Foo'ing a number returns nothing"
|
86
|
+
, "property" : "foo"
|
87
|
+
, "input" : "42"
|
88
|
+
, "expected" : null
|
89
|
+
}
|
90
|
+
, { "description": "Bar'ing a name with numbers gives an error"
|
91
|
+
, "property" : "bar"
|
92
|
+
, "firstName" : "HAL"
|
93
|
+
, "lastName" : "9000"
|
94
|
+
, "expected" : { "error": "You should never bar a number" }
|
95
|
+
}
|
96
|
+
]
|
97
|
+
}
|
98
|
+
]
|
99
|
+
}
|
100
|
+
|
101
|
+
```
|
102
|
+
|
103
|
+
Keep in mind that the description should not simply explain **what** each case
|
104
|
+
is (that is redundant information) but also **why** each case is there. For
|
105
|
+
example, what kinds of implementation mistakes might this case help us find?
|
106
|
+
|
107
|
+
There are also some convention about `expected` that you must follow:
|
108
|
+
|
54
109
|
- if the input is valid but there is no result for the input, the value at `"expected"` should be `null`.
|
55
110
|
- if an error is expected (because the input is invalid, or any other reason), the value at `"expected"` should be an object containing exactly one property, `"error"`, whose value is a string.
|
56
111
|
- The string should explain why the error would occur.
|
@@ -0,0 +1,137 @@
|
|
1
|
+
{
|
2
|
+
"comments":
|
3
|
+
[ " This is a JSON Schema for 'canonical-data.json' files. "
|
4
|
+
, " "
|
5
|
+
, " It enforces just a general structure for all exercises, "
|
6
|
+
, " without specifying how the test data should be organized "
|
7
|
+
, " for each type of test. We do this to keep generality and "
|
8
|
+
, " allow support for tests the do not fit well in the "
|
9
|
+
, " 'function (input) == output' structure, like property "
|
10
|
+
, " tests. "
|
11
|
+
, " "
|
12
|
+
, " The only thing enforced regarding how test data should be "
|
13
|
+
, " structured is the error encoding, because it was agreed "
|
14
|
+
, " and it doesn't restrict flexibility in a significant way. "
|
15
|
+
, " "
|
16
|
+
, " Standardized property names may help when automatically "
|
17
|
+
, " deriving JSON parsers in some languages, so we followed "
|
18
|
+
, " a few conventions from the 'Google JSON Style Guide'. "
|
19
|
+
, " "
|
20
|
+
, " Additionally, this schema strictly enforces letters, in "
|
21
|
+
, " lowerCamelCase, for naming the 'property' being tested. We "
|
22
|
+
, " expect this regularity will allow an easier automatic "
|
23
|
+
, " generation of function's names in test generators, "
|
24
|
+
, " slightly reducing the amount of manually generated code. "
|
25
|
+
],
|
26
|
+
|
27
|
+
"$schema": "http://json-schema.org/draft-04/schema#",
|
28
|
+
|
29
|
+
"self": { "vendor" : "io.exercism"
|
30
|
+
, "name" : "canonical-data"
|
31
|
+
, "format" : "jsonschema"
|
32
|
+
, "version": "1-0-0"
|
33
|
+
},
|
34
|
+
|
35
|
+
"$ref": "#/definitions/canonicalData",
|
36
|
+
|
37
|
+
"definitions":{
|
38
|
+
|
39
|
+
"canonicalData":
|
40
|
+
{ "description": "This is the top-level file structure"
|
41
|
+
, "type" : "object"
|
42
|
+
, "required" : ["exercise" , "version", "cases"]
|
43
|
+
, "properties" :
|
44
|
+
{ "exercise" : { "$ref": "#/definitions/exercise" }
|
45
|
+
, "version" : { "$ref": "#/definitions/version" }
|
46
|
+
, "comments" : { "$ref": "#/definitions/comments" }
|
47
|
+
, "cases" : { "$ref": "#/definitions/testGroup" }
|
48
|
+
}
|
49
|
+
, "additionalProperties": false
|
50
|
+
},
|
51
|
+
|
52
|
+
"exercise":
|
53
|
+
{ "description": "Exercise's slug (kebab-case)"
|
54
|
+
, "type" : "string"
|
55
|
+
, "pattern" : "^[a-z]+(-[a-z]+)*$"
|
56
|
+
},
|
57
|
+
|
58
|
+
"version" :
|
59
|
+
{ "description" : "Semantic versioning: MAJOR.MINOR.PATCH"
|
60
|
+
, "type" : "string"
|
61
|
+
, "pattern" : "^(0|[1-9][0-9]*)(\\.(0|[1-9][0-9]*)){2}$"
|
62
|
+
},
|
63
|
+
|
64
|
+
"comments":
|
65
|
+
{ "description": "An array of strings to fake multi-line comments"
|
66
|
+
, "type" : "array"
|
67
|
+
, "items" : { "type": "string" }
|
68
|
+
, "minItems" : 1
|
69
|
+
},
|
70
|
+
|
71
|
+
"testGroup":
|
72
|
+
{ "description": "An array of labeled test items"
|
73
|
+
, "type" : "array"
|
74
|
+
, "items" : { "$ref": "#/definitions/labeledTestItem" }
|
75
|
+
, "minItems" : 1
|
76
|
+
},
|
77
|
+
|
78
|
+
"labeledTestItem":
|
79
|
+
{ "description": "A single test or group of tests with a description"
|
80
|
+
, "oneOf": [ { "$ref": "#/definitions/labeledTest" }
|
81
|
+
, { "$ref": "#/definitions/labeledTestGroup" }
|
82
|
+
]
|
83
|
+
},
|
84
|
+
|
85
|
+
"labeledTest":
|
86
|
+
{ "description": "A single test with a description"
|
87
|
+
, "type" : "object"
|
88
|
+
, "required" : ["description", "property"]
|
89
|
+
, "properties" :
|
90
|
+
{ "description": { "$ref": "#/definitions/description" }
|
91
|
+
, "comments" : { "$ref": "#/definitions/comments" }
|
92
|
+
, "property" : { "$ref": "#/definitions/property" }
|
93
|
+
, "expected" : { "$ref": "#/definitions/expected" }
|
94
|
+
}
|
95
|
+
},
|
96
|
+
|
97
|
+
"labeledTestGroup":
|
98
|
+
{ "description": "A group of tests with a description"
|
99
|
+
, "type" : "object"
|
100
|
+
, "required" : ["description", "cases"]
|
101
|
+
, "properties" :
|
102
|
+
{ "description": { "$ref": "#/definitions/description" }
|
103
|
+
, "comments" : { "$ref": "#/definitions/comments" }
|
104
|
+
, "cases" : { "$ref": "#/definitions/testGroup" }
|
105
|
+
}
|
106
|
+
, "additionalProperties": false
|
107
|
+
},
|
108
|
+
|
109
|
+
"description":
|
110
|
+
{ "description": "A short, clear, one-line description"
|
111
|
+
, "type" : "string"
|
112
|
+
},
|
113
|
+
|
114
|
+
"property":
|
115
|
+
{ "description": "A letters-only, lowerCamelCase property name"
|
116
|
+
, "type" : "string"
|
117
|
+
, "pattern" : "^[a-z]+([A-Z][a-z]+)*[A-Z]?$"
|
118
|
+
},
|
119
|
+
|
120
|
+
"expected":
|
121
|
+
{ "description": "The expected return value of a test case"
|
122
|
+
, "properties":
|
123
|
+
{ "error": { "$ref": "#/definitions/error" }
|
124
|
+
}
|
125
|
+
, "dependencies":
|
126
|
+
{ "error": { "maxProperties": 1 }
|
127
|
+
}
|
128
|
+
},
|
129
|
+
|
130
|
+
"error":
|
131
|
+
{ "description": "A message describing an error condition"
|
132
|
+
, "type" : "string"
|
133
|
+
}
|
134
|
+
|
135
|
+
}
|
136
|
+
|
137
|
+
}
|
data/lib/trackler/version.rb
CHANGED
data/tracks/elixir/config.json
CHANGED
@@ -0,0 +1,86 @@
|
|
1
|
+
defmodule LinkedList do
|
2
|
+
@opaque t :: tuple()
|
3
|
+
|
4
|
+
@doc """
|
5
|
+
Construct a new LinkedList
|
6
|
+
"""
|
7
|
+
@spec new() :: t
|
8
|
+
def new() do
|
9
|
+
{}
|
10
|
+
end
|
11
|
+
|
12
|
+
@doc """
|
13
|
+
Push an item onto a LinkedList
|
14
|
+
"""
|
15
|
+
@spec push(t, any()) :: t
|
16
|
+
def push(list, elem) do
|
17
|
+
{elem, list}
|
18
|
+
end
|
19
|
+
|
20
|
+
@doc """
|
21
|
+
Calculate the length of a LinkedList
|
22
|
+
"""
|
23
|
+
@spec length(t) :: non_neg_integer()
|
24
|
+
def length(list) do
|
25
|
+
count_length(list, 0)
|
26
|
+
end
|
27
|
+
|
28
|
+
defp count_length({}, n), do: n
|
29
|
+
defp count_length({_, t}, n), do: count_length(t, n + 1)
|
30
|
+
|
31
|
+
@doc """
|
32
|
+
Determine if a LinkedList is empty
|
33
|
+
"""
|
34
|
+
@spec empty?(t) :: boolean()
|
35
|
+
def empty?({}), do: true
|
36
|
+
def empty?(_), do: false
|
37
|
+
|
38
|
+
@doc """
|
39
|
+
Get the value of a head of the LinkedList
|
40
|
+
"""
|
41
|
+
@spec peek(t) :: {:ok, any()} | {:error, :empty_list}
|
42
|
+
def peek({}), do: {:error, :empty_list}
|
43
|
+
def peek({x, _}), do: {:ok, x}
|
44
|
+
|
45
|
+
@doc """
|
46
|
+
Get tail of a LinkedList
|
47
|
+
"""
|
48
|
+
@spec tail(t) :: {:ok, t} | {:error, :empty_list}
|
49
|
+
def tail({}), do: {:error, :empty_list}
|
50
|
+
def tail({_, t}), do: {:ok, t}
|
51
|
+
|
52
|
+
@doc """
|
53
|
+
Remove the head from a LinkedList
|
54
|
+
"""
|
55
|
+
@spec pop(t) :: {:ok, any(), t} | {:error, :empty_list}
|
56
|
+
def pop({}), do: {:error, :empty_list}
|
57
|
+
def pop({h, t}), do: {:ok, h, t}
|
58
|
+
|
59
|
+
@doc """
|
60
|
+
Construct a LinkedList from a stdlib List
|
61
|
+
"""
|
62
|
+
@spec from_list(list()) :: t
|
63
|
+
def from_list(list) do
|
64
|
+
List.foldr(list, new(), &push(&2, &1))
|
65
|
+
end
|
66
|
+
|
67
|
+
@doc """
|
68
|
+
Construct a stdlib List LinkedList from a LinkedList
|
69
|
+
"""
|
70
|
+
@spec to_list(t) :: list()
|
71
|
+
def to_list(list) do
|
72
|
+
list |> do_to_list([]) |> Enum.reverse()
|
73
|
+
end
|
74
|
+
defp do_to_list({}, acc), do: acc
|
75
|
+
defp do_to_list({h, t}, acc), do: do_to_list(t, [h|acc])
|
76
|
+
|
77
|
+
@doc """
|
78
|
+
Reverse a LinkedList
|
79
|
+
"""
|
80
|
+
@spec reverse(t) :: t
|
81
|
+
def reverse(list) do
|
82
|
+
do_reverse(list, new())
|
83
|
+
end
|
84
|
+
def do_reverse({}, acc), do: acc
|
85
|
+
def do_reverse({h, t}, acc), do: do_reverse(t, push(acc, h))
|
86
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
defmodule LinkedList do
|
2
|
+
@opaque t :: tuple()
|
3
|
+
|
4
|
+
@doc """
|
5
|
+
Construct a new LinkedList
|
6
|
+
"""
|
7
|
+
@spec new() :: t
|
8
|
+
def new() do
|
9
|
+
# Your implementation here...
|
10
|
+
end
|
11
|
+
|
12
|
+
@doc """
|
13
|
+
Push an item onto a LinkedList
|
14
|
+
"""
|
15
|
+
@spec push(t, any()) :: t
|
16
|
+
def push(list, elem) do
|
17
|
+
# Your implementation here...
|
18
|
+
end
|
19
|
+
|
20
|
+
@doc """
|
21
|
+
Calculate the length of a LinkedList
|
22
|
+
"""
|
23
|
+
@spec length(t) :: non_neg_integer()
|
24
|
+
def length(list) do
|
25
|
+
# Your implementation here...
|
26
|
+
end
|
27
|
+
|
28
|
+
@doc """
|
29
|
+
Determine if a LinkedList is empty
|
30
|
+
"""
|
31
|
+
@spec empty?(t) :: boolean()
|
32
|
+
def empty?(list) do
|
33
|
+
# Your implementation here...
|
34
|
+
end
|
35
|
+
|
36
|
+
@doc """
|
37
|
+
Get the value of a head of the LinkedList
|
38
|
+
"""
|
39
|
+
@spec peek(t) :: {:ok, any()} | {:error, :empty_list}
|
40
|
+
def peek(list) do
|
41
|
+
# Your implementation here...
|
42
|
+
end
|
43
|
+
|
44
|
+
@doc """
|
45
|
+
Get tail of a LinkedList
|
46
|
+
"""
|
47
|
+
@spec tail(t) :: {:ok, t} | {:error, :empty_list}
|
48
|
+
def tail(list) do
|
49
|
+
# Your implementation here...
|
50
|
+
end
|
51
|
+
|
52
|
+
@doc """
|
53
|
+
Remove the head from a LinkedList
|
54
|
+
"""
|
55
|
+
@spec pop(t) :: {:ok, any(), t} | {:error, :empty_list}
|
56
|
+
def pop(list) do
|
57
|
+
# Your implementation here...
|
58
|
+
end
|
59
|
+
|
60
|
+
@doc """
|
61
|
+
Construct a LinkedList from a stdlib List
|
62
|
+
"""
|
63
|
+
@spec from_list(list()) :: t
|
64
|
+
def from_list(list) do
|
65
|
+
# Your implementation here...
|
66
|
+
end
|
67
|
+
|
68
|
+
@doc """
|
69
|
+
Construct a stdlib List LinkedList from a LinkedList
|
70
|
+
"""
|
71
|
+
@spec to_list(t) :: list()
|
72
|
+
def to_list(list) do
|
73
|
+
# Your implementation here...
|
74
|
+
end
|
75
|
+
|
76
|
+
@doc """
|
77
|
+
Reverse a LinkedList
|
78
|
+
"""
|
79
|
+
@spec reverse(t) :: t
|
80
|
+
def reverse(list) do
|
81
|
+
# Your implementation here...
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
if !System.get_env("EXERCISM_TEST_EXAMPLES") do
|
2
|
+
Code.load_file("linked_list.exs", __DIR__)
|
3
|
+
end
|
4
|
+
|
5
|
+
ExUnit.start
|
6
|
+
ExUnit.configure exclude: :pending, trace: true
|
7
|
+
|
8
|
+
defmodule LinkedListTest do
|
9
|
+
use ExUnit.Case
|
10
|
+
|
11
|
+
test "length/1 of new list" do
|
12
|
+
list = LinkedList.new()
|
13
|
+
assert LinkedList.length(list) == 0
|
14
|
+
end
|
15
|
+
|
16
|
+
@tag :pending
|
17
|
+
test "empty?/1 of new list" do
|
18
|
+
list = LinkedList.new()
|
19
|
+
assert LinkedList.empty?(list)
|
20
|
+
end
|
21
|
+
|
22
|
+
@tag :pending
|
23
|
+
test "length/1 of list of 1 datum" do
|
24
|
+
list = LinkedList.new() |> LinkedList.push(10)
|
25
|
+
assert LinkedList.length(list) == 1
|
26
|
+
end
|
27
|
+
|
28
|
+
@tag :pending
|
29
|
+
test "empty?/1 of list of 1 datum" do
|
30
|
+
list = LinkedList.new() |> LinkedList.push(20)
|
31
|
+
refute LinkedList.empty?(list)
|
32
|
+
end
|
33
|
+
|
34
|
+
@tag :pending
|
35
|
+
test "peek/1 of list of 1 datum" do
|
36
|
+
list = LinkedList.new() |> LinkedList.push(20)
|
37
|
+
assert LinkedList.peek(list) == {:ok, 20}
|
38
|
+
end
|
39
|
+
|
40
|
+
@tag :pending
|
41
|
+
test "peek/1 of list of empty list" do
|
42
|
+
list = LinkedList.new()
|
43
|
+
assert LinkedList.peek(list) == {:error, :empty_list}
|
44
|
+
end
|
45
|
+
|
46
|
+
@tag :pending
|
47
|
+
test "tail/1 of empty list" do
|
48
|
+
list = LinkedList.new()
|
49
|
+
assert {:error, :empty_list} = LinkedList.tail(list)
|
50
|
+
end
|
51
|
+
|
52
|
+
@tag :pending
|
53
|
+
test "tail/1 of list of 1 datum" do
|
54
|
+
list = LinkedList.new() |> LinkedList.push(:hello)
|
55
|
+
assert {:ok, tail} = LinkedList.tail(list)
|
56
|
+
assert LinkedList.peek(tail) == {:error, :empty_list}
|
57
|
+
end
|
58
|
+
|
59
|
+
@tag :pending
|
60
|
+
test "pushed items are stacked" do
|
61
|
+
list =
|
62
|
+
LinkedList.new()
|
63
|
+
|> LinkedList.push(:a)
|
64
|
+
|> LinkedList.push(:b)
|
65
|
+
assert LinkedList.peek(list) == {:ok, :b}
|
66
|
+
assert {:ok, list} = LinkedList.tail(list)
|
67
|
+
assert LinkedList.peek(list) == {:ok, :a}
|
68
|
+
assert {:ok, list} = LinkedList.tail(list)
|
69
|
+
assert LinkedList.peek(list) == {:error, :empty_list}
|
70
|
+
end
|
71
|
+
|
72
|
+
@tag :pending
|
73
|
+
test "push 10 times" do
|
74
|
+
list = Enum.reduce(1..10, LinkedList.new(), &LinkedList.push(&2, &1))
|
75
|
+
assert LinkedList.peek(list) == {:ok, 10}
|
76
|
+
assert LinkedList.length(list) == 10
|
77
|
+
end
|
78
|
+
|
79
|
+
@tag :pending
|
80
|
+
test "pop/1 of list of 1 datum" do
|
81
|
+
list = LinkedList.new() |> LinkedList.push(:a)
|
82
|
+
assert {:ok, :a, tail} = LinkedList.pop(list)
|
83
|
+
assert LinkedList.length(tail) == 0
|
84
|
+
end
|
85
|
+
|
86
|
+
@tag :pending
|
87
|
+
test "popping frenzy" do
|
88
|
+
list = Enum.reduce(11..20, LinkedList.new(), &LinkedList.push(&2, &1))
|
89
|
+
assert LinkedList.length(list) == 10
|
90
|
+
assert {:ok, 20, list} = LinkedList.pop(list)
|
91
|
+
assert {:ok, 19, list} = LinkedList.pop(list)
|
92
|
+
assert {:ok, 18, list} = LinkedList.pop(list)
|
93
|
+
assert {:ok, 17, list} = LinkedList.pop(list)
|
94
|
+
assert {:ok, 16, list} = LinkedList.pop(list)
|
95
|
+
assert {:ok, 15} = LinkedList.peek(list)
|
96
|
+
assert LinkedList.length(list) == 5
|
97
|
+
end
|
98
|
+
|
99
|
+
@tag :pending
|
100
|
+
test "from_list/1 of empty list" do
|
101
|
+
list = LinkedList.from_list([])
|
102
|
+
assert LinkedList.length(list) == 0
|
103
|
+
end
|
104
|
+
|
105
|
+
@tag :pending
|
106
|
+
test "from_list/1 of 2 element list" do
|
107
|
+
list = LinkedList.from_list([:a, :b])
|
108
|
+
assert LinkedList.length(list) == 2
|
109
|
+
assert {:ok, :a, list} = LinkedList.pop(list)
|
110
|
+
assert {:ok, :b, list} = LinkedList.pop(list)
|
111
|
+
assert {:error, :empty_list} = LinkedList.pop(list)
|
112
|
+
end
|
113
|
+
|
114
|
+
@tag :pending
|
115
|
+
test "to_list/1 of empty list" do
|
116
|
+
list = LinkedList.new()
|
117
|
+
assert LinkedList.to_list(list) == []
|
118
|
+
end
|
119
|
+
|
120
|
+
@tag :pending
|
121
|
+
test "to_list/1 of list of 1 datum" do
|
122
|
+
list = LinkedList.from_list([:mon])
|
123
|
+
assert LinkedList.to_list(list) == [:mon]
|
124
|
+
end
|
125
|
+
|
126
|
+
@tag :pending
|
127
|
+
test "to_list/1 of list of 2 datum" do
|
128
|
+
list = LinkedList.from_list([:mon, :tues])
|
129
|
+
assert LinkedList.to_list(list) == [:mon, :tues]
|
130
|
+
end
|
131
|
+
|
132
|
+
@tag :pending
|
133
|
+
test "reverse/1 of list of 2 datum" do
|
134
|
+
list = LinkedList.from_list([1, 2, 3]) |> LinkedList.reverse()
|
135
|
+
assert LinkedList.to_list(list) == [3, 2, 1]
|
136
|
+
end
|
137
|
+
|
138
|
+
@tag :pending
|
139
|
+
test "reverse/1 of list of 200 datum" do
|
140
|
+
list = Enum.to_list(1..200)
|
141
|
+
linked_list = LinkedList.from_list(list) |> LinkedList.reverse()
|
142
|
+
assert LinkedList.to_list(linked_list) == Enum.reverse(list)
|
143
|
+
end
|
144
|
+
|
145
|
+
@tag :pending
|
146
|
+
test "reverse/1 round trip" do
|
147
|
+
list = Enum.to_list(1..200)
|
148
|
+
linked_list =
|
149
|
+
LinkedList.from_list(list)
|
150
|
+
|> LinkedList.reverse()
|
151
|
+
|> LinkedList.reverse()
|
152
|
+
assert LinkedList.to_list(linked_list) == list
|
153
|
+
end
|
154
|
+
end
|