From 569ca53e683f03ea00b271dee48fc6f96c218c1b Mon Sep 17 00:00:00 2001 From: Pavel Tatarsky Date: Fri, 6 Jan 2017 14:56:19 +0300 Subject: [PATCH] * Fix issue #4 * Get test coverage over 80% --- lib/cassandra_ecto/adapter/cql.ex | 3 +-- mix.exs | 2 +- spec/cassandra_ecto/adapter/cql_spec.ex | 20 ++++++++++---------- spec/cassandra_ecto/adapter_spec.exs | 6 ++++++ spec/cassandra_ecto/log_spec.exs | 19 +++++++++++++++++++ spec/cassandra_ecto/migration/cql_spec.ex | 4 ++-- 6 files changed, 39 insertions(+), 15 deletions(-) create mode 100644 spec/cassandra_ecto/log_spec.exs diff --git a/lib/cassandra_ecto/adapter/cql.ex b/lib/cassandra_ecto/adapter/cql.ex index c68fc2a..0e59351 100644 --- a/lib/cassandra_ecto/adapter/cql.ex +++ b/lib/cassandra_ecto/adapter/cql.ex @@ -169,8 +169,7 @@ defmodule Cassandra.Ecto.Adapter.CQL do defp boolean(_name, [], _query), do: [] defp boolean(name, [%{expr: expr} | query_exprs], query) do - name <> " " <> - Enum.reduce(query_exprs, paren_expr(expr, query), fn + name <> " " <> Enum.reduce(query_exprs, expr(expr, query), fn %BooleanExpr{expr: expr, op: op}, {op, acc} -> {op, acc <> operator_to_boolean(op) <> paren_expr(expr, query)} %BooleanExpr{expr: expr, op: op}, {_, acc} -> diff --git a/mix.exs b/mix.exs index b806db9..c888a17 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule CassandraEcto.Mixfile do use Mix.Project - @version "0.4.0" + @version "0.4.1" def project do [app: :cassandra_ecto, diff --git a/spec/cassandra_ecto/adapter/cql_spec.ex b/spec/cassandra_ecto/adapter/cql_spec.ex index 6d796f1..80ed2d1 100644 --- a/spec/cassandra_ecto/adapter/cql_spec.ex +++ b/spec/cassandra_ecto/adapter/cql_spec.ex @@ -63,22 +63,22 @@ defmodule CassandraEctoAdapterCQLSpec do it "generates cql with binary clauses" do query = (from p in "posts", where: p.id >= 1 and p.title == "abra") |> normalize expect(to_cql(:all, query)) - |> to(eq "SELECT * FROM \"posts\" WHERE ((\"id\" >= 1) AND (\"title\" = 'abra'))") + |> to(eq "SELECT * FROM \"posts\" WHERE (\"id\" >= 1) AND (\"title\" = 'abra')") end it "generates cql with in clauses" do query = (from p in "posts", where: p.id in [1, 2]) |> normalize expect(to_cql(:all, query)) - |> to(eq "SELECT * FROM \"posts\" WHERE (\"id\" IN (1, 2))") + |> to(eq "SELECT * FROM \"posts\" WHERE \"id\" IN (1, 2)") end it "alters :in to :contains in array field search" do query = (from p in "posts", where: "abra" in p.tags) |> normalize expect(to_cql(:all, query)) - |> to(eq "SELECT * FROM \"posts\" WHERE (\"tags\" CONTAINS 'abra')") + |> to(eq "SELECT * FROM \"posts\" WHERE \"tags\" CONTAINS 'abra'") end it "supports fragments" do query = (from p in "posts", where: p.id > fragment("token(?)", 1)) |> normalize expect(to_cql(:all, query)) - |> to(eq "SELECT * FROM \"posts\" WHERE (\"id\" > token(1))") + |> to(eq "SELECT * FROM \"posts\" WHERE \"id\" > token(1)") end end context "with :offset" do @@ -121,7 +121,7 @@ defmodule CassandraEctoAdapterCQLSpec do it "generates cql" do query = (from p in "posts", where: p.id == 1) |> normalize expect(to_cql(:all, query, allow_filtering: true)) - |> to(eq "SELECT * FROM \"posts\" WHERE (\"id\" = 1) ALLOW FILTERING") + |> to(eq "SELECT * FROM \"posts\" WHERE \"id\" = 1 ALLOW FILTERING") end end context "with :per_partition_limit" do @@ -220,14 +220,14 @@ defmodule CassandraEctoAdapterCQLSpec do it "generates cql" do query = (from p in "posts", where: p.id == 1, update: [inc: [visits: 5]]) |> normalize(:update_all) expect(to_cql(:update_all, query)) - |> to(eq "UPDATE \"posts\" SET \"visits\" = \"visits\" + 5 WHERE (\"id\" = 1)") + |> to(eq "UPDATE \"posts\" SET \"visits\" = \"visits\" + 5 WHERE \"id\" = 1") end end context "with :set" do it "generates cql" do query = (from p in "posts", where: p.id == 1, update: [set: [title: "a", text: "b"]]) |> normalize(:update_all) expect(to_cql(:update_all, query)) - |> to(eq "UPDATE \"posts\" SET \"title\" = 'a', \"text\" = 'b' WHERE (\"id\" = 1)") + |> to(eq "UPDATE \"posts\" SET \"title\" = 'a', \"text\" = 'b' WHERE \"id\" = 1") end end # context "with :push" do @@ -235,14 +235,14 @@ defmodule CassandraEctoAdapterCQLSpec do # id = Ecto.UUID.bingenerate() # query = (from p in Post, where: p.id == ^id, update: [push: [tags: "a"]]) |> normalize(:update_all) # expect(to_cql(:update_all, query)) - # |> to(eq "UPDATE \"posts\" SET \"tags\" + {'a'} WHERE (\"id\" = ?)") + # |> to(eq "UPDATE \"posts\" SET \"tags\" + {'a'} WHERE \"id\" = ?") # end # end context "with if: :exists" do it "generates cql" do query = (from p in "posts", where: p.id == 1, update: [set: [title: "a", text: "b"]]) |> normalize(:update_all) expect(to_cql(:update_all, query, if: :exists)) - |> to(eq "UPDATE \"posts\" SET \"title\" = 'a', \"text\" = 'b' WHERE (\"id\" = 1) IF EXISTS") + |> to(eq "UPDATE \"posts\" SET \"title\" = 'a', \"text\" = 'b' WHERE \"id\" = 1 IF EXISTS") end end end @@ -250,7 +250,7 @@ defmodule CassandraEctoAdapterCQLSpec do it "generates cql" do query = (from p in "posts", where: p.id == 1) |> normalize(:delete_all) expect(to_cql(:delete_all, query)) - |> to(eq "DELETE FROM \"posts\" WHERE (\"id\" = 1)") + |> to(eq "DELETE FROM \"posts\" WHERE \"id\" = 1") end end end diff --git a/spec/cassandra_ecto/adapter_spec.exs b/spec/cassandra_ecto/adapter_spec.exs index 1f6d149..b36a928 100644 --- a/spec/cassandra_ecto/adapter_spec.exs +++ b/spec/cassandra_ecto/adapter_spec.exs @@ -57,6 +57,12 @@ defmodule CassandraEctoAdapterSpec do expect(TestRepo.all((from p in Post, where: "abra" in p.tags), allow_filtering: true) |> List.first |> Map.get(:id)) |> to(eq id) end + it "writes log to io in :cyan when logging enabled" do + message = capture_log(fn -> + TestRepo.all((from p in Post), log: true) + end) + expect(message) |> to(start_with "\e[36") + end end end context "with :update_all" do diff --git a/spec/cassandra_ecto/log_spec.exs b/spec/cassandra_ecto/log_spec.exs new file mode 100644 index 0000000..2455bba --- /dev/null +++ b/spec/cassandra_ecto/log_spec.exs @@ -0,0 +1,19 @@ +defmodule CassandraEctoLogSpec do + alias Cassandra.Ecto.Log + + use ESpec, async: true + + describe "Cassandra.Log" do + describe "log/4" do + it "writes log to io in cyan color for select queries" do + entry = %{connection_time: 0, decode_time: nil, + pool_time: nil, result: {:ok, []}, query: "SELECT something"} + message = capture_log(fn -> + Log.log(TestRepo, [], entry, []) + end) + expect(message) |> to(start_with "\e[36m\n") + expect(message) |> to(end_with "[debug] QUERY OK db=0.0ms\nSELECT something []\n\e[0m") + end + end + end +end diff --git a/spec/cassandra_ecto/migration/cql_spec.ex b/spec/cassandra_ecto/migration/cql_spec.ex index f3f2b1b..dfb4ada 100644 --- a/spec/cassandra_ecto/migration/cql_spec.ex +++ b/spec/cassandra_ecto/migration/cql_spec.ex @@ -20,8 +20,8 @@ defmodule CassandraEctoMigrationCQLSpec do |> to(eq "CREATE TYPE \"test\" (\"a\" int, \"b\" int)") end it "generates cql to create materialized view" do - to_cql({:create, %Table{name: :test_view, options: [type: :materialized_view, as: (from p in "test", select: {p.a, p.b}), primary_key: {:a, :b}, comment: "test"]}, []}) - |> to(eq "CREATE MATERIALIZED VIEW \"test_view\" AS SELECT \"a\", \"b\" FROM \"test\" PRIMARY KEY (\"a\", \"b\") WITH COMMENT = 'test'") + to_cql({:create, %Table{name: :test_view, options: [type: :materialized_view, as: (from p in "test", select: {p.a, p.b}, where: not(is_nil(p.a)) and not(is_nil(p.b))), primary_key: {:a, :b}, comment: "test"]}, []}) + |> to(eq "CREATE MATERIALIZED VIEW \"test_view\" AS SELECT \"a\", \"b\" FROM \"test\" WHERE \"a\" IS NOT NULL AND \"b\" IS NOT NULL PRIMARY KEY (\"a\", \"b\") WITH COMMENT = 'test'") end end context "with :alter" do