From 31f9e44b83e85a0808323fc16a6c0af8d1b4216f Mon Sep 17 00:00:00 2001
From: Randy Coulman <rcoulman@gmail.com>
Date: Fri, 15 Dec 2023 21:12:11 -0800
Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20Adopt=20Styler?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Adopt the [Styler](https://github.com/adobe/elixir-styler) library, which is an Elixir formatter plugin that imposes some opinionated formatting on the code in place of a number of Credo rules.

While I don't always prefer its opinions, I really like have it auto-fix a number of issues, and I find that it's worth the tradeoff to adopt it.
---
 .credo.exs                                 |  46 +++++-----
 .formatter.exs                             |   3 +-
 lib/config_cat/cache.ex                    |   5 +-
 lib/config_cat/cache_policy.ex             |   4 +-
 lib/config_cat/cache_policy/auto.ex        |  17 ++--
 lib/config_cat/cache_policy/null.ex        |   6 +-
 lib/config_cat/client.ex                   |  26 +++---
 lib/config_cat/config_cat_logger.ex        |   2 +-
 lib/config_cat/config_fetcher.ex           |  28 ++----
 lib/config_cat/fetch_time.ex               |   2 +-
 lib/config_cat/in_memory_cache.ex          |   4 +-
 lib/config_cat/local_file_data_source.ex   |   4 +-
 lib/config_cat/rollout.ex                  | 102 ++++++++++-----------
 lib/config_cat/rollout/comparator.ex       |  43 ++++-----
 lib/config_cat/supervisor.ex               |  18 ++--
 lib/config_cat/user.ex                     |   3 +-
 mix.exs                                    |   1 +
 mix.lock                                   |   1 +
 test/config_cat/cache_policy/auto_test.exs |   8 +-
 test/config_cat/cache_test.exs             |  20 +---
 test/config_cat/config_fetcher_test.exs    |  44 +++------
 test/config_cat/data_governance_test.exs   |   5 +-
 test/config_cat/default_user_test.exs      |  32 ++-----
 test/config_cat/hooks/impl_test.exs        |   9 +-
 test/config_cat/hooks_test.exs             |  13 +--
 test/config_cat_test.exs                   |  11 +--
 test/integration_test.exs                  |   8 +-
 test/rollout_test.exs                      |   5 +-
 test/support/cache_policy_case.ex          |  19 ++--
 test/support/client_case.ex                |  13 +--
 30 files changed, 211 insertions(+), 291 deletions(-)

diff --git a/.credo.exs b/.credo.exs
index cfa2ba50..80d748f8 100644
--- a/.credo.exs
+++ b/.credo.exs
@@ -71,7 +71,6 @@
           #
           {Credo.Check.Consistency.ExceptionNames, []},
           {Credo.Check.Consistency.LineEndings, []},
-          {Credo.Check.Consistency.ParameterPatternMatching, []},
           {Credo.Check.Consistency.SpaceAroundOperators, []},
           {Credo.Check.Consistency.SpaceInParentheses, []},
           {Credo.Check.Consistency.TabsOrSpaces, []},
@@ -82,8 +81,7 @@
           # You can customize the priority of any check
           # Priority values are: `low, normal, high, higher`
           #
-          {Credo.Check.Design.AliasUsage,
-           [priority: :low, if_nested_deeper_than: 2, if_called_more_often_than: 0]},
+          {Credo.Check.Design.AliasUsage, [priority: :low, if_nested_deeper_than: 2, if_called_more_often_than: 0]},
           # You can also customize the exit_status of each check.
           # If you don't want TODO comments to cause `mix credo` to fail, just
           # set this value to 0 (zero).
@@ -94,56 +92,37 @@
           #
           ## Readability Checks
           #
-          {Credo.Check.Readability.AliasOrder, []},
           {Credo.Check.Readability.FunctionNames, []},
           {Credo.Check.Readability.ImplTrue, []},
-          {Credo.Check.Readability.LargeNumbers, []},
           {Credo.Check.Readability.MaxLineLength, [priority: :low, max_length: 120]},
           {Credo.Check.Readability.ModuleAttributeNames, []},
-          {Credo.Check.Readability.ModuleDoc, []},
           {Credo.Check.Readability.ModuleNames, []},
-          {Credo.Check.Readability.MultiAlias, []},
           {Credo.Check.Readability.ParenthesesInCondition, []},
-          {Credo.Check.Readability.ParenthesesOnZeroArityDefs, []},
-          {Credo.Check.Readability.PipeIntoAnonymousFunctions, []},
           {Credo.Check.Readability.PredicateFunctionNames, []},
-          {Credo.Check.Readability.PreferImplicitTry, []},
           {Credo.Check.Readability.RedundantBlankLines, []},
           {Credo.Check.Readability.Semicolons, []},
           {Credo.Check.Readability.SingleFunctionToBlockPipe, []},
           {Credo.Check.Readability.SpaceAfterCommas, []},
           {Credo.Check.Readability.Specs, []},
-          {Credo.Check.Readability.StrictModuleLayout,
-           ignore: [:behaviour], order: [:shortdoc, :moduledoc, :use, :import, :alias, :require]},
           {Credo.Check.Readability.StringSigils, []},
           {Credo.Check.Readability.TrailingBlankLine, []},
           {Credo.Check.Readability.TrailingWhiteSpace, []},
-          {Credo.Check.Readability.UnnecessaryAliasExpansion, []},
           {Credo.Check.Readability.VariableNames, []},
           {Credo.Check.Readability.WithCustomTaggedTuple, []},
-          {Credo.Check.Readability.WithSingleClause, []},
 
           #
           ## Refactoring Opportunities
           #
           {Credo.Check.Refactor.Apply, []},
-          {Credo.Check.Refactor.CondStatements, []},
           {Credo.Check.Refactor.CyclomaticComplexity, []},
           {Credo.Check.Refactor.FunctionArity, []},
           {Credo.Check.Refactor.IoPuts, []},
           {Credo.Check.Refactor.LongQuoteBlocks, []},
           {Credo.Check.Refactor.MatchInCondition, []},
-          {Credo.Check.Refactor.MapJoin, []},
-          {Credo.Check.Refactor.NegatedConditionsInUnless, []},
-          {Credo.Check.Refactor.NegatedConditionsWithElse, []},
           {Credo.Check.Refactor.Nesting, []},
           {Credo.Check.Refactor.PassAsyncInTestCases, []},
-          {Credo.Check.Refactor.UnlessWithElse, []},
-          {Credo.Check.Refactor.WithClauses, []},
-          {Credo.Check.Refactor.FilterCount, []},
           {Credo.Check.Refactor.FilterFilter, []},
           {Credo.Check.Refactor.RejectReject, []},
-          {Credo.Check.Refactor.RedundantWithClauseResult, []},
 
           #
           ## Warnings
@@ -170,6 +149,29 @@
           {Credo.Check.Warning.UnsafeExec, []}
         ],
         disabled: [
+          #
+          # Checks that are handled by Styler
+          {Credo.Check.Consistency.ParameterPatternMatching, []},
+          {Credo.Check.Readability.AliasOrder, []},
+          {Credo.Check.Readability.LargeNumbers, []},
+          {Credo.Check.Readability.ModuleDoc, []},
+          {Credo.Check.Readability.MultiAlias, []},
+          {Credo.Check.Readability.ParenthesesOnZeroArityDefs, []},
+          {Credo.Check.Readability.PipeIntoAnonymousFunctions, []},
+          {Credo.Check.Readability.PreferImplicitTry, []},
+          {Credo.Check.Readability.StrictModuleLayout,
+           ignore: [:behaviour], order: [:shortdoc, :moduledoc, :use, :import, :alias, :require]},
+          {Credo.Check.Readability.UnnecessaryAliasExpansion, []},
+          {Credo.Check.Readability.WithSingleClause, []},
+          {Credo.Check.Refactor.CondStatements, []},
+          {Credo.Check.Refactor.FilterCount, []},
+          {Credo.Check.Refactor.MapJoin, []},
+          {Credo.Check.Refactor.NegatedConditionsInUnless, []},
+          {Credo.Check.Refactor.NegatedConditionsWithElse, []},
+          {Credo.Check.Refactor.RedundantWithClauseResult, []},
+          {Credo.Check.Refactor.UnlessWithElse, []},
+          {Credo.Check.Refactor.WithClauses, []},
+
           #
           # Checks scheduled for next check update (opt-in for now, just replace `false` with `[]`)
 
diff --git a/.formatter.exs b/.formatter.exs
index 32ad3a95..a2af9da2 100644
--- a/.formatter.exs
+++ b/.formatter.exs
@@ -1,5 +1,6 @@
 # Used by "mix format"
 [
   import_deps: [:typed_struct],
-  inputs: ["{mix,.credo,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
+  inputs: ["{mix,.credo,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"],
+  plugins: [Styler]
 ]
diff --git a/lib/config_cat/cache.ex b/lib/config_cat/cache.ex
index 27d91c72..573dae7d 100644
--- a/lib/config_cat/cache.ex
+++ b/lib/config_cat/cache.ex
@@ -8,8 +8,8 @@ defmodule ConfigCat.Cache do
   alias ConfigCat.ConfigEntry
   alias ConfigCat.Hooks
 
-  require ConfigCat.Constants, as: Constants
   require ConfigCat.ConfigCatLogger, as: ConfigCatLogger
+  require ConfigCat.Constants, as: Constants
 
   defmodule State do
     @moduledoc false
@@ -53,7 +53,8 @@ defmodule ConfigCat.Cache do
   def generate_key(sdk_key) do
     key = "#{sdk_key}_#{Constants.config_filename()}_#{Constants.serialization_format_version()}"
 
-    :crypto.hash(:sha, key)
+    :sha
+    |> :crypto.hash(key)
     |> Base.encode16(case: :lower)
   end
 
diff --git a/lib/config_cat/cache_policy.ex b/lib/config_cat/cache_policy.ex
index d08fe24b..82412549 100644
--- a/lib/config_cat/cache_policy.ex
+++ b/lib/config_cat/cache_policy.ex
@@ -36,6 +36,8 @@ defmodule ConfigCat.CachePolicy do
   See `manual/0` below for details.
   """
 
+  @behaviour ConfigCat.CachePolicy.Behaviour
+
   alias ConfigCat.CachePolicy.Auto
   alias ConfigCat.CachePolicy.Behaviour
   alias ConfigCat.CachePolicy.Lazy
@@ -43,8 +45,6 @@ defmodule ConfigCat.CachePolicy do
 
   require ConfigCat.Constants, as: Constants
 
-  @behaviour Behaviour
-
   @typedoc "Options for auto-polling mode."
   @type auto_options :: [
           {:max_init_wait_time_seconds, non_neg_integer()}
diff --git a/lib/config_cat/cache_policy/auto.ex b/lib/config_cat/cache_policy/auto.ex
index 65423306..128b8fa2 100644
--- a/lib/config_cat/cache_policy/auto.ex
+++ b/lib/config_cat/cache_policy/auto.ex
@@ -37,8 +37,7 @@ defmodule ConfigCat.CachePolicy.Auto do
   @default_poll_interval_seconds 60
 
   typedstruct enforce: true do
-    field :max_init_wait_time_ms, non_neg_integer(),
-      default: @default_max_init_wait_time_seconds * 1000
+    field :max_init_wait_time_ms, non_neg_integer(), default: @default_max_init_wait_time_seconds * 1000
 
     field :mode, String.t(), default: "a"
     field :poll_interval_ms, pos_integer(), default: @default_poll_interval_seconds * 1000
@@ -56,11 +55,13 @@ defmodule ConfigCat.CachePolicy.Auto do
       Keyword.pop(options, :poll_interval_seconds, @default_poll_interval_seconds)
 
     options =
-      [
-        max_init_wait_time_ms: rounded_ms(max_init_wait_time_seconds, 0),
-        poll_interval_ms: rounded_ms(poll_interval_seconds, 1)
-      ]
-      |> Keyword.merge(options)
+      Keyword.merge(
+        [
+          max_init_wait_time_ms: rounded_ms(max_init_wait_time_seconds, 0),
+          poll_interval_ms: rounded_ms(poll_interval_seconds, 1)
+        ],
+        options
+      )
 
     struct(__MODULE__, options)
   end
@@ -69,7 +70,7 @@ defmodule ConfigCat.CachePolicy.Auto do
     seconds
     |> max(min_value)
     |> Kernel.*(1000)
-    |> round
+    |> round()
   end
 
   @impl GenServer
diff --git a/lib/config_cat/cache_policy/null.ex b/lib/config_cat/cache_policy/null.ex
index dd3ca923..ef5aa0de 100644
--- a/lib/config_cat/cache_policy/null.ex
+++ b/lib/config_cat/cache_policy/null.ex
@@ -2,13 +2,12 @@ defmodule ConfigCat.CachePolicy.Null do
   @moduledoc false
 
   # The CachePolicy that gets used in :local_only mode
+  @behaviour ConfigCat.CachePolicy.Behaviour
 
   alias ConfigCat.CachePolicy.Behaviour
 
   require ConfigCat.ConfigCatLogger, as: ConfigCatLogger
 
-  @behaviour Behaviour
-
   @impl Behaviour
   def get(_instance_id) do
     # Should never be called
@@ -37,7 +36,6 @@ defmodule ConfigCat.CachePolicy.Null do
 
   @impl Behaviour
   def force_refresh(_instance_id) do
-    {:error,
-     "The SDK uses the `:local_only` override behavior which prevents making HTTP requests."}
+    {:error, "The SDK uses the `:local_only` override behavior which prevents making HTTP requests."}
   end
 end
diff --git a/lib/config_cat/client.ex b/lib/config_cat/client.ex
index c2cb673d..2b938920 100644
--- a/lib/config_cat/client.ex
+++ b/lib/config_cat/client.ex
@@ -11,8 +11,8 @@ defmodule ConfigCat.Client do
   alias ConfigCat.Rollout
   alias ConfigCat.User
 
-  require ConfigCat.Constants, as: Constants
   require ConfigCat.ConfigCatLogger, as: ConfigCatLogger
+  require ConfigCat.Constants, as: Constants
 
   defmodule State do
     @moduledoc false
@@ -96,17 +96,19 @@ defmodule ConfigCat.Client do
 
   @impl GenServer
   def handle_call({:get_key_and_value, variation_id}, _from, %State{} = state) do
-    with {:ok, settings, _fetch_time_ms} <- cached_settings(state),
-         result <- Enum.find_value(settings, nil, &entry_matching(&1, variation_id)) do
-      if is_nil(result) do
-        ConfigCatLogger.error(
-          "Could not find the setting for the specified variation ID: '#{variation_id}'",
-          event_id: 2011
-        )
-      end
+    case cached_settings(state) do
+      {:ok, settings, _fetch_time_ms} ->
+        result = Enum.find_value(settings, nil, &entry_matching(&1, variation_id))
+
+        if is_nil(result) do
+          ConfigCatLogger.error(
+            "Could not find the setting for the specified variation ID: '#{variation_id}'",
+            event_id: 2011
+          )
+        end
+
+        {:reply, result, state}
 
-      {:reply, result, state}
-    else
       _ ->
         ConfigCatLogger.error(
           "Config JSON is not present. Returning nil.",
@@ -207,8 +209,6 @@ defmodule ConfigCat.Client do
   defp value_matching(key, value, variation_id) do
     if Map.get(value, Constants.variation_id(), nil) == variation_id do
       {key, Map.get(value, Constants.value())}
-    else
-      nil
     end
   end
 
diff --git a/lib/config_cat/config_cat_logger.ex b/lib/config_cat/config_cat_logger.ex
index 03db7370..24f6e9ac 100644
--- a/lib/config_cat/config_cat_logger.ex
+++ b/lib/config_cat/config_cat_logger.ex
@@ -19,7 +19,7 @@ defmodule ConfigCat.ConfigCatLogger do
 
       Logger.error(fn -> module.formatted_message(message, metadata) end)
 
-      instance_id = Logger.metadata() |> Keyword.get(:instance_id)
+      instance_id = Keyword.get(Logger.metadata(), :instance_id)
 
       if instance_id do
         ConfigCat.Hooks.invoke_on_error(instance_id, message)
diff --git a/lib/config_cat/config_fetcher.ex b/lib/config_cat/config_fetcher.ex
index 3227dcaa..90941a44 100644
--- a/lib/config_cat/config_fetcher.ex
+++ b/lib/config_cat/config_fetcher.ex
@@ -34,6 +34,8 @@ end
 defmodule ConfigCat.CacheControlConfigFetcher do
   @moduledoc false
 
+  @behaviour ConfigCat.ConfigFetcher
+
   use GenServer
 
   alias ConfigCat.Config
@@ -42,8 +44,8 @@ defmodule ConfigCat.CacheControlConfigFetcher do
   alias ConfigCat.ConfigFetcher.FetchError
   alias HTTPoison.Response
 
-  require ConfigCat.Constants, as: Constants
   require ConfigCat.ConfigCatLogger, as: ConfigCatLogger
+  require ConfigCat.Constants, as: Constants
   require ConfigCat.RedirectMode, as: RedirectMode
 
   defmodule State do
@@ -108,8 +110,6 @@ defmodule ConfigCat.CacheControlConfigFetcher do
           | {:sdk_key, String.t()}
   @type options :: [option]
 
-  @behaviour ConfigFetcher
-
   @spec start_link(options()) :: GenServer.on_start()
   def start_link(options) do
     instance_id = Keyword.fetch!(options, :instance_id)
@@ -194,7 +194,7 @@ defmodule ConfigCat.CacheControlConfigFetcher do
   end
 
   defp base_headers(%State{mode: mode}) do
-    version = Application.spec(:configcat, :vsn) |> to_string()
+    version = :configcat |> Application.spec(:vsn) |> to_string()
     user_agent = "ConfigCat-Elixir/#{mode}-#{version}"
 
     [
@@ -221,18 +221,12 @@ defmodule ConfigCat.CacheControlConfigFetcher do
   # This function is slightly complex, but still reasonably understandable.
   # Breaking it up doesn't seem like it will help much.
   # credo:disable-for-next-line Credo.Check.Refactor.CyclomaticComplexity
-  defp handle_response(
-         %Response{status_code: code, body: raw_config, headers: headers},
-         %State{} = state,
-         etag
-       )
+  defp handle_response(%Response{status_code: code, body: raw_config, headers: headers}, %State{} = state, etag)
        when code >= 200 and code < 300 do
-    ConfigCatLogger.debug(
-      "ConfigCat configuration json fetch response code: #{code} Cached: #{extract_etag(headers)}"
-    )
+    ConfigCatLogger.debug("ConfigCat configuration json fetch response code: #{code} Cached: #{extract_etag(headers)}")
 
     with {:ok, config} <- Jason.decode(raw_config),
-         new_etag <- extract_etag(headers),
+         new_etag = extract_etag(headers),
          %{base_url: new_base_url, custom_endpoint?: custom_endpoint?, redirects: redirects} <-
            state,
          {base_url, redirect_mode} <- Config.preferences(config) do
@@ -288,8 +282,7 @@ defmodule ConfigCat.CacheControlConfigFetcher do
     {:ok, :unchanged, state}
   end
 
-  defp handle_response(%Response{status_code: status} = response, %State{} = state, _etag)
-       when status in [403, 404] do
+  defp handle_response(%Response{status_code: status} = response, %State{} = state, _etag) when status in [403, 404] do
     ConfigCatLogger.error(
       "Your SDK Key seems to be wrong. You can find the valid SDKKey at https://app.configcat.com/sdkkey. Received unexpected response: #{inspect(response)}",
       event_id: 1100
@@ -311,10 +304,7 @@ defmodule ConfigCat.CacheControlConfigFetcher do
     {:error, error, state}
   end
 
-  defp handle_error(
-         {:error, %HTTPoison.Error{reason: :checkout_timeout} = error},
-         %State{} = state
-       ) do
+  defp handle_error({:error, %HTTPoison.Error{reason: :checkout_timeout} = error}, %State{} = state) do
     ConfigCatLogger.error(
       "Request timed out while trying to fetch config JSON. Timeout values: [connect: #{state.connect_timeout_milliseconds}ms, read: #{state.read_timeout_milliseconds}ms]",
       event_id: 1102
diff --git a/lib/config_cat/fetch_time.ex b/lib/config_cat/fetch_time.ex
index 81eeb406..3c128e14 100644
--- a/lib/config_cat/fetch_time.ex
+++ b/lib/config_cat/fetch_time.ex
@@ -4,7 +4,7 @@ defmodule ConfigCat.FetchTime do
   @type t :: non_neg_integer()
 
   @spec now_ms :: t()
-  def now_ms, do: DateTime.utc_now() |> DateTime.to_unix(:millisecond)
+  def now_ms, do: DateTime.to_unix(DateTime.utc_now(), :millisecond)
 
   @spec to_datetime(t()) :: {:ok, DateTime.t()} | {:error, atom()}
   def to_datetime(ms) do
diff --git a/lib/config_cat/in_memory_cache.ex b/lib/config_cat/in_memory_cache.ex
index 53ffb2b0..3b97c335 100644
--- a/lib/config_cat/in_memory_cache.ex
+++ b/lib/config_cat/in_memory_cache.ex
@@ -1,12 +1,12 @@
 defmodule ConfigCat.InMemoryCache do
   @moduledoc false
 
+  @behaviour ConfigCat.ConfigCache
+
   use GenServer
 
   alias ConfigCat.ConfigCache
 
-  @behaviour ConfigCache
-
   @spec start_link(keyword()) :: GenServer.on_start()
   def start_link(_options) do
     GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
diff --git a/lib/config_cat/local_file_data_source.ex b/lib/config_cat/local_file_data_source.ex
index e2f96bde..468cd5b8 100644
--- a/lib/config_cat/local_file_data_source.ex
+++ b/lib/config_cat/local_file_data_source.ex
@@ -93,8 +93,8 @@ defmodule ConfigCat.LocalFileDataSource do
       with {:ok, %{mtime: timestamp}} <- File.stat(filename, time: :posix) do
         unless FileCache.cached_timestamp(cache) == timestamp do
           with {:ok, contents} <- File.read(filename),
-               {:ok, data} <- Jason.decode(contents),
-               settings <- normalize(data) do
+               {:ok, data} <- Jason.decode(contents) do
+            settings = normalize(data)
             FileCache.update(cache, settings, timestamp)
           else
             error ->
diff --git a/lib/config_cat/rollout.ex b/lib/config_cat/rollout.ex
index f722b20d..816da33f 100644
--- a/lib/config_cat/rollout.ex
+++ b/lib/config_cat/rollout.ex
@@ -6,8 +6,8 @@ defmodule ConfigCat.Rollout do
   alias ConfigCat.Rollout.Comparator
   alias ConfigCat.User
 
-  require ConfigCat.Constants, as: Constants
   require ConfigCat.ConfigCatLogger, as: ConfigCatLogger
+  require ConfigCat.Constants, as: Constants
 
   @spec evaluate(
           Config.key(),
@@ -24,10 +24,10 @@ defmodule ConfigCat.Rollout do
 
       with {:ok, valid_user} <- validate_user(user),
            {:ok, setting_descriptor} <- setting_descriptor(settings, key, default_value),
-           setting_variation <-
+           setting_variation =
              Map.get(setting_descriptor, Constants.variation_id(), default_variation_id),
-           rollout_rules <- Map.get(setting_descriptor, Constants.rollout_rules(), []),
-           percentage_rules <- Map.get(setting_descriptor, Constants.percentage_rules(), []),
+           rollout_rules = Map.get(setting_descriptor, Constants.rollout_rules(), []),
+           percentage_rules = Map.get(setting_descriptor, Constants.percentage_rules(), []),
            {value, variation, rule, percentage_rule} <-
              evaluate_rules(rollout_rules, percentage_rules, valid_user, key, logs) do
         variation = variation || setting_variation
@@ -121,47 +121,47 @@ defmodule ConfigCat.Rollout do
   end
 
   defp evaluate_rollout_rule(rule, default, user, logs) do
-    with comparison_attribute <- Map.get(rule, Constants.comparison_attribute()),
-         comparison_value <- Map.get(rule, Constants.comparison_value()),
-         comparator <- Map.get(rule, Constants.comparator()),
-         value <- Map.get(rule, Constants.value()),
-         variation <- Map.get(rule, Constants.variation_id()) do
-      case User.get_attribute(user, comparison_attribute) do
-        nil ->
-          log_no_match(logs, comparison_attribute, nil, comparator, comparison_value)
-          {:cont, default}
-
-        user_value ->
-          case Comparator.compare(comparator, to_string(user_value), to_string(comparison_value)) do
-            {:ok, true} ->
-              log_match(
-                logs,
-                comparison_attribute,
-                user_value,
-                comparator,
-                comparison_value,
-                value
-              )
-
-              {:halt, {value, variation, rule}}
-
-            {:ok, false} ->
-              log_no_match(logs, comparison_attribute, user_value, comparator, comparison_value)
-              {:cont, default}
-
-            {:error, error} ->
-              log_validation_error(
-                logs,
-                comparison_attribute,
-                user_value,
-                comparator,
-                comparison_value,
-                error
-              )
-
-              {:cont, default}
-          end
-      end
+    comparison_attribute = Map.get(rule, Constants.comparison_attribute())
+    comparison_value = Map.get(rule, Constants.comparison_value())
+    comparator = Map.get(rule, Constants.comparator())
+    value = Map.get(rule, Constants.value())
+    variation = Map.get(rule, Constants.variation_id())
+
+    case User.get_attribute(user, comparison_attribute) do
+      nil ->
+        log_no_match(logs, comparison_attribute, nil, comparator, comparison_value)
+        {:cont, default}
+
+      user_value ->
+        case Comparator.compare(comparator, to_string(user_value), to_string(comparison_value)) do
+          {:ok, true} ->
+            log_match(
+              logs,
+              comparison_attribute,
+              user_value,
+              comparator,
+              comparison_value,
+              value
+            )
+
+            {:halt, {value, variation, rule}}
+
+          {:ok, false} ->
+            log_no_match(logs, comparison_attribute, user_value, comparator, comparison_value)
+            {:cont, default}
+
+          {:error, error} ->
+            log_validation_error(
+              logs,
+              comparison_attribute,
+              user_value,
+              comparator,
+              comparison_value,
+              error
+            )
+
+            {:cont, default}
+        end
     end
   end
 
@@ -198,7 +198,8 @@ defmodule ConfigCat.Rollout do
     hash_candidate = "#{key}#{user_key}"
 
     {hash_value, _} =
-      :crypto.hash(:sha, hash_candidate)
+      :sha
+      |> :crypto.hash(hash_candidate)
       |> Base.encode16()
       |> String.slice(0, 7)
       |> Integer.parse(16)
@@ -231,14 +232,7 @@ defmodule ConfigCat.Rollout do
     )
   end
 
-  defp log_validation_error(
-         logs,
-         comparison_attribute,
-         user_value,
-         comparator,
-         comparison_value,
-         error
-       ) do
+  defp log_validation_error(logs, comparison_attribute, user_value, comparator, comparison_value, error) do
     message =
       "Evaluating rule: [#{comparison_attribute}:#{user_value}] [#{Comparator.description(comparator)}] [#{comparison_value}] => SKIP rule. Validation error: #{inspect(error)}"
 
diff --git a/lib/config_cat/rollout/comparator.ex b/lib/config_cat/rollout/comparator.ex
index db55c366..0e6b2654 100644
--- a/lib/config_cat/rollout/comparator.ex
+++ b/lib/config_cat/rollout/comparator.ex
@@ -55,59 +55,47 @@ defmodule ConfigCat.Rollout.Comparator do
 
   @spec compare(comparator(), String.t(), String.t()) :: result()
 
-  def compare(@is_one_of, user_value, comparison_value),
-    do: is_one_of(user_value, comparison_value)
+  def compare(@is_one_of, user_value, comparison_value), do: is_one_of(user_value, comparison_value)
 
-  def compare(@is_not_one_of, user_value, comparison_value),
-    do: is_one_of(user_value, comparison_value) |> negate()
+  def compare(@is_not_one_of, user_value, comparison_value), do: user_value |> is_one_of(comparison_value) |> negate()
 
-  def compare(@contains, user_value, comparison_value),
-    do: contains(user_value, comparison_value)
+  def compare(@contains, user_value, comparison_value), do: contains(user_value, comparison_value)
 
-  def compare(@does_not_contain, user_value, comparison_value),
-    do: contains(user_value, comparison_value) |> negate()
+  def compare(@does_not_contain, user_value, comparison_value), do: user_value |> contains(comparison_value) |> negate()
 
-  def compare(@is_one_of_semver, user_value, comparison_value),
-    do: is_one_of_semver(user_value, comparison_value)
+  def compare(@is_one_of_semver, user_value, comparison_value), do: is_one_of_semver(user_value, comparison_value)
 
   def compare(@is_not_one_of_semver, user_value, comparison_value),
-    do: is_one_of_semver(user_value, comparison_value) |> negate()
+    do: user_value |> is_one_of_semver(comparison_value) |> negate()
 
-  def compare(@less_than_semver, user_value, comparison_value),
-    do: compare_semver(user_value, comparison_value, [:lt])
+  def compare(@less_than_semver, user_value, comparison_value), do: compare_semver(user_value, comparison_value, [:lt])
 
   def compare(@less_than_equal_semver, user_value, comparison_value),
     do: compare_semver(user_value, comparison_value, [:lt, :eq])
 
-  def compare(@greater_than_semver, user_value, comparison_value),
-    do: compare_semver(user_value, comparison_value, [:gt])
+  def compare(@greater_than_semver, user_value, comparison_value), do: compare_semver(user_value, comparison_value, [:gt])
 
   def compare(@greater_than_equal_semver, user_value, comparison_value),
     do: compare_semver(user_value, comparison_value, [:gt, :eq])
 
-  def compare(@equals_number, user_value, comparison_value),
-    do: compare_numbers(user_value, comparison_value, &==/2)
+  def compare(@equals_number, user_value, comparison_value), do: compare_numbers(user_value, comparison_value, &==/2)
 
-  def compare(@not_equals_number, user_value, comparison_value),
-    do: compare_numbers(user_value, comparison_value, &!==/2)
+  def compare(@not_equals_number, user_value, comparison_value), do: compare_numbers(user_value, comparison_value, &!==/2)
 
-  def compare(@less_than_number, user_value, comparison_value),
-    do: compare_numbers(user_value, comparison_value, &</2)
+  def compare(@less_than_number, user_value, comparison_value), do: compare_numbers(user_value, comparison_value, &</2)
 
   def compare(@less_than_equal_number, user_value, comparison_value),
     do: compare_numbers(user_value, comparison_value, &<=/2)
 
-  def compare(@greater_than_number, user_value, comparison_value),
-    do: compare_numbers(user_value, comparison_value, &>/2)
+  def compare(@greater_than_number, user_value, comparison_value), do: compare_numbers(user_value, comparison_value, &>/2)
 
   def compare(@greater_than_equal_number, user_value, comparison_value),
     do: compare_numbers(user_value, comparison_value, &>=/2)
 
-  def compare(@is_one_of_sensitive, user_value, comparison_value),
-    do: is_one_of_sensitive(user_value, comparison_value)
+  def compare(@is_one_of_sensitive, user_value, comparison_value), do: is_one_of_sensitive(user_value, comparison_value)
 
   def compare(@is_not_one_of_sensitive, user_value, comparison_value),
-    do: is_one_of_sensitive(user_value, comparison_value) |> negate()
+    do: user_value |> is_one_of_sensitive(comparison_value) |> negate()
 
   def compare(_comparator, _user_value, _comparison_value) do
     {:ok, false}
@@ -161,7 +149,8 @@ defmodule ConfigCat.Rollout.Comparator do
   end
 
   defp hash_value(value) do
-    :crypto.hash(:sha, value)
+    :sha
+    |> :crypto.hash(value)
     |> Base.encode16()
     |> String.downcase()
   end
diff --git a/lib/config_cat/supervisor.ex b/lib/config_cat/supervisor.ex
index fcb926c2..41f00b2e 100644
--- a/lib/config_cat/supervisor.ex
+++ b/lib/config_cat/supervisor.ex
@@ -80,14 +80,16 @@ defmodule ConfigCat.Supervisor do
     override_behaviour = OverrideDataSource.behaviour(options[:flag_overrides])
 
     children =
-      [
-        hooks(options),
-        cache(options),
-        config_fetcher(options, override_behaviour),
-        cache_policy(options, override_behaviour),
-        client(options, override_behaviour)
-      ]
-      |> Enum.reject(&is_nil/1)
+      Enum.reject(
+        [
+          hooks(options),
+          cache(options),
+          config_fetcher(options, override_behaviour),
+          cache_policy(options, override_behaviour),
+          client(options, override_behaviour)
+        ],
+        &is_nil/1
+      )
 
     Supervisor.init(children, strategy: :one_for_one)
   end
diff --git a/lib/config_cat/user.ex b/lib/config_cat/user.ex
index 717ea7dd..4f0866a7 100644
--- a/lib/config_cat/user.ex
+++ b/lib/config_cat/user.ex
@@ -74,8 +74,7 @@ defmodule ConfigCat.User do
   """
   @spec new(String.t(), options()) :: t()
   def new(identifier, other_props \\ []) do
-    %__MODULE__{identifier: identifier}
-    |> struct!(other_props)
+    struct!(%__MODULE__{identifier: identifier}, other_props)
   end
 
   @doc false
diff --git a/mix.exs b/mix.exs
index ba88878f..7c10ea73 100644
--- a/mix.exs
+++ b/mix.exs
@@ -81,6 +81,7 @@ defmodule ConfigCat.MixProject do
       {:jason, "~> 1.2"},
       {:mix_test_interactive, "~> 1.2", only: :dev, runtime: false},
       {:mox, "~> 1.1", only: :test},
+      {:styler, "~> 0.11", only: [:dev, :test], runtime: false},
       {:typed_struct, "~> 0.3.0"}
     ]
   end
diff --git a/mix.lock b/mix.lock
index 9a1dfe60..ee930d23 100644
--- a/mix.lock
+++ b/mix.lock
@@ -24,6 +24,7 @@
   "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"},
   "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"},
   "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},
+  "styler": {:hex, :styler, "0.11.1", "1bf6a13f49c00c4e77855cd2dbd6fe5518b6bfb977e76fdb2fa088d64f839194", [:mix], [], "hexpm", "8d995b3e7a787645a09a9a7382e17fb99d4bb63f4cf8390a2aaf0afa8d4b2f7d"},
   "typed_struct": {:hex, :typed_struct, "0.3.0", "939789e3c1dca39d7170c87f729127469d1315dcf99fee8e152bb774b17e7ff7", [:mix], [], "hexpm", "c50bd5c3a61fe4e198a8504f939be3d3c85903b382bde4865579bc23111d1b6d"},
   "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
   "uuid": {:hex, :uuid, "1.1.8", "e22fc04499de0de3ed1116b770c7737779f226ceefa0badb3592e64d5cfb4eb9", [:mix], [], "hexpm", "c790593b4c3b601f5dc2378baae7efaf5b3d73c4c6456ba85759905be792f2ac"},
diff --git a/test/config_cat/cache_policy/auto_test.exs b/test/config_cat/cache_policy/auto_test.exs
index b710f04a..d9b1b162 100644
--- a/test/config_cat/cache_policy/auto_test.exs
+++ b/test/config_cat/cache_policy/auto_test.exs
@@ -78,8 +78,7 @@ defmodule ConfigCat.CachePolicy.AutoTest do
       %{entry: old_entry, settings: old_settings} = make_old_entry()
       old_entry = Map.update!(old_entry, :fetch_time_ms, &(&1 - policy.poll_interval_ms - 1))
 
-      MockFetcher
-      |> expect(:fetch, fn _id, _etag ->
+      expect(MockFetcher, :fetch, fn _id, _etag ->
         Process.sleep(wait_time_ms * 5)
         {:ok, entry}
       end)
@@ -165,7 +164,7 @@ defmodule ConfigCat.CachePolicy.AutoTest do
   describe "calling the config-changed callback" do
     setup do
       test_pid = self()
-      instance_id = UUID.uuid4() |> String.to_atom()
+      instance_id = String.to_atom(UUID.uuid4())
 
       %{entry: old_entry, settings: old_settings} = make_old_entry()
 
@@ -253,7 +252,6 @@ defmodule ConfigCat.CachePolicy.AutoTest do
   end
 
   defp wait_for_poll(policy) do
-    (policy.poll_interval_ms + 50)
-    |> Process.sleep()
+    Process.sleep(policy.poll_interval_ms + 50)
   end
 end
diff --git a/test/config_cat/cache_test.exs b/test/config_cat/cache_test.exs
index b787fc69..bf10da1e 100644
--- a/test/config_cat/cache_test.exs
+++ b/test/config_cat/cache_test.exs
@@ -30,9 +30,7 @@ defmodule ConfigCat.CacheTest do
       start_supervised!({Hooks, hooks: [on_error: on_error], instance_id: instance_id})
 
       cache =
-        start_supervised!(
-          {Cache, cache: MockConfigCache, cache_key: cache_key, instance_id: instance_id}
-        )
+        start_supervised!({Cache, cache: MockConfigCache, cache_key: cache_key, instance_id: instance_id})
 
       Mox.allow(MockConfigCache, self(), cache)
 
@@ -43,9 +41,7 @@ defmodule ConfigCat.CacheTest do
       cache_key: cache_key,
       instance_id: instance_id
     } do
-      MockConfigCache
-      |> expect(:get, fn ^cache_key -> {:ok, @serialized} end)
-
+      expect(MockConfigCache, :get, fn ^cache_key -> {:ok, @serialized} end)
       refute_received {:on_error, _message}
 
       assert {:ok, @entry} = Cache.get(instance_id)
@@ -55,9 +51,7 @@ defmodule ConfigCat.CacheTest do
       cache_key: cache_key,
       instance_id: instance_id
     } do
-      MockConfigCache
-      |> expect(:get, 1, fn ^cache_key -> {:ok, @serialized} end)
-
+      expect(MockConfigCache, :get, 1, fn ^cache_key -> {:ok, @serialized} end)
       {:ok, @entry} = Cache.get(instance_id)
 
       assert {:ok, @entry} = Cache.get(instance_id)
@@ -67,9 +61,7 @@ defmodule ConfigCat.CacheTest do
       cache_key: cache_key,
       instance_id: instance_id
     } do
-      MockConfigCache
-      |> expect(:set, fn ^cache_key, @serialized -> :ok end)
-
+      expect(MockConfigCache, :set, fn ^cache_key, @serialized -> :ok end)
       assert :ok = Cache.set(instance_id, @entry)
     end
 
@@ -90,9 +82,7 @@ defmodule ConfigCat.CacheTest do
     test "calls on_error hook when cache format is invalid", %{
       instance_id: instance_id
     } do
-      MockConfigCache
-      |> stub(:get, fn _cache_key -> {:ok, ""} end)
-
+      stub(MockConfigCache, :get, fn _cache_key -> {:ok, ""} end)
       {:error, :not_found} = Cache.get(instance_id)
 
       assert_received {:on_error, message}
diff --git a/test/config_cat/config_fetcher_test.exs b/test/config_cat/config_fetcher_test.exs
index 3ee88f57..3c9fa08b 100644
--- a/test/config_cat/config_fetcher_test.exs
+++ b/test/config_cat/config_fetcher_test.exs
@@ -23,7 +23,7 @@ defmodule ConfigCat.ConfigFetcherTest do
   @fetcher_options %{mode: @mode, sdk_key: @sdk_key}
 
   defp start_fetcher(%{mode: mode, sdk_key: sdk_key}, options \\ []) do
-    instance_id = UUID.uuid4() |> String.to_atom()
+    instance_id = String.to_atom(UUID.uuid4())
 
     start_supervised!({Hooks, instance_id: instance_id})
 
@@ -41,8 +41,7 @@ defmodule ConfigCat.ConfigFetcherTest do
 
     url = global_config_url()
 
-    MockAPI
-    |> stub(:get, fn ^url, _headers, _options ->
+    stub(MockAPI, :get, fn ^url, _headers, _options ->
       {:ok, %Response{status_code: 200, body: @raw_config, headers: [{"ETag", @etag}]}}
     end)
 
@@ -64,8 +63,7 @@ defmodule ConfigCat.ConfigFetcherTest do
 
     url = global_config_url()
 
-    MockAPI
-    |> expect(:get, 1, fn ^url, _headers, _options ->
+    expect(MockAPI, :get, 1, fn ^url, _headers, _options ->
       Process.sleep(50)
       {:ok, %Response{status_code: 200, body: @raw_config, headers: [{"ETag", @etag}]}}
     end)
@@ -90,8 +88,7 @@ defmodule ConfigCat.ConfigFetcherTest do
 
     response = %Response{status_code: 200, body: @raw_config}
 
-    MockAPI
-    |> stub(:get, fn _url, headers, _options ->
+    stub(MockAPI, :get, fn _url, headers, _options ->
       assert_user_agent_matches(headers, ~r"^ConfigCat-Elixir/#{@mode}-")
 
       {:ok, response}
@@ -109,8 +106,7 @@ defmodule ConfigCat.ConfigFetcherTest do
       headers: [{"ETag", @etag}]
     }
 
-    MockAPI
-    |> stub(:get, fn _url, headers, _options ->
+    stub(MockAPI, :get, fn _url, headers, _options ->
       assert List.keyfind(headers, "ETag", 0) == nil
       {:ok, initial_response}
     end)
@@ -122,8 +118,7 @@ defmodule ConfigCat.ConfigFetcherTest do
       headers: [{"ETag", @etag}]
     }
 
-    MockAPI
-    |> expect(:get, fn _url, headers, _options ->
+    expect(MockAPI, :get, fn _url, headers, _options ->
       assert {"If-None-Match", @etag} = List.keyfind(headers, "If-None-Match", 0)
       {:ok, not_modified_response}
     end)
@@ -139,9 +134,7 @@ defmodule ConfigCat.ConfigFetcherTest do
       headers: [{"ETag", @etag}]
     }
 
-    MockAPI
-    |> stub(:get, fn _url, _headers, _options -> {:ok, response} end)
-
+    stub(MockAPI, :get, fn _url, _headers, _options -> {:ok, response} end)
     assert {:ok, :unchanged} = ConfigFetcher.fetch(fetcher, @etag)
   end
 
@@ -151,9 +144,7 @@ defmodule ConfigCat.ConfigFetcherTest do
 
     response = %Response{status_code: 503}
 
-    MockAPI
-    |> stub(:get, fn _url, _headers, _options -> {:ok, response} end)
-
+    stub(MockAPI, :get, fn _url, _headers, _options -> {:ok, response} end)
     assert {:error, %FetchError{reason: ^response}} = ConfigFetcher.fetch(fetcher, nil)
   end
 
@@ -163,9 +154,7 @@ defmodule ConfigCat.ConfigFetcherTest do
 
     error = %HTTPoison.Error{reason: "failed"}
 
-    MockAPI
-    |> stub(:get, fn _url, _headers, _options -> {:error, error} end)
-
+    stub(MockAPI, :get, fn _url, _headers, _options -> {:error, error} end)
     assert {:error, %FetchError{reason: ^error}} = ConfigFetcher.fetch(fetcher, nil)
   end
 
@@ -176,11 +165,7 @@ defmodule ConfigCat.ConfigFetcherTest do
 
     url = config_url(base_url, @sdk_key)
 
-    MockAPI
-    |> expect(:get, fn ^url, _headers, _options ->
-      {:ok, %Response{status_code: 200, body: @raw_config}}
-    end)
-
+    expect(MockAPI, :get, fn ^url, _headers, _options -> {:ok, %Response{status_code: 200, body: @raw_config}} end)
     {:ok, _} = ConfigFetcher.fetch(fetcher, nil)
   end
 
@@ -189,8 +174,7 @@ defmodule ConfigCat.ConfigFetcherTest do
 
     response = %Response{status_code: 200, body: @raw_config}
 
-    MockAPI
-    |> expect(:get, fn _url, _headers, options ->
+    expect(MockAPI, :get, fn _url, _headers, options ->
       assert Keyword.get(options, :recv_timeout) == 5000
       assert Keyword.get(options, :timeout) == 8000
       {:ok, response}
@@ -211,8 +195,7 @@ defmodule ConfigCat.ConfigFetcherTest do
 
     response = %Response{status_code: 200, body: @raw_config}
 
-    MockAPI
-    |> expect(:get, fn _url, _headers, options ->
+    expect(MockAPI, :get, fn _url, _headers, options ->
       assert Keyword.get(options, :recv_timeout) == read_timeout
       assert Keyword.get(options, :timeout) == connect_timeout
       {:ok, response}
@@ -227,8 +210,7 @@ defmodule ConfigCat.ConfigFetcherTest do
 
     response = %Response{status_code: 200, body: @raw_config}
 
-    MockAPI
-    |> expect(:get, fn _url, _headers, options ->
+    expect(MockAPI, :get, fn _url, _headers, options ->
       assert Keyword.get(options, :proxy) == proxy
       {:ok, response}
     end)
diff --git a/test/config_cat/data_governance_test.exs b/test/config_cat/data_governance_test.exs
index e9a6fbc9..03bd8c6d 100644
--- a/test/config_cat/data_governance_test.exs
+++ b/test/config_cat/data_governance_test.exs
@@ -25,7 +25,7 @@ defmodule ConfigCat.ConfigFetcher.DataGovernanceTest do
   @fetcher_options %{mode: @mode, sdk_key: @sdk_key}
 
   defp start_fetcher(%{mode: mode, sdk_key: sdk_key}, options) do
-    instance_id = UUID.uuid4() |> String.to_atom()
+    instance_id = String.to_atom(UUID.uuid4())
 
     start_supervised!({Hooks, instance_id: instance_id})
 
@@ -272,7 +272,8 @@ defmodule ConfigCat.ConfigFetcher.DataGovernanceTest do
   end
 
   defp stub_response(response_uri, redirect_mode) do
-    Config.new_with_preferences(response_uri, redirect_mode)
+    response_uri
+    |> Config.new_with_preferences(redirect_mode)
     |> Jason.encode!()
   end
 
diff --git a/test/config_cat/default_user_test.exs b/test/config_cat/default_user_test.exs
index e61fd697..b851ef45 100644
--- a/test/config_cat/default_user_test.exs
+++ b/test/config_cat/default_user_test.exs
@@ -48,26 +48,18 @@ defmodule ConfigCat.DefaultUserTest do
 
     test "get_all_values/1 uses the default user if no user is passed", %{client: client} do
       expected =
-        %{
-          "testBoolKey" => true,
-          "testStringKey" => "fake1"
-        }
-        |> Enum.sort()
+        Enum.sort(%{"testBoolKey" => true, "testStringKey" => "fake1"})
 
-      actual = ConfigCat.get_all_values(nil, client: client) |> Enum.sort()
+      actual = nil |> ConfigCat.get_all_values(client: client) |> Enum.sort()
       assert actual == expected
     end
 
     test "get_all_values/1 uses the passed user", %{client: client} do
       expected =
-        %{
-          "testBoolKey" => true,
-          "testStringKey" => "fake2"
-        }
-        |> Enum.sort()
+        Enum.sort(%{"testBoolKey" => true, "testStringKey" => "fake2"})
 
       user = User.new("test@test2.com")
-      actual = ConfigCat.get_all_values(user, client: client) |> Enum.sort()
+      actual = user |> ConfigCat.get_all_values(client: client) |> Enum.sort()
       assert actual == expected
     end
   end
@@ -94,26 +86,18 @@ defmodule ConfigCat.DefaultUserTest do
 
     test "get_all_values/1 uses the undefined user case if no user is passed", %{client: client} do
       expected =
-        %{
-          "testBoolKey" => true,
-          "testStringKey" => "testValue"
-        }
-        |> Enum.sort()
+        Enum.sort(%{"testBoolKey" => true, "testStringKey" => "testValue"})
 
-      actual = ConfigCat.get_all_values(nil, client: client) |> Enum.sort()
+      actual = nil |> ConfigCat.get_all_values(client: client) |> Enum.sort()
       assert actual == expected
     end
 
     test "get_all_values/1 uses the passed user", %{client: client} do
       expected =
-        %{
-          "testBoolKey" => true,
-          "testStringKey" => "fake2"
-        }
-        |> Enum.sort()
+        Enum.sort(%{"testBoolKey" => true, "testStringKey" => "fake2"})
 
       user = User.new("test@test2.com")
-      actual = ConfigCat.get_all_values(user, client: client) |> Enum.sort()
+      actual = user |> ConfigCat.get_all_values(client: client) |> Enum.sort()
       assert actual == expected
     end
   end
diff --git a/test/config_cat/hooks/impl_test.exs b/test/config_cat/hooks/impl_test.exs
index 2b47591e..75288163 100644
--- a/test/config_cat/hooks/impl_test.exs
+++ b/test/config_cat/hooks/impl_test.exs
@@ -23,8 +23,7 @@ defmodule ConfigCat.Hooks.ImplTest do
     end
 
     impl =
-      Impl.new()
-      |> Impl.add_hook(:on_error, callback)
+      Impl.add_hook(Impl.new(), :on_error, callback)
 
     assert :ok = Impl.invoke_hook(impl, :on_error, [message])
     assert_received {:on_error_called, ^message}
@@ -35,7 +34,8 @@ defmodule ConfigCat.Hooks.ImplTest do
     callback2 = fn -> send(self(), :callback2_called) end
 
     impl =
-      Impl.new(on_client_ready: callback1)
+      [on_client_ready: callback1]
+      |> Impl.new()
       |> Impl.add_hook(:on_client_ready, callback2)
 
     assert :ok = Impl.invoke_hook(impl, :on_client_ready, [])
@@ -50,7 +50,8 @@ defmodule ConfigCat.Hooks.ImplTest do
     good_callback = fn -> send(self(), :good_callback_called) end
 
     impl =
-      Impl.new(on_client_ready: fail_callback)
+      [on_client_ready: fail_callback]
+      |> Impl.new()
       |> Impl.add_hook(:on_client_ready, good_callback)
 
     assert :ok = Impl.invoke_hook(impl, :on_client_ready, [])
diff --git a/test/config_cat/hooks_test.exs b/test/config_cat/hooks_test.exs
index d7587138..62a1f24c 100644
--- a/test/config_cat/hooks_test.exs
+++ b/test/config_cat/hooks_test.exs
@@ -101,7 +101,8 @@ defmodule ConfigCat.HooksTest do
     {:ok, instance_id} = start_hooks()
 
     _hooks =
-      ConfigCat.hooks(client: instance_id)
+      [client: instance_id]
+      |> ConfigCat.hooks()
       |> Hooks.add_on_client_ready({TestHooks, :on_client_ready, [test_pid]})
       |> Hooks.add_on_config_changed({TestHooks, :on_config_changed, [test_pid]})
       |> Hooks.add_on_flag_evaluated({TestHooks, :on_flag_evaluated, [test_pid]})
@@ -122,9 +123,7 @@ defmodule ConfigCat.HooksTest do
   end
 
   test "provides details on on_flag_evaluated hook" do
-    MockFetcher
-    |> stub(:fetch, fn _instance_id, _etag -> {:ok, ConfigEntry.new(@config, "NEW-ETAG")} end)
-
+    stub(MockFetcher, :fetch, fn _instance_id, _etag -> {:ok, ConfigEntry.new(@config, "NEW-ETAG")} end)
     test_pid = self()
 
     {:ok, instance_id} =
@@ -159,9 +158,7 @@ defmodule ConfigCat.HooksTest do
   end
 
   test "doesn't fail when callbacks raise errors" do
-    MockFetcher
-    |> stub(:fetch, fn _instance_id, _etag -> {:ok, ConfigEntry.new(@config, "NEW-ETAG")} end)
-
+    stub(MockFetcher, :fetch, fn _instance_id, _etag -> {:ok, ConfigEntry.new(@config, "NEW-ETAG")} end)
     callback0 = fn -> raise "Error raised in callback" end
     callback1 = fn _ignored -> raise "Error raised in callback" end
 
@@ -182,7 +179,7 @@ defmodule ConfigCat.HooksTest do
   end
 
   defp start_hooks(config \\ []) do
-    instance_id = UUID.uuid4() |> String.to_atom()
+    instance_id = String.to_atom(UUID.uuid4())
 
     start_supervised!({Hooks, hooks: config, instance_id: instance_id})
 
diff --git a/test/config_cat_test.exs b/test/config_cat_test.exs
index de0e3957..ea802520 100644
--- a/test/config_cat_test.exs
+++ b/test/config_cat_test.exs
@@ -37,8 +37,8 @@ defmodule ConfigCatTest do
     end
 
     test "get_all_keys/1 returns all known keys", %{client: client} do
-      expected = ~w(testBoolKey testStringKey testIntKey testDoubleKey key1 key2) |> Enum.sort()
-      actual = ConfigCat.get_all_keys(client: client) |> Enum.sort()
+      expected = Enum.sort(~w(testBoolKey testStringKey testIntKey testDoubleKey key1 key2))
+      actual = [client: client] |> ConfigCat.get_all_keys() |> Enum.sort()
       assert actual == expected
     end
 
@@ -74,17 +74,16 @@ defmodule ConfigCatTest do
     @tag capture_log: true
     test "get_all_values/2 returns all key/value pairs", %{client: client} do
       expected =
-        %{
+        Enum.sort(%{
           "testBoolKey" => true,
           "testStringKey" => "testValue",
           "testIntKey" => 1,
           "testDoubleKey" => 1.1,
           "key1" => true,
           "key2" => false
-        }
-        |> Enum.sort()
+        })
 
-      actual = ConfigCat.get_all_values(nil, client: client) |> Enum.sort()
+      actual = nil |> ConfigCat.get_all_values(client: client) |> Enum.sort()
       assert actual == expected
     end
 
diff --git a/test/integration_test.exs b/test/integration_test.exs
index b931da69..09323522 100644
--- a/test/integration_test.exs
+++ b/test/integration_test.exs
@@ -11,12 +11,14 @@ defmodule ConfigCat.IntegrationTest do
   @sdk_key "PKDVCLf-Hq-h-kCzMp-L7Q/PaDVCFk9EpmD6sLpGLltTA"
 
   test "raises error if SDK key is missing" do
-    start_config_cat(nil)
+    nil
+    |> start_config_cat()
     |> assert_sdk_key_required()
   end
 
   test "raises error if SDK key is an empty string" do
-    start_config_cat("")
+    ""
+    |> start_config_cat()
     |> assert_sdk_key_required()
   end
 
@@ -117,7 +119,7 @@ defmodule ConfigCat.IntegrationTest do
     |> Cache.generate_key()
     |> InMemoryCache.clear()
 
-    name = UUID.uuid4() |> String.to_atom()
+    name = String.to_atom(UUID.uuid4())
     default_options = [name: name, sdk_key: sdk_key]
 
     with {:ok, _pid} <-
diff --git a/test/rollout_test.exs b/test/rollout_test.exs
index 97c94d3f..f7621059 100644
--- a/test/rollout_test.exs
+++ b/test/rollout_test.exs
@@ -109,7 +109,8 @@ defmodule ConfigCat.RolloutTest do
       |> String.split(";")
       |> Enum.drop(4)
 
-    Enum.zip(settings_keys, expected_values)
+    settings_keys
+    |> Enum.zip(expected_values)
     |> Enum.map(fn {setting_key, expected} ->
       run_test(setting_key, expected, user, client, type)
     end)
@@ -166,7 +167,7 @@ defmodule ConfigCat.RolloutTest do
   defp normalize(value), do: value
 
   defp start_config_cat(sdk_key) do
-    name = UUID.uuid4() |> String.to_atom()
+    name = String.to_atom(UUID.uuid4())
 
     with {:ok, _pid} <-
            start_supervised(
diff --git a/test/support/cache_policy_case.ex b/test/support/cache_policy_case.ex
index ee0628ac..ffe848e0 100644
--- a/test/support/cache_policy_case.ex
+++ b/test/support/cache_policy_case.ex
@@ -52,7 +52,7 @@ defmodule ConfigCat.CachePolicyCase do
   @spec start_cache_policy(CachePolicy.t(), keyword()) :: {:ok, atom()}
   def start_cache_policy(policy, options \\ []) do
     instance_id =
-      Keyword.get_lazy(options, :instance_id, fn -> UUID.uuid4() |> String.to_atom() end)
+      Keyword.get_lazy(options, :instance_id, fn -> String.to_atom(UUID.uuid4()) end)
 
     if Keyword.get(options, :start_hooks?, true) do
       start_supervised!({Hooks, instance_id: instance_id})
@@ -87,17 +87,14 @@ defmodule ConfigCat.CachePolicyCase do
     cache_key = UUID.uuid4()
 
     {:ok, _pid} =
-      start_supervised(
-        {Cache, cache: InMemoryCache, cache_key: cache_key, instance_id: instance_id}
-      )
+      start_supervised({Cache, cache: InMemoryCache, cache_key: cache_key, instance_id: instance_id})
 
     {:ok, cache_key}
   end
 
   @spec expect_refresh(ConfigEntry.t(), pid() | nil) :: Mox.t()
   def expect_refresh(entry, test_pid \\ nil) do
-    MockFetcher
-    |> expect(:fetch, fn _id, _etag ->
+    expect(MockFetcher, :fetch, fn _id, _etag ->
       if test_pid, do: send(test_pid, :fetch_complete)
       {:ok, entry}
     end)
@@ -105,14 +102,12 @@ defmodule ConfigCat.CachePolicyCase do
 
   @spec expect_unchanged :: Mox.t()
   def expect_unchanged do
-    MockFetcher
-    |> expect(:fetch, fn _id, _etag -> {:ok, :unchanged} end)
+    expect(MockFetcher, :fetch, fn _id, _etag -> {:ok, :unchanged} end)
   end
 
   @spec expect_not_refreshed :: Mox.t()
   def expect_not_refreshed do
-    MockFetcher
-    |> expect(:fetch, 0, fn _id, _etag -> :not_called end)
+    expect(MockFetcher, :fetch, 0, fn _id, _etag -> :not_called end)
   end
 
   @spec assert_returns_error(function()) :: true
@@ -120,9 +115,7 @@ defmodule ConfigCat.CachePolicyCase do
     response = %Response{status_code: 503}
     error = FetchError.exception(reason: response, transient?: true)
 
-    MockFetcher
-    |> stub(:fetch, fn _id, _etag -> {:error, error} end)
-
+    stub(MockFetcher, :fetch, fn _id, _etag -> {:error, error} end)
     assert {:error, _message} = force_refresh_fn.()
   end
 end
diff --git a/test/support/client_case.ex b/test/support/client_case.ex
index 0bcf7e12..b574f022 100644
--- a/test/support/client_case.ex
+++ b/test/support/client_case.ex
@@ -17,17 +17,12 @@ defmodule ConfigCat.ClientCase do
 
   @spec start_client([Client.option()]) :: {:ok, GenServer.server()}
   def start_client(opts \\ []) do
-    instance_id = UUID.uuid4() |> String.to_atom()
+    instance_id = String.to_atom(UUID.uuid4())
 
     start_supervised!({Hooks, instance_id: instance_id})
 
     options =
-      [
-        cache_policy: MockCachePolicy,
-        flag_overrides: NullDataSource.new(),
-        instance_id: instance_id
-      ]
-      |> Keyword.merge(opts)
+      Keyword.merge([cache_policy: MockCachePolicy, flag_overrides: NullDataSource.new(), instance_id: instance_id], opts)
 
     {:ok, pid} = start_supervised({Client, options})
 
@@ -39,9 +34,7 @@ defmodule ConfigCat.ClientCase do
   @spec stub_cached_settings({:ok, Config.settings(), FetchTime.t()} | {:error, :not_found}) ::
           :ok
   def stub_cached_settings(response) do
-    MockCachePolicy
-    |> Mox.stub(:get, fn _id -> response end)
-
+    Mox.stub(MockCachePolicy, :get, fn _id -> response end)
     :ok
   end
 end