Add ex_slop, configure it, run it and fix issues

This commit is contained in:
Claudio Ortolina
2026-04-12 22:07:27 +01:00
parent 9370e5f64d
commit 88906e10ad
18 changed files with 34 additions and 81 deletions
+23
View File
@@ -4,6 +4,29 @@
name: "default",
checks: %{
extra: [
{ExSlop.Check.Warning.BlanketRescue, []},
{ExSlop.Check.Warning.RescueWithoutReraise, []},
{ExSlop.Check.Warning.RepoAllThenFilter, []},
{ExSlop.Check.Warning.QueryInEnumMap, []},
{ExSlop.Check.Warning.GenserverAsKvStore, []},
{ExSlop.Check.Refactor.FilterNil, []},
{ExSlop.Check.Refactor.RejectNil, []},
{ExSlop.Check.Refactor.ReduceAsMap, []},
{ExSlop.Check.Refactor.MapIntoLiteral, []},
{ExSlop.Check.Refactor.IdentityPassthrough, []},
{ExSlop.Check.Refactor.IdentityMap, []},
{ExSlop.Check.Refactor.CaseTrueFalse, []},
{ExSlop.Check.Refactor.TryRescueWithSafeAlternative, []},
{ExSlop.Check.Refactor.WithIdentityElse, []},
{ExSlop.Check.Refactor.WithIdentityDo, []},
{ExSlop.Check.Refactor.SortThenReverse, []},
{ExSlop.Check.Refactor.StringConcatInReduce, []},
{ExSlop.Check.Readability.NarratorDoc, []},
{ExSlop.Check.Readability.DocFalseOnPublicFunction, []},
{ExSlop.Check.Readability.BoilerplateDocParams, []},
{ExSlop.Check.Readability.ObviousComment, []},
{ExSlop.Check.Readability.StepComment, []},
{ExSlop.Check.Readability.NarratorComment, []},
{Credo.Check.Refactor.Nesting, max_nesting: 3},
{Credo.Check.Readability.ModuleDoc,
ignore_names: [
-4
View File
@@ -281,11 +281,9 @@ defmodule MusicLibrary.ScrobbleRules do
{album_rules, artist_rules} =
Enum.split_with(enabled_rules, fn rule -> rule.type == :album end)
# Apply all album rules in one query
album_result =
case apply_all_album_rules(album_rules) do
{:ok, count} ->
# Return the count for each album rule (total updated)
# Note: this returns the same count for each rule since they're applied together
Enum.map(album_rules, fn rule ->
{:ok, {rule.type, rule.match_value, count}}
@@ -297,11 +295,9 @@ defmodule MusicLibrary.ScrobbleRules do
end)
end
# Apply all artist rules in one query
artist_result =
case apply_all_artist_rules(artist_rules) do
{:ok, count} ->
# Return the count for each artist rule (total updated)
# Note: this returns the same count for each rule since they're applied together
Enum.map(artist_rules, fn rule ->
{:ok, {rule.type, rule.match_value, count}}
+1 -9
View File
@@ -1,13 +1,5 @@
defmodule MusicLibraryWeb.Layouts do
@moduledoc """
This module holds different layouts used by your application.
See the `layouts` directory for all templates available.
The "root" layout is a skeleton rendered as part of the
application router. The "app" layout is set as the default
layout on both `use MusicLibraryWeb, :controller` and
`use MusicLibraryWeb, :live_view`.
"""
@moduledoc false
use MusicLibraryWeb, :html
import MusicLibraryWeb.UniversalSearchLive.Index, only: [universal_search_trigger: 1]
+1
View File
@@ -71,6 +71,7 @@ defmodule MusicLibrary.MixProject do
{:tailwind, "~> 0.3", runtime: Mix.env() == :dev},
{:benchee, "~> 1.3", only: :dev, runtime: false},
{:credo, "~> 1.7", only: [:dev, :test], runtime: false},
{:ex_slop, "~> 0.1", only: [:dev, :test], runtime: false},
{:quokka, "~> 2.6", only: [:dev, :test], runtime: false},
{:live_debugger, "~> 0.7.0", only: :dev},
{:usage_rules, "~> 1.1", only: [:dev]},
+1
View File
@@ -19,6 +19,7 @@
"elixir_make": {:hex, :elixir_make, "0.9.0", "6484b3cd8c0cee58f09f05ecaf1a140a8c97670671a6a0e7ab4dc326c3109726", [:mix], [], "hexpm", "db23d4fd8b757462ad02f8aa73431a426fe6671c80b200d9710caf3d1dd0ffdb"},
"error_tracker": {:hex, :error_tracker, "0.8.0", "15774836205c1b4cd8275b594d99c10f4de168eb00573743526b6a919f2aca4a", [:mix], [{:ecto, "~> 3.13", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.13", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, ">= 0.0.0", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:igniter, "~> 0.5", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:myxql, ">= 0.0.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:phoenix_ecto, "~> 4.6", [hex: :phoenix_ecto, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "00ab8342932de7ad63be567ddd36ea238c840c122c7b2c5d1a42638ce6f39220"},
"esbuild": {:hex, :esbuild, "0.10.0", "b0aa3388a1c23e727c5a3e7427c932d89ee791746b0081bbe56103e9ef3d291f", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "468489cda427b974a7cc9f03ace55368a83e1a7be12fba7e30969af78e5f8c70"},
"ex_slop": {:hex, :ex_slop, "0.2.0", "28ee70d62975636242dabf47d24e247acfbfdffd9c7cdc5a0d1c396aa42b421d", [:mix], [{:credo, "~> 1.7", [hex: :credo, repo: "hexpm", optional: false]}], "hexpm", "da8ccad55b61eebf7972fee1ab723f5227e58ed052ea09be4f9fe315c5e89cc2"},
"expo": {:hex, :expo, "1.1.1", "4202e1d2ca6e2b3b63e02f69cfe0a404f77702b041d02b58597c00992b601db5", [:mix], [], "hexpm", "5fb308b9cb359ae200b7e23d37c76978673aa1b06e2b3075d814ce12c5811640"},
"exqlite": {:hex, :exqlite, "0.36.0", "07b4f95d61cb82b8d52946d0639497fa7d32117e09b2c8d25e24a38723c295cb", [:make, :mix], [{:cc_precompiler, "~> 0.1", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.8", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "cbeca3ce781f9ff07cfa9a87486f3ebd512a143ad6a14ed5c9fca21fe0bf3ae7"},
"file_system": {:hex, :file_system, "1.1.1", "31864f4685b0148f25bd3fbef2b1228457c0c89024ad67f7a81a3ffbc0bbad3a", [:mix], [], "hexpm", "7a15ff97dfe526aeefb090a7a9d3d03aa907e100e262a0f8f7746b78f8f87a5d"},
@@ -209,7 +209,6 @@ defmodule MusicLibrary.ScrobbleRulesTest do
assert {:ok, 1} = ScrobbleRules.apply_album_rule(rule)
# Verify the matching track was updated
updated_track = Repo.get_by(Track, scrobbled_at_uts: track1.scrobbled_at_uts)
assert updated_track.album.musicbrainz_id == rule.target_musicbrainz_id
end
@@ -232,7 +231,6 @@ defmodule MusicLibrary.ScrobbleRulesTest do
assert {:ok, 1} = ScrobbleRules.apply_artist_rule(rule)
# Verify the matching track was updated
updated_track = Repo.get_by(Track, scrobbled_at_uts: track1.scrobbled_at_uts)
assert updated_track.artist.musicbrainz_id == rule.target_musicbrainz_id
end
@@ -359,17 +357,14 @@ defmodule MusicLibrary.ScrobbleRulesTest do
album: %{musicbrainz_id: "", title: "Wish You Were Here"}
})
# Create a non-matching track
_track3 =
scrobbled_track_fixture(%{
scrobbled_at_uts: System.system_time(:second) + 2,
album: %{musicbrainz_id: "", title: "The Wall"}
})
# Apply both rules at once
assert {:ok, 2} = ScrobbleRules.apply_all_album_rules([rule1, rule2])
# Verify both tracks were updated by fetching them again
updated_track1 = Repo.get(Track, track1.scrobbled_at_uts)
assert updated_track1.album.musicbrainz_id == rule1.target_musicbrainz_id
@@ -400,7 +395,6 @@ defmodule MusicLibrary.ScrobbleRulesTest do
artist: %{musicbrainz_id: "", name: "Led Zeppelin"}
})
# Create a non-matching track
_track3 =
scrobbled_track_fixture(%{
scrobbled_at_uts: System.system_time(:second) + 2,
@@ -8,11 +8,9 @@ defmodule MusicLibrary.Worker.PruneAssetCacheTest do
@describetag :capture_log
test "prunes old cache entries" do
# Insert a cache entry with an old timestamp
old_timestamp = DateTime.utc_now() |> DateTime.add(-8, :day) |> DateTime.to_unix()
:ets.insert(Cache, {{"old_payload", "image/jpeg"}, old_timestamp, "old_content"})
# Insert a recent cache entry
Cache.set("recent_payload", "image/jpeg", "recent_content")
assert :ok = perform_job(PruneAssetCache, %{})
@@ -56,7 +56,6 @@ defmodule MusicLibraryWeb.ScrobbleLive.IndexTest do
session
|> unwrap(fn view ->
# Process the {:perform_search, query} message
render(view)
end)
|> assert_has("input[value='marbles']")
@@ -73,7 +72,6 @@ defmodule MusicLibraryWeb.ScrobbleLive.IndexTest do
|> form("form[phx-submit='search']", %{query: "marbles"})
|> render_submit()
# Process the {:perform_search, query} message
render(view)
end)
|> assert_has("h3", "Release Groups")
@@ -103,16 +101,13 @@ defmodule MusicLibraryWeb.ScrobbleLive.IndexTest do
|> form("form[phx-submit='search']", %{query: "marbles"})
|> render_submit()
# Process search results
render(view)
# Click on a release group
view
|> render_click("select_release_group", %{
"release_group_id" => release_group_id
})
# Process the {:fetch_releases, release_group} message
render(view)
end)
|> assert_has("h3", "Releases for")
@@ -37,7 +37,6 @@ defmodule MusicLibraryWeb.ScrobbledTracksLiveTest do
end
test "shows empty state when no tracks", %{conn: conn} do
# Delete the created track
ListeningStats.delete_track(track_fixture())
conn
@@ -47,7 +47,6 @@ defmodule MusicLibraryWeb.RecordsOnThisDayEmailTest do
end
test "skips sending when no records match" do
# Create a record with a release date that won't match
Fixtures.Records.record(%{release_date: "2020-01-01"})
date = ~D[2025-06-15]
+1 -15
View File
@@ -1,19 +1,5 @@
defmodule MusicLibraryWeb.ConnCase do
@moduledoc """
This module defines the test case to be used by
tests that require setting up a connection.
Such tests rely on `Phoenix.ConnTest` and also
import other functionality to make it easier
to build common data structures and query the data layer.
Finally, if the test case interacts with the database,
we enable the SQL sandbox, so changes done to the database
are reverted at the end of every test. If you are using
PostgreSQL, you can even run database tests asynchronously
by setting `use MusicLibraryWeb.ConnCase, async: true`, although
this option is not recommended for other databases.
"""
@moduledoc false
use ExUnit.CaseTemplate
+1 -14
View File
@@ -1,18 +1,5 @@
defmodule MusicLibrary.DataCase do
@moduledoc """
This module defines the setup for tests requiring
access to the application's data layer.
You may define functions here to be used as helpers in
your tests.
Finally, if the test case interacts with the database,
we enable the SQL sandbox, so changes done to the database
are reverted at the end of every test. If you are using
PostgreSQL, you can even run database tests asynchronously
by setting `use MusicLibrary.DataCase, async: true`, although
this option is not recommended for other databases.
"""
@moduledoc false
use ExUnit.CaseTemplate
@@ -1,8 +1,5 @@
defmodule MusicLibrary.ArtistInfoFixtures do
@moduledoc """
This module defines test helpers for creating
entities via the `MusicLibrary.Artists.ArtistInfo` schema.
"""
@moduledoc false
alias MusicLibrary.Artists.ArtistInfo
alias MusicLibrary.Repo
@@ -1,8 +1,5 @@
defmodule MusicLibrary.Fixtures.OnlineStoreTemplates do
@moduledoc """
This module defines test helpers for creating
entities via the `MusicLibrary.OnlineStoreTemplates` context.
"""
@moduledoc false
alias MusicLibrary.OnlineStoreTemplates
@@ -1,8 +1,5 @@
defmodule MusicLibrary.Fixtures.RecordSets do
@moduledoc """
This module defines test helpers for creating
entities via the `MusicLibrary.RecordSets` context.
"""
@moduledoc false
alias MusicLibrary.RecordSets
@@ -1,8 +1,5 @@
defmodule MusicLibrary.Fixtures.Records do
@moduledoc """
This module defines test helpers for creating
entities via the `MusicLibrary.Records` context.
"""
@moduledoc false
alias MusicBrainz.Fixtures.ReleaseGroup
alias MusicLibrary.Assets
@@ -1,8 +1,5 @@
defmodule MusicLibrary.ScrobbleRulesFixtures do
@moduledoc """
This module defines test helpers for creating
entities via the `MusicLibrary.ScrobbleRules` context.
"""
@moduledoc false
alias MusicLibrary.ScrobbleRules
@@ -1,8 +1,5 @@
defmodule MusicLibrary.ScrobbledTracksFixtures do
@moduledoc """
This module defines test helpers for creating
scrobbled track entities via the database.
"""
@moduledoc false
alias LastFm.Track
alias MusicLibrary.Repo