diff --git a/.credo.exs b/.credo.exs index cfc55eb..f078317 100644 --- a/.credo.exs +++ b/.credo.exs @@ -1,3 +1,5 @@ +# This file is synced with beam-community/common-config. Any changes will be overwritten. + # This file contains the configuration for Credo and you are probably reading # this after creating it with `mix credo.gen.config`. # @@ -21,16 +23,7 @@ # You can give explicit globs or simply directories. # In the latter case `**/*.{ex,exs}` will be used. # - included: [ - "lib/", - "src/", - "test/", - "web/", - "apps/*/lib/", - "apps/*/src/", - "apps/*/test/", - "apps/*/web/" - ], + included: ["config/", "lib/", "priv/", "test/"], excluded: [~r"/_build/", ~r"/deps/", ~r"/node_modules/"] }, # @@ -46,7 +39,7 @@ # If you want to enforce a style guide and need a more traditional linting # experience, you can change `strict` to `true` below: # - strict: false, + strict: true, # # To modify the timeout for parsing files, change this value: # @@ -70,10 +63,12 @@ # {Credo.Check.Consistency.ExceptionNames, []}, {Credo.Check.Consistency.LineEndings, []}, + {Credo.Check.Consistency.MultiAliasImportRequireUse, []}, {Credo.Check.Consistency.ParameterPatternMatching, []}, {Credo.Check.Consistency.SpaceAroundOperators, []}, {Credo.Check.Consistency.SpaceInParentheses, []}, {Credo.Check.Consistency.TabsOrSpaces, []}, + {Credo.Check.Consistency.UnusedVariableNames, false}, # ## Design Checks @@ -81,7 +76,8 @@ # 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: 2]}, + {Credo.Check.Design.DuplicatedCode, false}, # 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). @@ -92,39 +88,61 @@ # ## Readability Checks # + {Credo.Check.Readability.AliasAs, false}, {Credo.Check.Readability.AliasOrder, []}, + {Credo.Check.Readability.BlockPipe, []}, {Credo.Check.Readability.FunctionNames, []}, - {Credo.Check.Readability.LargeNumbers, []}, - {Credo.Check.Readability.MaxLineLength, [priority: :low, max_length: 120]}, + {Credo.Check.Readability.ImplTrue, []}, + {Credo.Check.Readability.LargeNumbers, [trailing_digits: 2]}, + {Credo.Check.Readability.MaxLineLength, false}, {Credo.Check.Readability.ModuleAttributeNames, []}, - {Credo.Check.Readability.ModuleDoc, []}, + {Credo.Check.Readability.ModuleDoc, false}, {Credo.Check.Readability.ModuleNames, []}, + {Credo.Check.Readability.MultiAlias, false}, + {Credo.Check.Readability.NestedFunctionCalls, []}, {Credo.Check.Readability.ParenthesesInCondition, []}, {Credo.Check.Readability.ParenthesesOnZeroArityDefs, []}, {Credo.Check.Readability.PredicateFunctionNames, []}, {Credo.Check.Readability.PreferImplicitTry, []}, {Credo.Check.Readability.RedundantBlankLines, []}, {Credo.Check.Readability.Semicolons, []}, + {Credo.Check.Readability.SeparateAliasRequire, []}, + {Credo.Check.Readability.SinglePipe, []}, {Credo.Check.Readability.SpaceAfterCommas, []}, + {Credo.Check.Readability.Specs, false}, + {Credo.Check.Readability.StrictModuleLayout, + [ + order: + ~w(moduledoc behaviour use import require alias module_attribute defstruct callback macrocallback optional_callback)a, + ignore: [:type] + ]}, {Credo.Check.Readability.StringSigils, []}, {Credo.Check.Readability.TrailingBlankLine, []}, {Credo.Check.Readability.TrailingWhiteSpace, []}, {Credo.Check.Readability.UnnecessaryAliasExpansion, []}, {Credo.Check.Readability.VariableNames, []}, + {Credo.Check.Readability.WithCustomTaggedTuple, []}, # ## Refactoring Opportunities # + {Credo.Check.Refactor.ABCSize, false}, + {Credo.Check.Refactor.AppendSingleItem, []}, {Credo.Check.Refactor.CondStatements, []}, {Credo.Check.Refactor.CyclomaticComplexity, []}, + {Credo.Check.Refactor.DoubleBooleanNegation, []}, {Credo.Check.Refactor.FunctionArity, []}, {Credo.Check.Refactor.LongQuoteBlocks, []}, # {Credo.Check.Refactor.MapInto, []}, {Credo.Check.Refactor.MatchInCondition, []}, + {Credo.Check.Refactor.ModuleDependencies, false}, {Credo.Check.Refactor.NegatedConditionsInUnless, []}, {Credo.Check.Refactor.NegatedConditionsWithElse, []}, + {Credo.Check.Refactor.NegatedIsNil, []}, {Credo.Check.Refactor.Nesting, []}, + {Credo.Check.Refactor.PipeChainStart, []}, {Credo.Check.Refactor.UnlessWithElse, []}, + {Credo.Check.Refactor.VariableRebinding, false}, {Credo.Check.Refactor.WithClauses, []}, # @@ -135,11 +153,18 @@ {Credo.Check.Warning.ExpensiveEmptyEnumCheck, []}, {Credo.Check.Warning.IExPry, []}, {Credo.Check.Warning.IoInspect, []}, + {Credo.Check.Warning.LeakyEnvironment, []}, # {Credo.Check.Warning.LazyLogging, []}, - {Credo.Check.Warning.MixEnv, false}, + {Credo.Check.Warning.MapGetUnsafePass, []}, + # disabling this check by default, as if not included, it will be + # run on version 1.7.0 and above + {Credo.Check.Warning.MissedMetadataKeyInLoggerConfig, false}, + {Credo.Check.Warning.MixEnv, []}, {Credo.Check.Warning.OperationOnSameValues, []}, {Credo.Check.Warning.OperationWithConstantResult, []}, {Credo.Check.Warning.RaiseInsideRescue, []}, + {Credo.Check.Warning.UnsafeExec, []}, + {Credo.Check.Warning.UnsafeToAtom, []}, {Credo.Check.Warning.UnusedEnumOperation, []}, {Credo.Check.Warning.UnusedFileOperation, []}, {Credo.Check.Warning.UnusedKeywordOperation, []}, @@ -147,41 +172,7 @@ {Credo.Check.Warning.UnusedPathOperation, []}, {Credo.Check.Warning.UnusedRegexOperation, []}, {Credo.Check.Warning.UnusedStringOperation, []}, - {Credo.Check.Warning.UnusedTupleOperation, []}, - {Credo.Check.Warning.UnsafeExec, []}, - - # - # Checks scheduled for next check update (opt-in for now, just replace `false` with `[]`) - - # - # Controversial and experimental checks (opt-in, just replace `false` with `[]`) - # - {Credo.Check.Consistency.MultiAliasImportRequireUse, false}, - {Credo.Check.Consistency.UnusedVariableNames, false}, - {Credo.Check.Design.DuplicatedCode, false}, - {Credo.Check.Readability.AliasAs, false}, - {Credo.Check.Readability.BlockPipe, false}, - {Credo.Check.Readability.ImplTrue, false}, - {Credo.Check.Readability.MultiAlias, false}, - {Credo.Check.Readability.SeparateAliasRequire, false}, - {Credo.Check.Readability.SinglePipe, false}, - {Credo.Check.Readability.Specs, false}, - {Credo.Check.Readability.StrictModuleLayout, false}, - {Credo.Check.Readability.WithCustomTaggedTuple, false}, - {Credo.Check.Refactor.ABCSize, false}, - {Credo.Check.Refactor.AppendSingleItem, false}, - {Credo.Check.Refactor.DoubleBooleanNegation, false}, - {Credo.Check.Refactor.ModuleDependencies, false}, - {Credo.Check.Refactor.NegatedIsNil, false}, - {Credo.Check.Refactor.PipeChainStart, false}, - {Credo.Check.Refactor.VariableRebinding, false}, - {Credo.Check.Warning.LeakyEnvironment, false}, - {Credo.Check.Warning.MapGetUnsafePass, false}, - {Credo.Check.Warning.UnsafeToAtom, false} - - # - # Custom checks can be created using `mix credo.gen.check`. - # + {Credo.Check.Warning.UnusedTupleOperation, []} ] } ] diff --git a/.formatter.exs b/.formatter.exs index eb0477f..e287cec 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,4 +1,8 @@ +# This file is synced with beam-community/common-config. Any changes will be overwritten. + [ - inputs: ["*.{ex,exs}", "{lib,test}/**/*.{ex,exs}", "example/{lib,test}/**/*.{ex,exs}"], - line_length: 120 + import_deps: [], + inputs: ["*.{heex,ex,exs}", "{config,lib,priv,test}/**/*.{heex,ex,exs}"], + line_length: 120, + plugins: [] ] diff --git a/.github/release-please-config.json b/.github/release-please-config.json new file mode 100644 index 0000000..cd8b23a --- /dev/null +++ b/.github/release-please-config.json @@ -0,0 +1,39 @@ +{ + "$comment": "This file is synced with beam-community/common-config. Any changes will be overwritten.", + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", + "changelog-sections": [ + { + "type": "feat", + "section": "Features", + "hidden": false + }, + { + "type": "fix", + "section": "Bug Fixes", + "hidden": false + }, + { + "type": "chore", + "section": "Miscellaneous", + "hidden": false + } + ], + "draft": false, + "draft-pull-request": false, + "packages": { + ".": { + "extra-files": [ + "README.md" + ], + "release-type": "elixir" + } + }, + "plugins": [ + { + "type": "sentence-case" + } + ], + "prerelease": false, + "pull-request-header": "An automated release has been created for you.", + "separate-pull-requests": true +} diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..f3f57ac --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,121 @@ +# This file is synced with beam-community/common-config. Any changes will be overwritten. + +name: CI + +on: + merge_group: + pull_request: + types: + - opened + - reopened + - synchronize + push: + branches: + - main + workflow_call: + secrets: + GH_PERSONAL_ACCESS_TOKEN: + required: true + workflow_dispatch: + +concurrency: + group: CI ${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + Credo: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Elixir + uses: stordco/actions-elixir/setup@v1 + with: + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + + - name: Credo + run: mix credo --strict + + Dependencies: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Elixir + uses: stordco/actions-elixir/setup@v1 + with: + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + + - name: Unused + run: mix deps.unlock --check-unused + + Dialyzer: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Elixir + uses: stordco/actions-elixir/setup@v1 + with: + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + + - name: Dialyzer + run: mix dialyzer --format github + + Format: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Elixir + uses: stordco/actions-elixir/setup@v1 + with: + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + + - name: Format + run: mix format --check-formatted + + Test: + name: Test (Elixir ${{ matrix.versions.elixir }} OTP ${{ matrix.versions.otp }}) + + runs-on: ubuntu-latest + + env: + MIX_ENV: test + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Elixir + uses: stordco/actions-elixir/setup@v1 + with: + elixir-version: ${{ matrix.versions.elixir }} + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + otp-version: ${{ matrix.versions.otp }} + + - name: Compile + run: mix compile --warnings-as-errors + + - name: Test + run: mix test + + strategy: + fail-fast: false + matrix: + versions: + - elixir: 1.13 + otp: 25 + - elixir: 1.14 + otp: 25 + - elixir: 1.15 + otp: 26 + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 957284b..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,49 +0,0 @@ ---- - -name: Continuous Integration - -on: - pull_request: - types: - - opened - - reopened - - synchronize - push: - branches: - - master - -jobs: - Test: - env: - MIX_ENV: test - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: erlef/setup-beam@v1 - with: - otp-version: 24 - elixir-version: 1.12 - - run: mix deps.get - - run: mix test - - Format: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: erlef/setup-beam@v1 - with: - otp-version: 24 - elixir-version: 1.12 - - run: mix deps.get - - run: mix format --check-formatted - - Credo: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: erlef/setup-beam@v1 - with: - otp-version: 24 - elixir-version: 1.12 - - run: mix deps.get - - run: mix credo diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index 2a4500a..0000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,27 +0,0 @@ ---- - -name: Publish to Hex.pm - -on: - push: - paths: - - 'VERSION' - branches: - - master - workflow_dispatch: {} - -jobs: - Publish: - runs-on: ubuntu-latest - env: - HEX_API_KEY: ${{ secrets.HEXPM_SECRET }} - steps: - - uses: actions/checkout@v2 - - uses: erlef/setup-beam@v1 - with: - otp-version: 24 - elixir-version: 1.12 - - run: mix deps.get - - run: mix compile --docs - - run: mix hex.publish --yes - diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml new file mode 100644 index 0000000..5e2628a --- /dev/null +++ b/.github/workflows/pr.yaml @@ -0,0 +1,35 @@ +# This file is synced with beam-community/common-config. Any changes will be overwritten. + +name: PR + +on: + merge_group: + pull_request: + types: + - edited + - opened + - reopened + - synchronize + +jobs: + Title: + if: ${{ github.event_name == 'pull_request' }} + name: Check Title + runs-on: ubuntu-latest + + steps: + - name: Check + uses: stordco/actions-pr-title@v1.0.0 + with: + regex: '^(feat!|fix!|fix|feat|chore)(\(\w+\))?:\s(\[#\d{1,5}\])?.*$' + hint: | + Your PR title does not match the Conventional Commits convention. Please rename your PR to match one of the following formats: + + fix: [#123] some title of the PR + fix(scope): [#123] some title of the PR + feat: [#1234] some title of the PR + chore: update some action + + Note: Adding ! (i.e. `feat!:`) represents a breaking change and will result in a SemVer major release. + + See https://www.conventionalcommits.org/en/v1.0.0/ for more information. diff --git a/.github/workflows/production.yaml b/.github/workflows/production.yaml new file mode 100644 index 0000000..6304a1e --- /dev/null +++ b/.github/workflows/production.yaml @@ -0,0 +1,35 @@ +# This file is synced with beam-community/common-config. Any changes will be overwritten. + +name: Production + +on: + release: + types: + - released + - prereleased + workflow_dispatch: + +concurrency: + group: Production + +jobs: + Hex: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Elixir + uses: stordco/actions-elixir/setup@v1 + with: + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + + - name: Compile + run: mix compile --docs + + - name: Publish + run: mix hex.publish --yes + env: + HEX_API_KEY: ${{ secrets.HEX_API_KEY }} + diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..40ef723 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,23 @@ +# This file is synced with beam-community/common-config. Any changes will be overwritten. + +name: Release + +on: + push: + branches: + - main + +jobs: + Please: + runs-on: ubuntu-latest + + steps: + - id: release + name: Release + uses: google-github-actions/release-please-action@v3 + with: + command: manifest + config-file: .github/release-please-config.json + manifest-file: .github/release-please-manifest.json + release-type: elixir + token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} diff --git a/VERSION b/VERSION deleted file mode 100644 index 9ab8337..0000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.9.1 diff --git a/lib/ua_parser/parsers/base.ex b/lib/ua_parser/parsers/base.ex index 434cc0e..b2e0074 100644 --- a/lib/ua_parser/parsers/base.ex +++ b/lib/ua_parser/parsers/base.ex @@ -1,10 +1,18 @@ defmodule UAParser.Parsers.Base do @moduledoc """ - A module repsenting the base and behaviour for all of our parsers. + A module representing the base and behaviour for all of our parsers. """ @callback parse(args :: term) :: result :: term | nil + defmacro __using__(_opts) do + quote do + @behaviour UAParser.Parsers.Base + + import UAParser.Parsers.Base + end + end + defmacro replacement_parser(opts) do [family_key | replacements] = Keyword.fetch!(opts, :keys) mod = opts[:struct] diff --git a/lib/ua_parser/parsers/device.ex b/lib/ua_parser/parsers/device.ex index 885c801..6e89e2a 100644 --- a/lib/ua_parser/parsers/device.ex +++ b/lib/ua_parser/parsers/device.ex @@ -3,10 +3,7 @@ defmodule UAParser.Parsers.Device do A parser module representing the device & its relevent information of a user agent. """ - - @behaviour UAParser.Parsers.Base - - import UAParser.Parsers.Base + use UAParser.Parsers.Base alias UAParser.Device diff --git a/lib/ua_parser/parsers/operating_system.ex b/lib/ua_parser/parsers/operating_system.ex index cc5b45d..2e76ff2 100644 --- a/lib/ua_parser/parsers/operating_system.ex +++ b/lib/ua_parser/parsers/operating_system.ex @@ -3,7 +3,7 @@ defmodule UAParser.Parsers.OperatingSystem do A parser module representing the operating system derived from a user agent. """ - import UAParser.Parsers.Base + use UAParser.Parsers.Base alias UAParser.OperatingSystem diff --git a/lib/ua_parser/parsers/user_agent.ex b/lib/ua_parser/parsers/user_agent.ex index 8fbff3a..dba9685 100644 --- a/lib/ua_parser/parsers/user_agent.ex +++ b/lib/ua_parser/parsers/user_agent.ex @@ -2,10 +2,9 @@ defmodule UAParser.Parsers.UA do @moduledoc """ A parser module representing the user agent from a request. """ + use UAParser.Parsers.Base - alias UAParser.{Parsers.Base, UA} - - import Base + alias UAParser.UA replacement_parser( struct: UA, diff --git a/lib/ua_parser/parsers/version.ex b/lib/ua_parser/parsers/version.ex index a458f7f..ba5b165 100644 --- a/lib/ua_parser/parsers/version.ex +++ b/lib/ua_parser/parsers/version.ex @@ -4,9 +4,7 @@ defmodule UAParser.Parsers.Version do browser derived from the user agent. """ - @behaviour UAParser.Parsers.Base - - import UAParser.Parsers.Base + use UAParser.Parsers.Base alias UAParser.Version diff --git a/lib/ua_parser/processor.ex b/lib/ua_parser/processor.ex index ab01f8c..492fe54 100644 --- a/lib/ua_parser/processor.ex +++ b/lib/ua_parser/processor.ex @@ -17,6 +17,7 @@ defmodule UAParser.Processor do defp atom_key(key) do key |> String.Chars.to_string() + # credo:disable-for-next-line Credo.Check.Warning.UnsafeToAtom |> String.to_atom() end diff --git a/lib/ua_parser/user_agent.ex b/lib/ua_parser/user_agent.ex index 148c4da..3d2abbb 100644 --- a/lib/ua_parser/user_agent.ex +++ b/lib/ua_parser/user_agent.ex @@ -35,7 +35,11 @@ end defimpl String.Chars, for: UAParser.UA do def to_string(%{family: family, version: nil}), do: family_name(family) - def to_string(%{family: family, version: version}), do: "#{family_name(family)} #{version}" + + def to_string(%{family: family, version: version}) do + family_name = family_name(family) + "#{family_name} #{version}" + end defp family_name(nil), do: "Other" defp family_name(name), do: name diff --git a/mix.exs b/mix.exs index e730e03..e686bb1 100644 --- a/mix.exs +++ b/mix.exs @@ -6,8 +6,8 @@ defmodule UAParser.Mixfile do def project do [ app: :ua_parser, - version: version(), - elixir: "~> 1.4", + version: "1.9.1", + elixir: "~> 1.13", build_embedded: Mix.env() == :prod, start_permanent: Mix.env() == :prod, package: package(), @@ -22,9 +22,11 @@ defmodule UAParser.Mixfile do defp deps do [ - {:yamerl, "~> 0.8"}, - {:credo, "~> 1.5", only: [:dev, :test]}, - {:ex_doc, "~> 0.24", only: :dev, runtime: false} + {:yamerl, "~> 0.10"}, + # Dev & Test dependencies + {:dialyxir, "~> 1.1", only: [:dev, :test], runtime: false}, + {:credo, "~> 1.7", only: [:dev, :test], runtime: false}, + {:ex_doc, "~> 0.31", only: :dev, runtime: false} ] end @@ -32,7 +34,7 @@ defmodule UAParser.Mixfile do [ description: "Parse user-agent strings with BrowserScope patterns", maintainers: ["Sean Callan", "Nathan Youngman"], - files: ["lib", "mix.exs", "README*", "LICENSE*", "priv", "VERSION"], + files: ["lib", "mix.exs", "README*", "LICENSE*", "priv"], licenses: ["Apache-2.0"], links: %{GitHub: @source_url} ] @@ -46,14 +48,7 @@ defmodule UAParser.Mixfile do ], main: "readme", source_url: @source_url, - source_ref: "v#{version()}", formatters: ["html"] ] end - - defp version do - "VERSION" - |> File.read!() - |> String.trim() - end end diff --git a/mix.lock b/mix.lock index 1e729de..968445d 100644 --- a/mix.lock +++ b/mix.lock @@ -1,15 +1,15 @@ %{ - "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"}, - "credo": {:hex, :credo, "1.5.6", "e04cc0fdc236fefbb578e0c04bd01a471081616e741d386909e527ac146016c6", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "4b52a3e558bd64e30de62a648518a5ea2b6e3e5d2b164ef5296244753fc7eb17"}, - "earmark": {:hex, :earmark, "1.3.2", "b840562ea3d67795ffbb5bd88940b1bed0ed9fa32834915125ea7d02e35888a5", [:mix], [], "hexpm", "e3be2bc3ae67781db529b80aa7e7c49904a988596e2dbff897425b48b3581161"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.13", "0c98163e7d04a15feb62000e1a891489feb29f3d10cb57d4f845c405852bbef8", [:mix], [], "hexpm", "d602c26af3a0af43d2f2645613f65841657ad6efc9f0e361c3b6c06b578214ba"}, - "ex_doc": {:hex, :ex_doc, "0.24.2", "e4c26603830c1a2286dae45f4412a4d1980e1e89dc779fcd0181ed1d5a05c8d9", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "e134e1d9e821b8d9e4244687fb2ace58d479b67b282de5158333b0d57c6fb7da"}, + "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, + "credo": {:hex, :credo, "1.7.1", "6e26bbcc9e22eefbff7e43188e69924e78818e2fe6282487d0703652bc20fd62", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "e9871c6095a4c0381c89b6aa98bc6260a8ba6addccf7f6a53da8849c748a58a2"}, + "dialyxir": {:hex, :dialyxir, "1.4.2", "764a6e8e7a354f0ba95d58418178d486065ead1f69ad89782817c296d0d746a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "516603d8067b2fd585319e4b13d3674ad4f314a5902ba8130cd97dc902ce6bbd"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"}, + "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, + "ex_doc": {:hex, :ex_doc, "0.31.0", "06eb1dfd787445d9cab9a45088405593dd3bb7fe99e097eaa71f37ba80c7a676", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.1", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "5350cafa6b7f77bdd107aa2199fe277acf29d739aba5aee7e865fc680c62a110"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, - "jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"}, - "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"}, - "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, - "nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"}, - "yamerl": {:hex, :yamerl, "0.8.1", "07da13ffa1d8e13948943789665c62ccd679dfa7b324a4a2ed3149df17f453a4", [:rebar3], [], "hexpm", "96cb30f9d64344fed0ef8a92e9f16f207de6c04dfff4f366752ca79f5bceb23f"}, - "yomel": {:hex, :yomel, "0.5.0", "c5a42d1818deda3f85ae14b1f01f6ece22b9ed8e8087012359fc04b59d85f621", [:make, :mix], []}, + "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, + "makeup": {:hex, :makeup, "1.1.1", "fa0bc768698053b2b3869fa8a62616501ff9d11a562f3ce39580d60860c3a55e", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5dc62fbdd0de44de194898b6710692490be74baa02d9d108bc29f007783b0b48"}, + "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"}, + "makeup_erlang": {:hex, :makeup_erlang, "0.1.3", "d684f4bac8690e70b06eb52dad65d26de2eefa44cd19d64a8095e1417df7c8fd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "b78dc853d2e670ff6390b605d807263bf606da3c82be37f9d7f68635bd886fc9"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, + "yamerl": {:hex, :yamerl, "0.10.0", "4ff81fee2f1f6a46f1700c0d880b24d193ddb74bd14ef42cb0bcf46e81ef2f8e", [:rebar3], [], "hexpm", "346adb2963f1051dc837a2364e4acf6eb7d80097c0f53cbdc3046ec8ec4b4e6e"}, } diff --git a/test/ua_parser/processor_test.exs b/test/ua_parser/processor_test.exs index 88dd951..9eb7793 100644 --- a/test/ua_parser/processor_test.exs +++ b/test/ua_parser/processor_test.exs @@ -4,17 +4,29 @@ defmodule UAParser.ProcessorTest do alias UAParser.Processor test "converts yaml document into data structure" do - result = Processor.process(test_data()) + test_data = + File.cwd!() + |> Path.join("test/fixtures/patterns.yml") + |> :yamerl_constr.file() - assert is_tuple(result) - assert tuple_size(result) == 3 - assert [[{:regex, pattern}]] = elem(result, 0) - assert Regex.regex?(pattern) - end - - def test_data do - File.cwd!() - |> Path.join("test/fixtures/patterns.yml") - |> :yamerl_constr.file() + assert {[ + [ + regex: %Regex{} + ] + ], + [ + [ + regex: %Regex{}, + os_replacement: "Mac OS X" + ] + ], + [ + [ + regex: %Regex{}, + device_replacement: "$1", + brand_replacement: "Apple", + model_replacement: "$1" + ] + ]} = Processor.process(test_data) end end