test: Start test suite (#16)

This commit is contained in:
Zach Daniel 2020-09-03 04:18:11 -04:00 committed by GitHub
parent f837b06bc6
commit 60c18dd149
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 440 additions and 120 deletions

View file

@ -18,9 +18,19 @@ jobs:
otp: ["23", "22"]
elixir: ["1.10.0"]
ash: ["master", "1.12", "1.13"]
pg_version: ["9.5", "9.6", "11"]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ASH_VERSION: ${{matrix.ash}}
services:
pg:
image: postgres:${{ matrix.pg_version }}
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
ports: ["5432:5432"]
steps:
- run: sudo apt-get install --yes erlang-dev
- uses: actions/checkout@v2
@ -41,6 +51,8 @@ jobs:
key: otp-${{matrix.otp}}-elixir-${{matrix.elixir}}-build-2-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}
restore-keys: otp-${{matrix.otp}}-elixir-${{matrix.elixir}}-build-2
- run: mix deps.get
- run: MIX_ENV=test mix ecto.create
- run: MIX_ENV=test mix ecto.migrate
- run: mix check --except dialyzer
if: startsWith(github.ref, 'refs/tags/v')
- run: mix check
@ -53,8 +65,18 @@ jobs:
matrix:
otp: ["23"]
elixir: ["1.10.0"]
pg_version: ["11"]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
services:
pg:
image: postgres:${{ matrix.pg_version }}
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
ports: ["5432:5432"]
steps:
- run: sudo apt-get install --yes erlang-dev
- uses: actions/checkout@v2
@ -69,6 +91,8 @@ jobs:
key: otp-${{matrix.otp}}-elixir-${{matrix.elixir}}-deps-2-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}
restore-keys: otp-${{matrix.otp}}-elixir-${{matrix.elixir}}-deps-2-
- run: mix deps.get
- run: MIX_ENV=test mix ecto.create
- run: MIX_ENV=test mix ecto.migrate
- run: mix coveralls.github
release:
runs-on: ubuntu-latest

View file

@ -7,249 +7,173 @@ See [Conventional Commits](Https://conventionalcommits.org) for commit guideline
## [v0.19.0](https://github.com/ash-project/ash_postgres/compare/v0.18.0...v0.19.0) (2020-09-02)
### Features:
* support inner joins when possible (#15)
- support inner joins when possible (#15)
### Bug Fixes:
* better support for aggregates/calculations when delegating
- better support for aggregates/calculations when delegating
* don't fail w/ no extensions configured
- don't fail w/ no extensions configured
## [v0.18.0](https://github.com/ash-project/ash_postgres/compare/v0.17.0...v0.18.0) (2020-08-26)
### Features:
* update to ash 1.11 (#13)
- update to ash 1.11 (#13)
* support Ash v1.10 (#12)
- support Ash v1.10 (#12)
* support latest ash
- support latest ash
* update to latest ash
- update to latest ash
## [v0.17.0](https://github.com/ash-project/ash_postgres/compare/v0.16.1...v0.17.0) (2020-08-26)
### Features:
* update to ash 1.11 (#13)
- update to ash 1.11 (#13)
* support Ash v1.10 (#12)
- support Ash v1.10 (#12)
* support latest ash
- support latest ash
* update to latest ash
- update to latest ash
## [v0.16.1](https://github.com/ash-project/ash_postgres/compare/v0.16.0...v0.16.1) (2020-08-19)
### Bug Fixes:
* fix compile/dialyzer issues
- fix compile/dialyzer issues
## [v0.16.0](https://github.com/ash-project/ash_postgres/compare/v0.15.0...v0.16.0) (2020-08-19)
### Features:
* update to latest ash
- update to latest ash
* update to latest version of ash
- update to latest version of ash
## [v0.15.0](https://github.com/ash-project/ash_postgres/compare/v0.14.0...v0.15.0) (2020-08-18)
### Features:
* update to latest version of ash
- update to latest version of ash
## [v0.14.0](https://github.com/ash-project/ash_postgres/compare/v0.13.0...v0.14.0) (2020-08-17)
### Features:
* support ash 1.7
- support ash 1.7
* support named aggregates
- support named aggregates
## [v0.13.0](https://github.com/ash-project/ash_postgres/compare/v0.12.1...v0.13.0) (2020-07-25)
### Features:
* update to latest ash
- update to latest ash
* support latest ash
- support latest ash
## [v0.12.1](https://github.com/ash-project/ash_postgres/compare/v0.12.0...v0.12.1) (2020-07-24)
### Bug Fixes:
* add can? for `:aggregate`
- add can? for `:aggregate`
## [v0.12.0](https://github.com/ash-project/ash_postgres/compare/0.11.2...v0.12.0) (2020-07-24)
### Features:
* update to latest ash
- update to latest ash
## [v0.11.2](https://github.com/ash-project/ash_postgres/compare/0.11.1...v0.11.2) (2020-07-23)
### Bug Fixes:
* typespecs, errant IO.inspect
## [v0.11.1](https://github.com/ash-project/ash_postgres/compare/0.11.0...v0.11.1) (2020-07-23)
### Bug Fixes:
* typespecs, errant IO.inspect
## [v0.11.0](https://github.com/ash-project/ash_postgres/compare/0.10.0...v0.11.0) (2020-07-23)
### Features:
* support ash 13.0 aggregates
- support ash 13.0 aggregates
## [v0.10.0](https://github.com/ash-project/ash_postgres/compare/0.9.0...v0.10.0) (2020-07-15)
### Features:
* update to latest ash
- update to latest ash
## [v0.9.0](https://github.com/ash-project/ash_postgres/compare/0.8.0...v0.9.0) (2020-07-13)
### Features:
* update to latest ash
- update to latest ash
## [v0.8.0](https://github.com/ash-project/ash_postgres/compare/0.7.0...v0.8.0) (2020-07-09)
### Features:
* update to latest ash
- update to latest ash
## [v0.7.0](https://github.com/ash-project/ash_postgres/compare/0.6.0...v0.7.0) (2020-07-09)
### Features:
* update to latest ash
- update to latest ash
* update to latest ash, add docs
- update to latest ash, add docs
* update to ash 0.9.1 for transactions
- update to ash 0.9.1 for transactions
## [v0.6.0](https://github.com/ash-project/ash_postgres/compare/0.5.0...v0.6.0) (2020-06-29)
### Features:
* update to latest ash
- update to latest ash
## [v0.5.0](https://github.com/ash-project/ash_postgres/compare/0.4.0...v0.5.0) (2020-06-29)
### Features:
* upgrade to latest ash
- upgrade to latest ash
## [v0.4.0](https://github.com/ash-project/ash_postgres/compare/0.3.0...v0.4.0) (2020-06-27)
### Features:
* update to latest ash
- update to latest ash
## [v0.3.0](https://github.com/ash-project/ash_postgres/compare/0.2.1...v0.3.0) (2020-06-19)
### Features:
* New filter style (#10)
- New filter style (#10)
## [v0.2.1](https://github.com/ash-project/ash_postgres/compare/0.2.0...v0.2.1) (2020-06-15)
### Bug Fixes:
* update .formatter.exs
- update .formatter.exs
## [v0.2.0](https://github.com/ash-project/ash_postgres/compare/0.1.4...v0.2.0) (2020-06-14)
### Features:
* use the new DSL builder for config (#7)
- use the new DSL builder for config (#7)
## [v0.1.4](https://github.com/ash-project/ash_postgres/compare/0.1.3...v0.1.4) (2020-06-05)
### Bug Fixes:
* update ash version dependency
- update ash version dependency
* account for removal of name
- account for removal of name
## [v0.1.3](https://github.com/ash-project/ash_postgres/compare/0.1.2...v0.1.3) (2020-06-03)

View file

@ -4,3 +4,5 @@
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Coverage Status](https://coveralls.io/repos/github/ash-project/ash_postgres/badge.svg?branch=master)](https://coveralls.io/github/ash-project/ash_postgres?branch=master)
[![Hex version badge](https://img.shields.io/hexpm/v/ash_postgres.svg)](https://hex.pm/packages/ash_postgres)
The documentation for ash_postgres is available on [hexdocs](https://hexdocs.pm/ash_postgres/AshPostgres.html)

View file

@ -13,3 +13,23 @@ if Mix.env() == :dev do
manage_readme_version: "README.md",
version_tag_prefix: "v"
end
if Mix.env() == :test do
# Configure your database
#
config :ash_postgres, AshPostgres.TestRepo,
username: "postgres",
database: "postgres",
hostname: "localhost",
pool: Ecto.Adapters.SQL.Sandbox
# sobelow_skip ["Config.Secrets"]
config :ash_postgres, AshPostgres.TestRepo, password: "postgres"
config :ash_postgres, ecto_repos: [AshPostgres.TestRepo]
config :ash_postgres, AshPostgres.TestRepo, migration_primary_key: [name: :id, type: :binary_id]
config :logger, level: :warn
end

View file

@ -2,7 +2,17 @@ defmodule AshPostgres.DataLayer do
@moduledoc """
A postgres data layer that levereges Ecto's postgres capabilities.
To use this data layer, you need to define an `Ecto.Repo`. Ash adds some
AshPostgres supports all capabilities of an Ash data layer, and it will
most likely stay that way, as postgres is the primary target/most maintained
data layer.
Custom Predicates:
* AshPostgres.Predicates.Trigram
### Usage
To use this data layer, you need to define an `AshPostgres.Repo`. Ash adds some
functionality on top of ecto repos, so you'll want to use `AshPostgres.Repo`
Then, configure your resource like so:
@ -24,7 +34,7 @@ defmodule AshPostgres.DataLayer do
type: {:custom, AshPostgres.DataLayer, :validate_repo, []},
required: true,
doc:
"The repo that will be used to fetch your data. See the `Ecto.Repo` documentation for more"
"The repo that will be used to fetch your data. See the `AshPostgres.Repo` documentation for more"
],
table: [
type: :string,

View file

@ -7,6 +7,18 @@ defmodule AshPostgres.Repo do
You can use `Ecto.Repo`'s `init/2` to configure your repo like normal, but
instead of returning `{:ok, config}`, use `super(config)` to pass the
configuration to the `AshPostgres.Repo` implementation.
Currently the only additional configuration supported is `installed_extensions`,
and the only extension that ash_postgres reacts to is `"pg_trgm"`. If this extension
is installed, then the `AshPostgres.Predicates.Trigram` custom predicate will be
available.
```
def installed_extensions() do
["pg_trgm"]
end
```
"""
@doc "Use this to inform the data layer about what extensions are installed"

View file

@ -17,6 +17,7 @@ defmodule AshPostgres.MixProject do
deps: deps(),
description: @description,
test_coverage: [tool: ExCoveralls],
elixirc_paths: elixirc_paths(Mix.env()),
preferred_cli_env: [
coveralls: :test,
"coveralls.github": :test
@ -32,6 +33,9 @@ defmodule AshPostgres.MixProject do
]
end
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
defp package do
[
name: :ash_postgres,
@ -83,7 +87,7 @@ defmodule AshPostgres.MixProject do
defp aliases do
[
sobelow: "sobelow --skip",
sobelow: "sobelow --skip -i Config.Secrets",
credo: "credo --strict",
"ash.formatter": "ash.formatter --extensions AshPostgres.DataLayer"
]

View file

@ -0,0 +1,11 @@
defmodule AshPostgres.TestRepo.Migrations.AddPosts do
use Ecto.Migration
def change do
create table(:posts) do
add(:title, :string)
add(:score, :integer)
add(:public, :boolean)
end
end
end

View file

@ -0,0 +1,10 @@
defmodule AshPostgres.TestRepo.Migrations.AddComments do
use Ecto.Migration
def change do
create table(:comments) do
add(:title, :string)
add(:post_id, references(:posts))
end
end
end

View file

@ -1,8 +1,3 @@
defmodule AshPostgresTest do
use ExUnit.Case
doctest AshPostgres
test "works" do
assert true
end
end

273
test/filter_test.exs Normal file
View file

@ -0,0 +1,273 @@
defmodule AshPostgres.FilterTest do
use AshPostgres.RepoCase
defmodule Post do
use Ash.Resource,
data_layer: AshPostgres.DataLayer
postgres do
table "posts"
repo AshPostgres.TestRepo
end
actions do
read(:read)
create(:create)
end
attributes do
attribute(:id, :uuid, primary_key?: true, default: &Ecto.UUID.generate/0)
attribute(:title, :string)
attribute(:score, :integer)
attribute(:public, :boolean)
end
relationships do
has_many(:comments, AshPostgres.FilterTest.Comment, destination_field: :post_id)
end
end
defmodule Comment do
use Ash.Resource,
data_layer: AshPostgres.DataLayer
postgres do
table "comments"
repo AshPostgres.TestRepo
end
actions do
read(:read)
create(:create)
end
attributes do
attribute(:id, :uuid, primary_key?: true, default: &Ecto.UUID.generate/0)
attribute(:title, :string)
end
relationships do
belongs_to(:post, Post)
end
end
defmodule Api do
use Ash.Api
resources do
resource(Post)
resource(Comment)
end
end
describe "with no filter applied" do
test "with no data" do
assert [] = Api.read!(Post)
end
test "with data" do
Post
|> Ash.Changeset.new(%{title: "title"})
|> Api.create!()
assert [%Post{title: "title"}] = Api.read!(Post)
end
end
describe "with a simple filter applied" do
test "with no data" do
results =
Post
|> Ash.Query.filter(title: "title")
|> Api.read!()
assert [] = results
end
test "with data that matches" do
Post
|> Ash.Changeset.new(%{title: "title"})
|> Api.create!()
results =
Post
|> Ash.Query.filter(title: "title")
|> Api.read!()
assert [%Post{title: "title"}] = results
end
test "with some data that matches and some data that doesnt" do
Post
|> Ash.Changeset.new(%{title: "title"})
|> Api.create!()
results =
Post
|> Ash.Query.filter(title: "no_title")
|> Api.read!()
assert [] = results
end
test "with related data that doesn't match" do
post =
Post
|> Ash.Changeset.new(%{title: "title"})
|> Api.create!()
Comment
|> Ash.Changeset.new(%{title: "not match"})
|> Ash.Changeset.replace_relationship(:post, post)
|> Api.create!()
results =
Post
|> Ash.Query.filter(comments: [title: "match"])
|> Api.read!()
assert [] = results
end
test "with related data that does match" do
post =
Post
|> Ash.Changeset.new(%{title: "title"})
|> Api.create!()
Comment
|> Ash.Changeset.new(%{title: "match"})
|> Ash.Changeset.replace_relationship(:post, post)
|> Api.create!()
results =
Post
|> Ash.Query.filter(comments: [title: "match"])
|> Api.read!()
assert [%Post{title: "title"}] = results
end
test "with related data that does and doesn't match" do
post =
Post
|> Ash.Changeset.new(%{title: "title"})
|> Api.create!()
Comment
|> Ash.Changeset.new(%{title: "match"})
|> Ash.Changeset.replace_relationship(:post, post)
|> Api.create!()
Comment
|> Ash.Changeset.new(%{title: "not match"})
|> Ash.Changeset.replace_relationship(:post, post)
|> Api.create!()
results =
Post
|> Ash.Query.filter(comments: [title: "match"])
|> Api.read!()
assert [%Post{title: "title"}] = results
end
end
describe "with a boolean filter applied" do
test "with no data" do
results =
Post
|> Ash.Query.filter(or: [[title: "title"], [score: 1]])
|> Api.read!()
assert [] = results
end
test "with data that doesn't match" do
Post
|> Ash.Changeset.new(%{title: "no title", score: 2})
|> Api.create!()
results =
Post
|> Ash.Query.filter(or: [[title: "title"], [score: 1]])
|> Api.read!()
assert [] = results
end
test "with data that matches both conditions" do
Post
|> Ash.Changeset.new(%{title: "title", score: 0})
|> Api.create!()
Post
|> Ash.Changeset.new(%{score: 1, title: "nothing"})
|> Api.create!()
results =
Post
|> Ash.Query.filter(or: [[title: "title"], [score: 1]])
|> Api.read!()
|> Enum.sort_by(& &1.score)
assert [%Post{title: "title", score: 0}, %Post{title: "nothing", score: 1}] = results
end
test "with data that matches one condition and data that matches nothing" do
Post
|> Ash.Changeset.new(%{title: "title", score: 0})
|> Api.create!()
Post
|> Ash.Changeset.new(%{score: 2, title: "nothing"})
|> Api.create!()
results =
Post
|> Ash.Query.filter(or: [[title: "title"], [score: 1]])
|> Api.read!()
|> Enum.sort_by(& &1.score)
assert [%Post{title: "title", score: 0}] = results
end
test "with related data in an or statement that matches, while basic filter doesn't match" do
post =
Post
|> Ash.Changeset.new(%{title: "doesn't match"})
|> Api.create!()
Comment
|> Ash.Changeset.new(%{title: "match"})
|> Ash.Changeset.replace_relationship(:post, post)
|> Api.create!()
results =
Post
|> Ash.Query.filter(or: [[title: "match"], [comments: [title: "match"]]])
|> Api.read!()
assert [%Post{title: "doesn't match"}] = results
end
test "with related data in an or statement that doesn't match, while basic filter does match" do
post =
Post
|> Ash.Changeset.new(%{title: "match"})
|> Api.create!()
Comment
|> Ash.Changeset.new(%{title: "doesn't match"})
|> Ash.Changeset.replace_relationship(:post, post)
|> Api.create!()
results =
Post
|> Ash.Query.filter(or: [[title: "match"], [comments: [title: "match"]]])
|> Api.read!()
assert [%Post{title: "match"}] = results
end
end
end

28
test/support/repo_case.ex Normal file
View file

@ -0,0 +1,28 @@
defmodule AshPostgres.RepoCase do
@moduledoc false
use ExUnit.CaseTemplate
alias Ecto.Adapters.SQL.Sandbox
using do
quote do
alias AshPostgres.TestRepo
import Ecto
import Ecto.Query
import AshPostgres.RepoCase
# and any other stuff
end
end
setup tags do
:ok = Sandbox.checkout(AshPostgres.TestRepo)
unless tags[:async] do
Sandbox.mode(AshPostgres.TestRepo, {:shared, self()})
end
:ok
end
end

View file

@ -0,0 +1,5 @@
defmodule AshPostgres.TestRepo do
@moduledoc false
use AshPostgres.Repo,
otp_app: :ash_postgres
end

View file

@ -1 +1,3 @@
ExUnit.start()
AshPostgres.TestRepo.start_link()