Skip to content

Commit 910d97e

Browse files
authored
Fix tests on Elixir 1.15 (#335)
Starts running tests on Elixir 1.15 with OTP 26 The map ordering change in OTP 26 caused many tests to break because they were implicitly relying on a not guaranteed order. Adds machete to add a sorted_list test helper (instead of changing many assertions to be split across two statements)
1 parent e707dbf commit 910d97e

File tree

8 files changed

+139
-62
lines changed

8 files changed

+139
-62
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ jobs:
2020
include:
2121
- elixir: '1.11.4'
2222
otp: '24.2'
23+
- elixir: '1.15.5'
24+
otp: '26.0'
2325

2426
steps:
2527
- uses: actions/checkout@v3

mix.exs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ defmodule Scenic.Mixfile do
5757
{:credo, ">= 0.0.0", only: [:dev, :test], runtime: false},
5858
{:excoveralls, ">= 0.0.0", only: :test, runtime: false},
5959
{:inch_ex, "~> 2.0", only: [:dev, :docs], runtime: false},
60-
{:dialyxir, "~> 1.1", only: :dev, runtime: false}
60+
{:dialyxir, "~> 1.1", only: :dev, runtime: false},
61+
{:machete, "~> 0.2.8", only: :test}
6162
]
6263
end
6364

mix.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
1717
"inch_ex": {:hex, :inch_ex, "2.0.0", "24268a9284a1751f2ceda569cd978e1fa394c977c45c331bb52a405de544f4de", [:mix], [{:bunt, "~> 0.2", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "96d0ec5ecac8cf63142d02f16b7ab7152cf0f0f1a185a80161b758383c9399a8"},
1818
"jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"},
19+
"machete": {:hex, :machete, "0.2.8", "ca7be4d2d65f05f4ab5eac0f5fd339cea08d4d75f775ac6c22991df2baed5d80", [:mix], [], "hexpm", "09bf5b306385d01c877453ead94914a595beecba3f2525c7364ee3ba0630a224"},
1920
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
2021
"makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"},
2122
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},

test/scenic/component/input/text_field_test.exs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
#
66

77
defmodule Scenic.Component.Input.TextFieldTest do
8-
use ExUnit.Case, async: false
8+
use Scenic.Test.DataCase, async: false
9+
use Machete
10+
import Scenic.Test.SortedListMatcher
911
doctest Scenic.Component.Input.TextField
1012

1113
alias Scenic.Graph
@@ -96,7 +98,7 @@ defmodule Scenic.Component.Input.TextFieldTest do
9698
assert Input.fetch_captures!(vp) == {:ok, []}
9799
Input.send(vp, @press_in)
98100
force_sync(vp.pid, pid)
99-
assert Input.fetch_captures!(vp) == {:ok, [:codepoint, :cursor_button, :key]}
101+
assert Input.fetch_captures!(vp) ~> {:ok, sorted_list([:codepoint, :cursor_button, :key])}
100102

101103
Input.send(vp, @cp_k)
102104
assert_receive({:fwd_event, {:value_changed, :text_field, "kInitial value"}}, 200)
@@ -105,7 +107,8 @@ defmodule Scenic.Component.Input.TextFieldTest do
105107
test "press_out releases and ends editing", %{vp: vp, pid: pid} do
106108
Input.send(vp, @press_in)
107109
force_sync(vp.pid, pid)
108-
assert Input.fetch_captures!(vp) == {:ok, [:codepoint, :cursor_button, :key]}
110+
111+
assert Input.fetch_captures!(vp) ~> {:ok, sorted_list([:codepoint, :cursor_button, :key])}
109112

110113
Input.send(vp, @press_out)
111114
force_sync(vp.pid, pid)

test/scenic/scene_test.exs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#
66

77
defmodule Scenic.SceneTest do
8-
use ExUnit.Case, async: false
8+
use Scenic.Test.DataCase, async: false
99
doctest Scenic.Scene
1010

1111
alias Scenic.ViewPort
@@ -382,34 +382,32 @@ defmodule Scenic.SceneTest do
382382
test "fetch_requests works", %{scene: scene} do
383383
Scenic.Scene.request_input(scene, :cursor_button)
384384

385-
assert Scene.fetch_requests(scene) == {:ok, [:cursor_button, :codepoint]}
385+
assert Scene.fetch_requests(scene) ~> {:ok, sorted_list([:cursor_button, :codepoint])}
386386

387387
# request input from outside the scene
388388
:ok = ViewPort.Input.request(scene.viewport, :cursor_pos)
389389

390390
# should only show input form the scene even though this is the caller
391-
assert Scene.fetch_requests(scene) == {:ok, [:cursor_button, :codepoint]}
391+
assert Scene.fetch_requests(scene) ~> {:ok, sorted_list([:cursor_button, :codepoint])}
392392
end
393393

394394
test "request_input works", %{scene: scene} do
395395
Scenic.Scene.request_input(scene, :cursor_button)
396396

397-
assert Scene.fetch_requests(scene) ==
398-
{:ok, [:cursor_button, :codepoint]}
397+
assert Scene.fetch_requests(scene) ~> {:ok, sorted_list([:cursor_button, :codepoint])}
399398

400399
:ok = Scene.request_input(scene, :cursor_pos)
401400

402-
assert Scene.fetch_requests(scene) ==
403-
{:ok, [:cursor_pos, :cursor_button, :codepoint]}
401+
assert Scene.fetch_requests(scene) ~> {:ok, sorted_list([:cursor_pos, :cursor_button, :codepoint])}
404402
end
405403

406404
test "unrequest_input works", %{scene: scene} do
407405
Scenic.Scene.request_input(scene, :cursor_button)
408406

409-
assert Scene.fetch_requests(scene) == {:ok, [:cursor_button, :codepoint]}
407+
assert Scene.fetch_requests(scene) ~> {:ok, sorted_list([:cursor_button, :codepoint])}
410408

411409
:ok = Scene.unrequest_input(scene, :codepoint)
412-
assert Scene.fetch_requests(scene) == {:ok, [:cursor_button]}
410+
assert Scene.fetch_requests(scene) ~> {:ok, sorted_list([:cursor_button])}
413411
end
414412

415413
test "fetch_captures works", %{scene: scene} do

test/scenic/view_port/input_test.exs

Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#
55

66
defmodule Scenic.ViewPort.InputTest do
7-
use ExUnit.Case, async: false
7+
use Scenic.Test.DataCase, async: false
88
doctest Scenic.ViewPort.Input
99

1010
alias Scenic.ViewPort
@@ -46,86 +46,86 @@ defmodule Scenic.ViewPort.InputTest do
4646
end
4747

4848
test "Test that capture/release/list_captures work", %{vp: vp} do
49-
assert Input.fetch_captures(vp) == {:ok, []}
49+
assert Input.fetch_captures(vp) ~> {:ok, sorted_list([])}
5050

5151
:ok = Input.capture(vp, :cursor_pos)
52-
assert Input.fetch_captures(vp) == {:ok, [:cursor_pos]}
52+
assert Input.fetch_captures(vp) ~> {:ok, sorted_list([:cursor_pos])}
5353

5454
:ok = Input.capture(vp, [:key, :codepoint])
55-
assert Input.fetch_captures(vp) == {:ok, [:key, :cursor_pos, :codepoint]}
55+
assert Input.fetch_captures(vp) ~> {:ok, sorted_list([:key, :cursor_pos, :codepoint])}
5656

5757
:ok = Input.release(vp, :key)
58-
assert Input.fetch_captures(vp) == {:ok, [:cursor_pos, :codepoint]}
58+
assert Input.fetch_captures(vp) ~> {:ok, sorted_list([:cursor_pos, :codepoint])}
5959

6060
:ok = Input.release(vp, :all)
61-
assert Input.fetch_captures(vp) == {:ok, []}
61+
assert Input.fetch_captures(vp) ~> {:ok, sorted_list([])}
6262
end
6363

6464
test "list_captures and list_captures! work", %{vp: vp} do
65-
assert Input.fetch_captures(vp) == {:ok, []}
66-
assert Input.fetch_captures!(vp) == {:ok, []}
65+
assert Input.fetch_captures(vp) ~> {:ok, sorted_list([])}
66+
assert Input.fetch_captures!(vp) ~> {:ok, sorted_list([])}
6767

6868
Agent.start(fn ->
6969
:ok = Input.capture(vp, [:codepoint])
7070
end)
7171

72-
assert Input.fetch_captures(vp) == {:ok, []}
73-
assert Input.fetch_captures!(vp) == {:ok, [:codepoint]}
72+
assert Input.fetch_captures(vp) ~> {:ok, sorted_list([])}
73+
assert Input.fetch_captures!(vp) ~> {:ok, sorted_list([:codepoint])}
7474

7575
:ok = Input.capture(vp, :cursor_pos)
76-
assert Input.fetch_captures(vp) == {:ok, [:cursor_pos]}
77-
assert Input.fetch_captures!(vp) == {:ok, [:codepoint, :cursor_pos]}
76+
assert Input.fetch_captures(vp) ~> {:ok, sorted_list([:cursor_pos])}
77+
assert Input.fetch_captures!(vp) ~> {:ok, sorted_list([:codepoint, :cursor_pos])}
7878
end
7979

8080
test "captures are cleaned up when the owning process stops", %{vp: vp} do
8181
# set up a capture
8282
:ok = Input.capture(vp, [:codepoint])
83-
assert Input.fetch_captures!(vp) == {:ok, [:codepoint]}
83+
assert Input.fetch_captures!(vp) ~> {:ok, sorted_list([:codepoint])}
8484

8585
# fake indicate this process went down
8686
Process.send(vp.pid, {:DOWN, make_ref(), :process, self(), :test}, [])
8787

88-
assert Input.fetch_captures!(vp) == {:ok, []}
88+
assert Input.fetch_captures!(vp) ~> {:ok, sorted_list([])}
8989
end
9090

9191
test "Test that request/unrequest/list_requests work", %{vp: vp} do
92-
assert Input.fetch_requests(vp) == {:ok, []}
92+
assert Input.fetch_requests(vp) ~> {:ok, sorted_list([])}
9393

9494
:ok = Input.request(vp, :cursor_pos)
95-
assert Input.fetch_requests(vp) == {:ok, [:cursor_pos]}
95+
assert Input.fetch_requests(vp) ~> {:ok, sorted_list([:cursor_pos])}
9696

9797
:ok = Input.request(vp, [:key, :codepoint])
98-
assert Input.fetch_requests(vp) == {:ok, [:key, :cursor_pos, :codepoint]}
98+
assert Input.fetch_requests(vp) ~> {:ok, sorted_list([:key, :cursor_pos, :codepoint])}
9999

100100
:ok = Input.unrequest(vp, :key)
101-
assert Input.fetch_requests(vp) == {:ok, [:cursor_pos, :codepoint]}
101+
assert Input.fetch_requests(vp) ~> {:ok, sorted_list([:cursor_pos, :codepoint])}
102102

103103
:ok = Input.unrequest(vp, :all)
104-
assert Input.fetch_requests(vp) == {:ok, []}
104+
assert Input.fetch_requests(vp) ~> {:ok, sorted_list([])}
105105
end
106106

107107
test "fetch_requests and fetch_requests! work", %{vp: vp} do
108-
assert Input.fetch_requests(vp) == {:ok, []}
109-
assert Input.fetch_requests!(vp) == {:ok, []}
108+
assert Input.fetch_requests(vp) ~> {:ok, sorted_list([])}
109+
assert Input.fetch_requests!(vp) ~> {:ok, sorted_list([])}
110110

111111
Agent.start(fn ->
112112
:ok = Input.request(vp, [:codepoint])
113113
end)
114114

115-
assert Input.fetch_captures(vp) == {:ok, []}
116-
assert Input.fetch_requests!(vp) == {:ok, [:codepoint]}
115+
assert Input.fetch_captures(vp) ~> {:ok, sorted_list([])}
116+
assert Input.fetch_requests!(vp) ~> {:ok, sorted_list([:codepoint])}
117117

118118
:ok = Input.request(vp, :cursor_pos)
119-
assert Input.fetch_requests(vp) == {:ok, [:cursor_pos]}
120-
assert Input.fetch_requests!(vp) == {:ok, [:codepoint, :cursor_pos]}
119+
assert Input.fetch_requests(vp) ~> {:ok, sorted_list([:cursor_pos])}
120+
assert Input.fetch_requests!(vp) ~> {:ok, sorted_list([:codepoint, :cursor_pos])}
121121
end
122122

123123
test "requests are cleaned up with the owning process stops", %{vp: vp, scene: scene} do
124124
:ok = Input.request(vp, :cursor_pos)
125125
Scenic.Scene.request_input(scene, :codepoint)
126-
assert Input.fetch_requests!(vp) == {:ok, [:codepoint, :cursor_pos]}
126+
assert Input.fetch_requests!(vp) ~> {:ok, sorted_list([:codepoint, :cursor_pos])}
127127
Scenic.Scene.stop(scene)
128-
assert Input.fetch_requests!(vp) == {:ok, [:cursor_pos]}
128+
assert Input.fetch_requests!(vp) ~> {:ok, sorted_list([:cursor_pos])}
129129
end
130130

131131
# ----------------
@@ -135,7 +135,7 @@ defmodule Scenic.ViewPort.InputTest do
135135
%{vp: vp, scene: scene} do
136136
# make like a driver
137137
GenServer.cast(vp.pid, {:register_driver, self()})
138-
assert Input.fetch_requests!(vp) == {:ok, []}
138+
assert Input.fetch_requests!(vp) ~> {:ok, sorted_list([])}
139139

140140
graph =
141141
Scenic.Graph.build()
@@ -162,7 +162,7 @@ defmodule Scenic.ViewPort.InputTest do
162162
} do
163163
# make like a driver
164164
GenServer.cast(vp.pid, {:register_driver, self()})
165-
assert Input.fetch_requests!(vp) == {:ok, []}
165+
assert Input.fetch_requests!(vp) ~> {:ok, sorted_list([])}
166166

167167
graph =
168168
Scenic.Graph.build()
@@ -179,7 +179,7 @@ defmodule Scenic.ViewPort.InputTest do
179179
} do
180180
# make like a driver
181181
GenServer.cast(vp.pid, {:register_driver, self()})
182-
assert Input.fetch_requests!(vp) == {:ok, []}
182+
assert Input.fetch_requests!(vp) ~> {:ok, sorted_list([])}
183183

184184
graph =
185185
Scenic.Graph.build()
@@ -193,7 +193,7 @@ defmodule Scenic.ViewPort.InputTest do
193193
test ":cursor_pos only the input listed in a input style is requested", %{vp: vp, scene: scene} do
194194
# make like a driver
195195
GenServer.cast(vp.pid, {:register_driver, self()})
196-
assert Input.fetch_requests!(vp) == {:ok, []}
196+
assert Input.fetch_requests!(vp) ~> {:ok, sorted_list([])}
197197

198198
graph =
199199
Scenic.Graph.build()
@@ -333,11 +333,11 @@ defmodule Scenic.ViewPort.InputTest do
333333
# specific input types
334334

335335
test "cursor_scroll request works", %{vp: vp} do
336-
assert Input.fetch_captures!(vp) == {:ok, []}
337-
assert Input.fetch_requests(vp) == {:ok, []}
336+
assert Input.fetch_captures!(vp) ~> {:ok, sorted_list([])}
337+
assert Input.fetch_requests(vp) ~> {:ok, sorted_list([])}
338338

339339
:ok = Input.request(vp, :cursor_scroll)
340-
assert Input.fetch_requests(vp) == {:ok, [:cursor_scroll]}
340+
assert Input.fetch_requests(vp) ~> {:ok, sorted_list([:cursor_scroll])}
341341

342342
assert Input.send(vp, {:cursor_scroll, {{1, 2}, {3, 4}}}) == :ok
343343

@@ -348,11 +348,11 @@ defmodule Scenic.ViewPort.InputTest do
348348
end
349349

350350
test "cursor_scroll capture works", %{vp: vp} do
351-
assert Input.fetch_captures(vp) == {:ok, []}
352-
assert Input.fetch_requests(vp) == {:ok, []}
351+
assert Input.fetch_captures(vp) ~> {:ok, sorted_list([])}
352+
assert Input.fetch_requests(vp) ~> {:ok, sorted_list([])}
353353

354354
:ok = Input.capture(vp, :cursor_scroll)
355-
assert Input.fetch_captures(vp) == {:ok, [:cursor_scroll]}
355+
assert Input.fetch_captures(vp) ~> {:ok, sorted_list([:cursor_scroll])}
356356

357357
assert Input.send(vp, {:cursor_scroll, {{1, 2}, {3, 4}}}) == :ok
358358

@@ -363,11 +363,11 @@ defmodule Scenic.ViewPort.InputTest do
363363
end
364364

365365
test "cursor_pos request works", %{vp: vp} do
366-
assert Input.fetch_captures!(vp) == {:ok, []}
367-
assert Input.fetch_requests(vp) == {:ok, []}
366+
assert Input.fetch_captures!(vp) ~> {:ok, sorted_list([])}
367+
assert Input.fetch_requests(vp) ~> {:ok, sorted_list([])}
368368

369369
:ok = Input.request(vp, :cursor_pos)
370-
assert Input.fetch_requests(vp) == {:ok, [:cursor_pos]}
370+
assert Input.fetch_requests(vp) ~> {:ok, sorted_list([:cursor_pos])}
371371

372372
assert Input.send(vp, {:cursor_pos, {1, 2}}) == :ok
373373

@@ -378,11 +378,11 @@ defmodule Scenic.ViewPort.InputTest do
378378
end
379379

380380
test "cursor_pos capture works", %{vp: vp} do
381-
assert Input.fetch_captures(vp) == {:ok, []}
382-
assert Input.fetch_requests(vp) == {:ok, []}
381+
assert Input.fetch_captures(vp) ~> {:ok, sorted_list([])}
382+
assert Input.fetch_requests(vp) ~> {:ok, sorted_list([])}
383383

384384
:ok = Input.capture(vp, :cursor_pos)
385-
assert Input.fetch_captures(vp) == {:ok, [:cursor_pos]}
385+
assert Input.fetch_captures(vp) ~> {:ok, sorted_list([:cursor_pos])}
386386

387387
assert Input.send(vp, {:cursor_pos, {1, 2}}) == :ok
388388

@@ -396,7 +396,7 @@ defmodule Scenic.ViewPort.InputTest do
396396
# drivers are sent input updates
397397

398398
test "drivers are sent requested input updates", %{vp: vp} do
399-
assert Input.fetch_requests!(vp) == {:ok, []}
399+
assert Input.fetch_requests!(vp) ~> {:ok, sorted_list([])}
400400
:ok = Input.request(vp, :cursor_button)
401401

402402
GenServer.cast(vp.pid, {:register_driver, self()})
@@ -418,7 +418,7 @@ defmodule Scenic.ViewPort.InputTest do
418418
test "drivers are sent requested input updates when a scene goes down", %{vp: vp, scene: scene} do
419419
Scenic.Scene.request_input(scene, :cursor_button)
420420

421-
assert Input.fetch_requests!(vp) == {:ok, [:cursor_button]}
421+
assert Input.fetch_requests!(vp) ~> {:ok, sorted_list([:cursor_button])}
422422

423423
GenServer.cast(vp.pid, {:register_driver, self()})
424424
assert_receive({:_request_input_, [:cursor_button]}, 100)
@@ -432,8 +432,8 @@ defmodule Scenic.ViewPort.InputTest do
432432
test "drivers are sent captured input updates", %{vp: vp, scene: scene} do
433433
Scenic.Scene.request_input(scene, :cursor_button)
434434

435-
assert Input.fetch_captures!(vp) == {:ok, []}
436-
assert Input.fetch_requests!(vp) == {:ok, [:cursor_button]}
435+
assert Input.fetch_captures!(vp) ~> {:ok, sorted_list([])}
436+
assert Input.fetch_requests!(vp) ~> {:ok, sorted_list([:cursor_button])}
437437

438438
GenServer.cast(vp.pid, {:register_driver, self()})
439439
assert_receive({:_request_input_, [:cursor_button]}, 100)
@@ -454,7 +454,7 @@ defmodule Scenic.ViewPort.InputTest do
454454
test "drivers are sent captured input updates when a scene goes down", %{vp: vp, scene: scene} do
455455
Scenic.Scene.request_input(scene, :cursor_button)
456456

457-
assert Input.fetch_requests!(vp) == {:ok, [:cursor_button]}
457+
assert Input.fetch_requests!(vp) ~> {:ok, sorted_list([:cursor_button])}
458458
self = self()
459459
# have to have an agent do the capture so that it comes from a different pid than this
460460
# test, which is pretending to be a driver...
@@ -479,7 +479,7 @@ defmodule Scenic.ViewPort.InputTest do
479479

480480
# should get an update when the owning pid goes down
481481
# calling fetch_requests! makes sure the vp has processed the agent DOWN message
482-
assert Input.fetch_requests!(vp) == {:ok, [:cursor_button]}
482+
assert Input.fetch_requests!(vp) ~> {:ok, sorted_list([:cursor_button])}
483483
assert_receive({:_request_input_, [:cursor_button]}, 100)
484484
end
485485

0 commit comments

Comments
 (0)