Skip to content

Commit b9c9de5

Browse files
authored
Update to Elixir 1.20 (#1635)
* fix exercises * update CI and readme * fix type warnings in tests * fix some runtime warnings * fix city office type warning
1 parent 6368638 commit b9c9de5

15 files changed

Lines changed: 45 additions & 73 deletions

File tree

.github/workflows/ci.yml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ jobs:
1717
runs-on: ubuntu-24.04
1818
strategy:
1919
matrix:
20-
elixir: [1.19.2]
21-
otp: [28.1]
20+
elixir: [1.20.1]
21+
otp: [29.0]
2222

2323
steps:
2424
- name: Checkout code
@@ -76,8 +76,6 @@ jobs:
7676
strategy:
7777
matrix:
7878
include:
79-
- elixir: '1.15.0'
80-
otp: '26.0'
8179
- elixir: '1.16.0'
8280
otp: '26.2'
8381
- elixir: '1.17.0'
@@ -86,6 +84,8 @@ jobs:
8684
otp: '27.2'
8785
- elixir: '1.19.2'
8886
otp: '28.1'
87+
- elixir: '1.20.1'
88+
otp: '29.0'
8989

9090
steps:
9191
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
@@ -121,4 +121,3 @@ jobs:
121121

122122
- name: Run Checks
123123
run: bin/ci.sh
124-

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
## Setup
1010

11-
The exercises currently target Elixir versions from 1.15 to 1.19 and Erlang/OTP versions from 25 to 27. Detailed installation instructions can be found at
11+
The exercises currently target Elixir versions from 1.16 to 1.20 and Erlang/OTP versions from 26 to 29. Detailed installation instructions can be found at
1212
[https://elixir-lang.org/install.html](https://elixir-lang.org/install.html). We recommend using the [asdf version manager](https://github.com/asdf-vm/asdf) to manage multiple Elixir versions.
1313

1414
## Testing

exercises/concept/city-office/test/form_test.exs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ defmodule FormTest do
7676
end
7777
end
7878

79-
defmacrop assert_type({module_name, type_name}, expected_type_definition) do
79+
defmacrop assert_type({module_name, type_name}, expected_type_definitions) do
8080
quote do
8181
{:ok, types} = Code.Typespec.fetch_types(unquote(module_name))
8282

@@ -94,15 +94,11 @@ defmodule FormTest do
9494

9595
actual_type_definition = Macro.to_string(type_definition)
9696

97-
if is_list(unquote(expected_type_definition)) do
98-
if actual_type_definition in unquote(expected_type_definition) do
99-
assert true
100-
else
101-
# we know this will fail at this point, but we're using it to provide a nice failure message
102-
assert actual_type_definition == hd(unquote(expected_type_definition))
103-
end
97+
if actual_type_definition in unquote(expected_type_definitions) do
98+
assert true
10499
else
105-
assert actual_type_definition == unquote(expected_type_definition)
100+
# we know this will fail at this point, but we're using it to provide a nice failure message
101+
assert actual_type_definition == hd(unquote(expected_type_definitions))
106102
end
107103
end
108104
end
@@ -231,10 +227,10 @@ defmodule FormTest do
231227

232228
@tag task_id: 5
233229
test "has a custom 'address_tuple' type with named arguments" do
234-
expected_type_definition =
235-
"{street :: String.t(), postal_code :: String.t(), city :: String.t()}"
230+
expected_type_definitions =
231+
["{street :: String.t(), postal_code :: String.t(), city :: String.t()}"]
236232

237-
assert_type({Form, :address_tuple}, expected_type_definition)
233+
assert_type({Form, :address_tuple}, expected_type_definitions)
238234
end
239235

240236
@tag task_id: 5

exercises/concept/kitchen-calculator/test/kitchen_calculator_test.exs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,22 +88,22 @@ defmodule KitchenCalculatorTest do
8888
describe "convert from x to y:" do
8989
@tag task_id: 4
9090
test "teaspoon to tablespoon" do
91-
assert KitchenCalculator.convert({:teaspoon, 15}, :tablespoon) == {:tablespoon, 5}
91+
assert KitchenCalculator.convert({:teaspoon, 15}, :tablespoon) == {:tablespoon, 5.0}
9292
end
9393

9494
@tag task_id: 4
9595
test "cups to fluid ounces" do
96-
assert KitchenCalculator.convert({:cup, 4}, :fluid_ounce) == {:fluid_ounce, 32}
96+
assert KitchenCalculator.convert({:cup, 4}, :fluid_ounce) == {:fluid_ounce, 32.0}
9797
end
9898

9999
@tag task_id: 4
100100
test "fluid ounces to teaspoons" do
101-
assert KitchenCalculator.convert({:fluid_ounce, 4}, :teaspoon) == {:teaspoon, 24}
101+
assert KitchenCalculator.convert({:fluid_ounce, 4}, :teaspoon) == {:teaspoon, 24.0}
102102
end
103103

104104
@tag task_id: 4
105105
test "tablespoons to cups" do
106-
assert KitchenCalculator.convert({:tablespoon, 320}, :cup) == {:cup, 20}
106+
assert KitchenCalculator.convert({:tablespoon, 320}, :cup) == {:cup, 20.0}
107107
end
108108
end
109109
end

exercises/concept/paint-by-number/.meta/exemplar.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ defmodule PaintByNumber do
3030

3131
case picture do
3232
<<>> -> nil
33-
<<pixel_color_index::size(palette_bit_size), _::bitstring>> -> pixel_color_index
33+
<<pixel_color_index::size(^palette_bit_size), _::bitstring>> -> pixel_color_index
3434
end
3535
end
3636

@@ -39,7 +39,7 @@ defmodule PaintByNumber do
3939

4040
case picture do
4141
<<>> -> <<>>
42-
<<_::size(palette_bit_size), rest::bitstring>> -> rest
42+
<<_::size(^palette_bit_size), rest::bitstring>> -> rest
4343
end
4444
end
4545

exercises/concept/top-secret/test/top_secret_test.exs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
defmodule TopSecretTest do
22
use ExUnit.Case
33

4+
# Maintainer notes:
5+
# - in Elixir 1.17, `:...` got [] as an argument list, before that it was nil
6+
# - in Elixir 1.20, `:__block__` got the line number in the metadata, before that it was empty
7+
48
describe "to_ast/1" do
59
@tag task_id: 1
610
test "handles an empty string" do
711
string = ""
8-
ast = {:__block__, [], []}
912

10-
assert TopSecret.to_ast(string) == ast
13+
assert {:__block__, _line_1_or_empty_list, []} = TopSecret.to_ast(string)
1114
end
1215

1316
@tag task_id: 1
@@ -17,14 +20,12 @@ defmodule TopSecretTest do
1720
y = x - 2
1821
"""
1922

20-
ast =
21-
{:__block__, [],
22-
[
23-
{:=, [line: 1], [{:x, [line: 1], nil}, 7]},
24-
{:=, [line: 2], [{:y, [line: 2], nil}, {:-, [line: 2], [{:x, [line: 2], nil}, 2]}]}
25-
]}
26-
27-
assert TopSecret.to_ast(string) == ast
23+
assert {:__block__, _line_1_or_empty_list,
24+
[
25+
{:=, [line: 1], [{:x, [line: 1], nil}, 7]},
26+
{:=, [line: 2],
27+
[{:y, [line: 2], nil}, {:-, [line: 2], [{:x, [line: 2], nil}, 2]}]}
28+
]} = TopSecret.to_ast(string)
2829
end
2930

3031
@tag task_id: 1
@@ -45,7 +46,7 @@ defmodule TopSecretTest do
4546
[
4647
do: {
4748
:__block__,
48-
[],
49+
_line_1_or_empty_list,
4950
[
5051
{:@, [line: 2],
5152
[

exercises/practice/beer-song/test/beer_song_test.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ defmodule BeerSongTest do
4646
describe "lyrics" do
4747
@tag :pending
4848
test "first two verses" do
49-
assert BeerSong.lyrics(99..98) == """
49+
assert BeerSong.lyrics(99..98//-1) == """
5050
99 bottles of beer on the wall, 99 bottles of beer.
5151
Take one down and pass it around, 98 bottles of beer on the wall.
5252
@@ -57,7 +57,7 @@ defmodule BeerSongTest do
5757

5858
@tag :pending
5959
test "last three verses" do
60-
assert BeerSong.lyrics(2..0) == """
60+
assert BeerSong.lyrics(2..0//-1) == """
6161
2 bottles of beer on the wall, 2 bottles of beer.
6262
Take one down and pass it around, 1 bottle of beer on the wall.
6363

exercises/practice/collatz-conjecture/test/collatz_conjecture_test.exs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,4 @@ defmodule CollatzConjectureTest do
3939
test "negative value is an error " do
4040
assert_raise FunctionClauseError, fn -> CollatzConjecture.calc(-15) end
4141
end
42-
43-
@tag :pending
44-
test "string as input value is an error " do
45-
assert_raise FunctionClauseError, fn -> CollatzConjecture.calc("fubar") end
46-
end
4742
end

exercises/practice/intergalactic-transmission/.meta/example.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ defmodule Transmission do
2929
@spec get_parity(bitstring()) :: <<_::1>>
3030
defp get_parity(data) do
3131
bit_count = bit_size(data)
32-
<<value::size(bit_count)>> = data
32+
<<value::size(^bit_count)>> = data
3333

3434
parity_int =
3535
0..(bit_count - 1)
@@ -71,7 +71,7 @@ defmodule Transmission do
7171

7272
defp finalize(data, acc) when bit_size(data) == 7 do
7373
bits_count = 8 - rem(bit_size(acc), 8)
74-
<<head::size(bits_count), _::bitstring>> = data
74+
<<head::size(^bits_count), _::bitstring>> = data
7575
<<acc::bitstring, head::size(bits_count)>>
7676
end
7777
end

exercises/practice/kindergarten-garden/.meta/example.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ defmodule Garden do
5151
letters = "#{first_row_letters}#{second_row_letters}"
5252
map = add_to_map(map, current_name, letters)
5353

54-
first_row = String.slice(first_row, 2..-1//-1)
55-
second_row = String.slice(second_row, 2..-1//-1)
54+
first_row = String.slice(first_row, 2..-1//1)
55+
second_row = String.slice(second_row, 2..-1//1)
5656
populate_map(first_row, second_row, map, student_names)
5757
end
5858

0 commit comments

Comments
 (0)