trackler 2.0.8.11 → 2.0.8.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|