From 25e28159fda633a43b50893aeddfbf4da996973c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20M=C3=A4nnchen?= Date: Thu, 13 Apr 2023 11:41:04 +0200 Subject: [PATCH] Add Basic Tests (#6) (#12) --- .gitignore | 5 ++ coveralls.json | 3 + lib/mix_dependency_submission/dependency.ex | 19 ++-- priv/test/fixtures/app/mix.exs | 14 +++ priv/test/fixtures/app/mix.lock | 7 ++ test/mix_dependency_submission_test.exs | 98 ++++++++++++++++++++- test/test_helper.exs | 2 +- 7 files changed, 137 insertions(+), 11 deletions(-) create mode 100644 coveralls.json create mode 100644 priv/test/fixtures/app/mix.exs create mode 100644 priv/test/fixtures/app/mix.lock diff --git a/.gitignore b/.gitignore index a228170..6278abc 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,8 @@ mix_dependency_submission-*.tar # Escript /mix_dependency_submission + +# Fixture Applications +priv/test/fixtures/*/* +!priv/test/fixtures/*/mix.exs +!priv/test/fixtures/*/mix.lock \ No newline at end of file diff --git a/coveralls.json b/coveralls.json new file mode 100644 index 0000000..f0c204e --- /dev/null +++ b/coveralls.json @@ -0,0 +1,3 @@ +{ + "skip_files": ["lib/mix_dependency_submission/cli.ex"] +} diff --git a/lib/mix_dependency_submission/dependency.ex b/lib/mix_dependency_submission/dependency.ex index 09a79f8..6874098 100644 --- a/lib/mix_dependency_submission/dependency.ex +++ b/lib/mix_dependency_submission/dependency.ex @@ -83,7 +83,7 @@ defmodule MixDependencySubmission.Dependency do %Dependency{ package_url: purl, metadata: %{name: dep}, - relationship: if(dep in child_apps(dep), do: :direct, else: :indirect), + relationship: if(dep in child_apps(), do: :direct, else: :indirect), scope: mix_dependency_scope(dep), dependencies: get_resolved_child_dependencies(dep, lock) }} @@ -103,8 +103,8 @@ defmodule MixDependencySubmission.Dependency do |> deps_scms() |> Map.delete(dep) |> Enum.map(&mix_dependency_to_manifest(&1, lock)) - |> Enum.filter(&match?({:ok, _package_url}, &1)) - |> Enum.map(fn {:ok, package_url} -> package_url end) + |> Enum.filter(&match?({:ok, _dep}, &1)) + |> Enum.map(fn {:ok, %Dependency{package_url: package_url}} -> package_url end) end @spec mix_dependency_scope(dep :: atom()) :: :runtime | :development @@ -183,16 +183,17 @@ defmodule MixDependencySubmission.Dependency do scm.accepts_options(dep, opts) end - @spec child_apps(dep :: atom()) :: [atom()] + @spec child_apps :: [atom()] if function_exported?(Mix.Project, :deps_tree, 1) do - defp child_apps(dep) do - %{^dep => child_apps} = Mix.Project.deps_tree(parents: [dep], depth: 1) + defp child_apps do + %{^dep => child_apps} = Mix.Project.deps_tree(depth: 1) end else # TODO: Remove when only supporting Elixir >= 1.15 - defp child_apps(dep) do - %Mix.Dep{deps: deps} = Enum.find(Mix.Dep.cached(), &match?(%Mix.Dep{app: ^dep}, &1)) - Enum.map(deps, & &1.app) + defp child_apps do + Mix.Dep.cached() + |> Enum.filter(&match?(%Mix.Dep{top_level: true}, &1)) + |> Enum.map(& &1.app) end end diff --git a/priv/test/fixtures/app/mix.exs b/priv/test/fixtures/app/mix.exs new file mode 100644 index 0000000..87a491c --- /dev/null +++ b/priv/test/fixtures/app/mix.exs @@ -0,0 +1,14 @@ +defmodule App.MixProject do + use Mix.Project + + def project do + [ + app: :app, + deps: [ + {:credo, "~> 1.7"}, + {:mime, "~> 2.0"}, + {:expo, github: "elixir-gettext/expo"} + ] + ] + end +end diff --git a/priv/test/fixtures/app/mix.lock b/priv/test/fixtures/app/mix.lock new file mode 100644 index 0000000..41d5a24 --- /dev/null +++ b/priv/test/fixtures/app/mix.lock @@ -0,0 +1,7 @@ +%{ + "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, + "credo": {:hex, :credo, "1.7.0", "6119bee47272e85995598ee04f2ebbed3e947678dee048d10b5feca139435f75", [: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", "6839fcf63d1f0d1c0f450abc8564a57c43d644077ab96f2934563e68b8a769d7"}, + "expo": {:git, "https://github.com/elixir-gettext/expo.git", "2ae85019d62288001bdc4a949d65bf650beee315", []}, + "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, + "jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"}, +} diff --git a/test/mix_dependency_submission_test.exs b/test/mix_dependency_submission_test.exs index 3bfbb19..294585b 100644 --- a/test/mix_dependency_submission_test.exs +++ b/test/mix_dependency_submission_test.exs @@ -1,6 +1,102 @@ defmodule MixDependencySubmissionTest do use ExUnit.Case, async: false + + alias MixDependencySubmission.Submission + doctest MixDependencySubmission - # TODO + describe inspect(&MixDependencySubmission.submission/1) do + test "generates valid submission for 'app' fixture" do + run_in_fixture(:app, fn -> + current_version = + :mix_dependency_submission + |> Application.spec(:vsn) + |> List.to_string() + |> Version.parse!() + + assert %Submission{ + version: 0, + job: %Submission.Job{ + id: "github_job_id", + correlator: "github_workflowgithub_job_id", + html_url: nil + }, + sha: "sha", + ref: "ref", + detector: %Submission.Detector{ + name: "mix_dependency_submission", + version: ^current_version, + url: %URI{ + scheme: "https", + userinfo: nil, + host: "github.com", + port: 443, + path: "/jshmrtn/mix-dependency-submission", + query: nil, + fragment: nil + } + }, + scanned: %DateTime{}, + metadata: %{}, + manifests: %{ + "mix.exs" => %Submission.Manifest{ + name: "mix.exs", + file: %Submission.Manifest.File{ + source_location: "mix.exs" + }, + metadata: %{}, + resolved: %{ + # TODO: Add tests for child dependencies + credo: %Submission.Manifest.Dependency{ + package_url: %Purl{type: "hex", name: "credo", version: "1.7.0"}, + metadata: %{name: :credo}, + relationship: :direct, + scope: :runtime + }, + expo: %Submission.Manifest.Dependency{ + package_url: %Purl{ + type: "github", + name: "expo", + namespace: ["elixir-gettext"], + version: "2ae85019d62288001bdc4a949d65bf650beee315" + }, + metadata: %{name: :expo}, + relationship: :direct, + scope: :runtime + }, + mime: %Submission.Manifest.Dependency{ + # Version is empty because dependency is not locked + package_url: %Purl{type: "hex", name: "mime", version: nil}, + metadata: %{name: :mime}, + relationship: :direct, + scope: :runtime + } + } + } + } + } = + MixDependencySubmission.submission(%{ + github_job_id: "github_job_id", + github_workflow: "github_workflow", + sha: "sha", + ref: "ref", + file_path: "mix.exs" + }) + end) + end + end + + @spec run_in_fixture(fixture_app :: atom(), callback :: (() -> result)) :: result + when result: term() + defp run_in_fixture(fixture_app, callback) do + Mix.ProjectStack.on_clean_slate(fn -> + Mix.Project.in_project( + :app, + Application.app_dir(:mix_dependency_submission, "priv/test/fixtures/#{fixture_app}"), + fn _module -> + callback.() + end + ) + end) + end end diff --git a/test/test_helper.exs b/test/test_helper.exs index 869559e..6a0af57 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -1 +1 @@ -ExUnit.start() +ExUnit.start(capture_log: true)