zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

type.exs (21228B)


      1 defmodule Ecto.Integration.TypeTest do
      2   use Ecto.Integration.Case, async: Application.compile_env(:ecto, :async_integration_tests, true)
      3 
      4   alias Ecto.Integration.{Comment, Custom, Item, ItemColor, Order, Post, User, Tag, Usec}
      5   alias Ecto.Integration.TestRepo
      6   import Ecto.Query
      7 
      8   @parameterized_type Ecto.ParameterizedType.init(Ecto.Enum, values: [:a, :b])
      9 
     10   test "primitive types" do
     11     integer  = 1
     12     float    = 0.1
     13     blob     = <<0, 1>>
     14     uuid     = "00010203-0405-4607-8809-0a0b0c0d0e0f"
     15     datetime = ~N[2014-01-16 20:26:51]
     16 
     17     TestRepo.insert!(%Post{blob: blob, public: true, visits: integer, uuid: uuid,
     18                            counter: integer, inserted_at: datetime, intensity: float})
     19 
     20     # nil
     21     assert [nil] = TestRepo.all(from Post, select: nil)
     22 
     23     # ID
     24     assert [1] = TestRepo.all(from p in Post, where: p.counter == ^integer, select: p.counter)
     25 
     26     # Integers
     27     assert [1] = TestRepo.all(from p in Post, where: p.visits == ^integer, select: p.visits)
     28     assert [1] = TestRepo.all(from p in Post, where: p.visits == 1, select: p.visits)
     29     assert [3] = TestRepo.all(from p in Post, select: p.visits + 2)
     30 
     31     # Floats
     32     assert [0.1] = TestRepo.all(from p in Post, where: p.intensity == ^float, select: p.intensity)
     33     assert [0.1] = TestRepo.all(from p in Post, where: p.intensity == 0.1, select: p.intensity)
     34     assert [1500.0] = TestRepo.all(from p in Post, select: 1500.0)
     35     assert [0.5] = TestRepo.all(from p in Post, select: p.intensity * 5)
     36 
     37     # Booleans
     38     assert [true] = TestRepo.all(from p in Post, where: p.public == ^true, select: p.public)
     39     assert [true] = TestRepo.all(from p in Post, where: p.public == true, select: p.public)
     40 
     41     # Binaries
     42     assert [^blob] = TestRepo.all(from p in Post, where: p.blob == <<0, 1>>, select: p.blob)
     43     assert [^blob] = TestRepo.all(from p in Post, where: p.blob == ^blob, select: p.blob)
     44 
     45     # UUID
     46     assert [^uuid] = TestRepo.all(from p in Post, where: p.uuid == ^uuid, select: p.uuid)
     47 
     48     # NaiveDatetime
     49     assert [^datetime] = TestRepo.all(from p in Post, where: p.inserted_at == ^datetime, select: p.inserted_at)
     50 
     51     # Datetime
     52     datetime = DateTime.from_unix!(System.os_time(:second), :second)
     53     TestRepo.insert!(%User{inserted_at: datetime})
     54     assert [^datetime] = TestRepo.all(from u in User, where: u.inserted_at == ^datetime, select: u.inserted_at)
     55 
     56     # usec
     57     naive_datetime = ~N[2014-01-16 20:26:51.000000]
     58     datetime = DateTime.from_naive!(~N[2014-01-16 20:26:51.000000], "Etc/UTC")
     59     TestRepo.insert!(%Usec{naive_datetime_usec: naive_datetime, utc_datetime_usec: datetime})
     60     assert [^naive_datetime] = TestRepo.all(from u in Usec, where: u.naive_datetime_usec == ^naive_datetime, select: u.naive_datetime_usec)
     61     assert [^datetime] = TestRepo.all(from u in Usec, where: u.utc_datetime_usec == ^datetime, select: u.utc_datetime_usec)
     62 
     63     naive_datetime = ~N[2014-01-16 20:26:51.123000]
     64     datetime = DateTime.from_naive!(~N[2014-01-16 20:26:51.123000], "Etc/UTC")
     65     TestRepo.insert!(%Usec{naive_datetime_usec: naive_datetime, utc_datetime_usec: datetime})
     66     assert [^naive_datetime] = TestRepo.all(from u in Usec, where: u.naive_datetime_usec == ^naive_datetime, select: u.naive_datetime_usec)
     67     assert [^datetime] = TestRepo.all(from u in Usec, where: u.utc_datetime_usec == ^datetime, select: u.utc_datetime_usec)
     68   end
     69 
     70   @tag :select_not
     71   test "primitive types boolean negate" do
     72     TestRepo.insert!(%Post{public: true})
     73     assert [false] = TestRepo.all(from p in Post, where: p.public == true, select: not p.public)
     74     assert [true] = TestRepo.all(from p in Post, where: p.public == true, select: not not p.public)
     75   end
     76 
     77   test "aggregate types" do
     78     datetime = ~N[2014-01-16 20:26:51]
     79     TestRepo.insert!(%Post{inserted_at: datetime})
     80     query = from p in Post, select: max(p.inserted_at)
     81     assert [^datetime] = TestRepo.all(query)
     82   end
     83 
     84   # We don't specifically assert on the tuple content because
     85   # some databases would return integer, others decimal.
     86   # The important is that the type has been invoked for wrapping.
     87   test "aggregate custom types" do
     88     TestRepo.insert!(%Post{wrapped_visits: {:int, 10}})
     89     query = from p in Post, select: sum(p.wrapped_visits)
     90     assert [{:int, _}] = TestRepo.all(query)
     91   end
     92 
     93   @tag :aggregate_filters
     94   test "aggregate filter types" do
     95     datetime = ~N[2014-01-16 20:26:51]
     96     TestRepo.insert!(%Post{inserted_at: datetime})
     97     query = from p in Post, select: filter(max(p.inserted_at), p.public == ^true)
     98     assert [^datetime] = TestRepo.all(query)
     99   end
    100 
    101   test "coalesce text type when default" do
    102     TestRepo.insert!(%Post{blob: nil})
    103     blob = <<0, 1>>
    104     query = from p in Post, select: coalesce(p.blob, ^blob)
    105     assert [^blob] = TestRepo.all(query)
    106   end
    107 
    108   test "coalesce text type when value" do
    109     blob = <<0, 2>>
    110     default_blob = <<0, 1>>
    111     TestRepo.insert!(%Post{blob: blob})
    112     query = from p in Post, select: coalesce(p.blob, ^default_blob)
    113     assert [^blob] = TestRepo.all(query)
    114   end
    115 
    116   test "tagged types" do
    117     %{id: post_id} = TestRepo.insert!(%Post{visits: 12})
    118     TestRepo.insert!(%Comment{text: "#{post_id}", post_id: post_id})
    119 
    120     # Numbers
    121     assert [1]   = TestRepo.all(from Post, select: type(^"1", :integer))
    122     assert [1.0] = TestRepo.all(from Post, select: type(^1.0, :float))
    123     assert [1]   = TestRepo.all(from p in Post, select: type(^"1", p.visits))
    124     assert [1.0] = TestRepo.all(from p in Post, select: type(^"1", p.intensity))
    125 
    126     # Custom wrappers
    127     assert [1] = TestRepo.all(from Post, select: type(^"1", CustomPermalink))
    128 
    129     # Custom types
    130     uuid = Ecto.UUID.generate()
    131     assert [^uuid] = TestRepo.all(from Post, select: type(^uuid, Ecto.UUID))
    132 
    133     # Parameterized types
    134     assert [:a] = TestRepo.all(from Post, select: type(^"a", ^@parameterized_type))
    135 
    136     # Math operations
    137     assert [4]   = TestRepo.all(from Post, select: type(2 + ^"2", :integer))
    138     assert [4.0] = TestRepo.all(from Post, select: type(2.0 + ^"2", :float))
    139     assert [4]   = TestRepo.all(from p in Post, select: type(2 + ^"2", p.visits))
    140     assert [4.0] = TestRepo.all(from p in Post, select: type(2.0 + ^"2", p.intensity))
    141 
    142     # Comparison expression
    143     assert [12] = TestRepo.all(from p in Post, select: type(coalesce(p.visits, 0), :integer))
    144     assert [1.0] = TestRepo.all(from p in Post, select: type(coalesce(p.intensity, 1.0), :float))
    145 
    146     # parent_as/1
    147     child = from c in Comment, where: type(parent_as(:posts).id, :string) == c.text, select: c.post_id
    148     query = from p in Post, as: :posts, where: p.id in subquery(child), select: p.id
    149     assert [post_id] == TestRepo.all(query)
    150   end
    151 
    152   test "binary id type" do
    153     assert %Custom{} = custom = TestRepo.insert!(%Custom{})
    154     bid = custom.bid
    155     assert [^bid] = TestRepo.all(from c in Custom, select: c.bid)
    156     assert [^bid] = TestRepo.all(from c in Custom, select: type(^bid, :binary_id))
    157   end
    158 
    159   @tag :like_match_blob
    160   test "text type as blob" do
    161     assert %Post{} = post = TestRepo.insert!(%Post{blob: <<0, 1, 2>>})
    162     id = post.id
    163     assert post.blob == <<0, 1, 2>>
    164     assert [^id] = TestRepo.all(from p in Post, where: like(p.blob, ^<<0, 1, 2>>), select: p.id)
    165   end
    166 
    167   @tag :like_match_blob
    168   @tag :text_type_as_string
    169   test "text type as string" do
    170     assert %Post{} = post = TestRepo.insert!(%Post{blob: "hello"})
    171     id = post.id
    172     assert post.blob == "hello"
    173     assert [^id] = TestRepo.all(from p in Post, where: like(p.blob, ^"hello"), select: p.id)
    174   end
    175 
    176   @tag :array_type
    177   test "array type" do
    178     ints = [1, 2, 3]
    179     tag = TestRepo.insert!(%Tag{ints: ints})
    180 
    181     assert TestRepo.all(from t in Tag, where: t.ints == ^[], select: t.ints) == []
    182     assert TestRepo.all(from t in Tag, where: t.ints == ^[1, 2, 3], select: t.ints) == [ints]
    183 
    184     # Both sides interpolation
    185     assert TestRepo.all(from t in Tag, where: ^"b" in ^["a", "b", "c"], select: t.ints) == [ints]
    186     assert TestRepo.all(from t in Tag, where: ^"b" in [^"a", ^"b", ^"c"], select: t.ints) == [ints]
    187 
    188     # Querying
    189     assert TestRepo.all(from t in Tag, where: t.ints == [1, 2, 3], select: t.ints) == [ints]
    190     assert TestRepo.all(from t in Tag, where: 0 in t.ints, select: t.ints) == []
    191     assert TestRepo.all(from t in Tag, where: 1 in t.ints, select: t.ints) == [ints]
    192 
    193     # Update
    194     tag = TestRepo.update!(Ecto.Changeset.change tag, ints: nil)
    195     assert TestRepo.get!(Tag, tag.id).ints == nil
    196 
    197     tag = TestRepo.update!(Ecto.Changeset.change tag, ints: [3, 2, 1])
    198     assert TestRepo.get!(Tag, tag.id).ints == [3, 2, 1]
    199 
    200     # Update all
    201     {1, _} = TestRepo.update_all(Tag, push: [ints: 0])
    202     assert TestRepo.get!(Tag, tag.id).ints == [3, 2, 1, 0]
    203 
    204     {1, _} = TestRepo.update_all(Tag, pull: [ints: 2])
    205     assert TestRepo.get!(Tag, tag.id).ints == [3, 1, 0]
    206 
    207     {1, _} = TestRepo.update_all(Tag, set: [ints: nil])
    208     assert TestRepo.get!(Tag, tag.id).ints == nil
    209   end
    210 
    211   @tag :array_type
    212   test "array type with custom types" do
    213     uuids = ["51fcfbdd-ad60-4ccb-8bf9-47aabd66d075"]
    214     TestRepo.insert!(%Tag{uuids: ["51fcfbdd-ad60-4ccb-8bf9-47aabd66d075"]})
    215 
    216     assert TestRepo.all(from t in Tag, where: t.uuids == ^[], select: t.uuids) == []
    217     assert TestRepo.all(from t in Tag, where: t.uuids == ^["51fcfbdd-ad60-4ccb-8bf9-47aabd66d075"],
    218                                        select: t.uuids) == [uuids]
    219 
    220     {1, _} = TestRepo.update_all(Tag, set: [uuids: nil])
    221     assert TestRepo.all(from t in Tag, select: t.uuids) == [nil]
    222   end
    223 
    224   @tag :array_type
    225   test "array type with nil in array" do
    226     tag = TestRepo.insert!(%Tag{ints: [1, nil, 3]})
    227     assert tag.ints == [1, nil, 3]
    228   end
    229 
    230   @tag :map_type
    231   test "untyped map" do
    232     post1 = TestRepo.insert!(%Post{meta: %{"foo" => "bar", "baz" => "bat"}})
    233     post2 = TestRepo.insert!(%Post{meta: %{foo: "bar", baz: "bat"}})
    234 
    235     assert TestRepo.all(from p in Post, where: p.id == ^post1.id, select: p.meta) ==
    236            [%{"foo" => "bar", "baz" => "bat"}]
    237     assert TestRepo.all(from p in Post, where: p.id == ^post2.id, select: p.meta) ==
    238            [%{"foo" => "bar", "baz" => "bat"}]
    239   end
    240 
    241   @tag :map_type
    242   test "typed string map" do
    243     post1 = TestRepo.insert!(%Post{links: %{"foo" => "http://foo.com", "bar" => "http://bar.com"}})
    244     post2 = TestRepo.insert!(%Post{links: %{foo: "http://foo.com", bar: "http://bar.com"}})
    245 
    246     assert TestRepo.all(from p in Post, where: p.id == ^post1.id, select: p.links) ==
    247            [%{"foo" => "http://foo.com", "bar" => "http://bar.com"}]
    248     assert TestRepo.all(from p in Post, where: p.id == ^post2.id, select: p.links) ==
    249            [%{"foo" => "http://foo.com", "bar" => "http://bar.com"}]
    250   end
    251 
    252   @tag :map_type
    253   test "typed float map" do
    254     post = TestRepo.insert!(%Post{intensities: %{"foo" => 1.0, "bar" => 416500.0}})
    255 
    256     # Note we are using === since we want to check integer vs float
    257     assert TestRepo.all(from p in Post, where: p.id == ^post.id, select: p.intensities) ===
    258            [%{"foo" => 1.0, "bar" => 416500.0}]
    259   end
    260 
    261   @tag :map_type
    262   test "map type on update" do
    263     post = TestRepo.insert!(%Post{meta: %{"world" => "hello"}})
    264     assert TestRepo.get!(Post, post.id).meta == %{"world" => "hello"}
    265 
    266     post = TestRepo.update!(Ecto.Changeset.change post, meta: %{hello: "world"})
    267     assert TestRepo.get!(Post, post.id).meta == %{"hello" => "world"}
    268 
    269     query = from(p in Post, where: p.id == ^post.id)
    270     TestRepo.update_all(query, set: [meta: %{world: "hello"}])
    271     assert TestRepo.get!(Post, post.id).meta == %{"world" => "hello"}
    272   end
    273 
    274   @tag :map_type
    275   test "embeds one" do
    276     item = %Item{price: 123, valid_at: ~D[2014-01-16]}
    277 
    278     order =
    279       %Order{}
    280       |> Ecto.Changeset.change
    281       |> Ecto.Changeset.put_embed(:item, item)
    282       |> TestRepo.insert!()
    283 
    284     dbitem = TestRepo.get!(Order, order.id).item
    285     assert item.reference == dbitem.reference
    286     assert item.price == dbitem.price
    287     assert item.valid_at == dbitem.valid_at
    288     assert dbitem.id
    289 
    290     [dbitem] = TestRepo.all(from o in Order, select: o.item)
    291     assert item.reference == dbitem.reference
    292     assert item.price == dbitem.price
    293     assert item.valid_at == dbitem.valid_at
    294     assert dbitem.id
    295 
    296     {1, _} = TestRepo.update_all(Order, set: [item: %{dbitem | price: 456}])
    297     assert TestRepo.get!(Order, order.id).item.price == 456
    298   end
    299 
    300   @tag :map_type
    301   @tag :json_extract_path
    302   test "json_extract_path with primitive values" do
    303     order = %Order{metadata:
    304       %{
    305         :id => 123,
    306         :time => ~T[09:00:00],
    307         "code" => "good",
    308         "'single quoted'" => "bar",
    309         "\"double quoted\"" => "baz",
    310         "enabled" => true,
    311         "extra" => [%{"enabled" => false}]
    312       }
    313     }
    314 
    315     order = TestRepo.insert!(order)
    316 
    317     assert TestRepo.one(from o in Order, select: o.metadata["id"]) == 123
    318     assert TestRepo.one(from o in Order, select: o.metadata["bad"]) == nil
    319     assert TestRepo.one(from o in Order, select: o.metadata["bad"]["bad"]) == nil
    320 
    321     field = "id"
    322     assert TestRepo.one(from o in Order, select: o.metadata[^field]) == 123
    323     assert TestRepo.one(from o in Order, select: o.metadata["time"]) == "09:00:00"
    324     assert TestRepo.one(from o in Order, select: o.metadata["'single quoted'"]) == "bar"
    325     assert TestRepo.one(from o in Order, select: o.metadata["';"]) == nil
    326     assert TestRepo.one(from o in Order, select: o.metadata["\"double quoted\""]) == "baz"
    327     assert TestRepo.one(from o in Order, select: o.metadata["enabled"]) == true
    328     assert TestRepo.one(from o in Order, select: o.metadata["extra"][0]["enabled"]) == false
    329 
    330     # where
    331     assert TestRepo.one(from o in Order, where: o.metadata["id"] == 123, select: o.id) == order.id
    332     assert TestRepo.one(from o in Order, where: o.metadata["id"] == 456, select: o.id) == nil
    333     assert TestRepo.one(from o in Order, where: o.metadata["code"] == "good", select: o.id) == order.id
    334     assert TestRepo.one(from o in Order, where: o.metadata["code"] == "bad", select: o.id) == nil
    335     assert TestRepo.one(from o in Order, where: o.metadata["enabled"] == true, select: o.id) == order.id
    336     assert TestRepo.one(from o in Order, where: o.metadata["extra"][0]["enabled"] == false, select: o.id) == order.id
    337   end
    338 
    339   @tag :map_type
    340   @tag :json_extract_path
    341   test "json_extract_path with arrays and objects" do
    342     order = %Order{metadata: %{tags: [%{name: "red"}, %{name: "green"}]}}
    343     order = TestRepo.insert!(order)
    344 
    345     assert TestRepo.one(from o in Order, select: o.metadata["tags"][0]["name"]) == "red"
    346     assert TestRepo.one(from o in Order, select: o.metadata["tags"][99]["name"]) == nil
    347 
    348     index = 1
    349     assert TestRepo.one(from o in Order, select: o.metadata["tags"][^index]["name"]) == "green"
    350 
    351     # where
    352     assert TestRepo.one(from o in Order, where: o.metadata["tags"][0]["name"] == "red", select: o.id) == order.id
    353     assert TestRepo.one(from o in Order, where: o.metadata["tags"][0]["name"] == "blue", select: o.id) == nil
    354     assert TestRepo.one(from o in Order, where: o.metadata["tags"][99]["name"] == "red", select: o.id) == nil
    355   end
    356 
    357   @tag :map_type
    358   @tag :json_extract_path
    359   test "json_extract_path with embeds" do
    360     order = %Order{items: [%{valid_at: ~D[2020-01-01]}]}
    361     TestRepo.insert!(order)
    362 
    363     assert TestRepo.one(from o in Order, select: o.items[0]["valid_at"]) == "2020-01-01"
    364   end
    365 
    366   @tag :map_type
    367   @tag :json_extract_path
    368   test "json_extract_path with custom field source" do
    369     order = TestRepo.insert!(%Order{metadata: %{tags: [%{name: "red"}, %{name: "green"}]}})
    370 
    371     assert TestRepo.one(from o in Order, where: o.metadata["tags"][0]["name"] == "red", select: o.id) == order.id
    372   end
    373 
    374   @tag :map_type
    375   @tag :map_type_schemaless
    376   test "embeds one with custom type" do
    377     item = %Item{price: 123, reference: "PREFIX-EXAMPLE"}
    378 
    379     order =
    380       %Order{}
    381       |> Ecto.Changeset.change
    382       |> Ecto.Changeset.put_embed(:item, item)
    383       |> TestRepo.insert!()
    384 
    385     dbitem = TestRepo.get!(Order, order.id).item
    386     assert dbitem.reference == "PREFIX-EXAMPLE"
    387     assert [%{"reference" => "EXAMPLE"}] = TestRepo.all(from o in "orders", select: o.item)
    388   end
    389 
    390   @tag :map_type
    391   test "empty embeds one" do
    392     order = TestRepo.insert!(%Order{})
    393     assert order.item == nil
    394     assert TestRepo.get!(Order, order.id).item == nil
    395   end
    396 
    397   @tag :map_type
    398   @tag :array_type
    399   test "embeds many" do
    400     item = %Item{price: 123, valid_at: ~D[2014-01-16]}
    401     tag =
    402       %Tag{}
    403       |> Ecto.Changeset.change
    404       |> Ecto.Changeset.put_embed(:items, [item])
    405     tag = TestRepo.insert!(tag)
    406 
    407     [dbitem] = TestRepo.get!(Tag, tag.id).items
    408     assert item.price == dbitem.price
    409     assert item.valid_at == dbitem.valid_at
    410     assert dbitem.id
    411 
    412     [[dbitem]] = TestRepo.all(from t in Tag, select: t.items)
    413     assert item.price == dbitem.price
    414     assert item.valid_at == dbitem.valid_at
    415     assert dbitem.id
    416 
    417     {1, _} = TestRepo.update_all(Tag, set: [items: [%{dbitem | price: 456}]])
    418     assert (TestRepo.get!(Tag, tag.id).items |> hd).price == 456
    419   end
    420 
    421   @tag :map_type
    422   @tag :array_type
    423   test "empty embeds many" do
    424     tag = TestRepo.insert!(%Tag{})
    425     assert tag.items == []
    426     assert TestRepo.get!(Tag, tag.id).items == []
    427   end
    428 
    429   @tag :map_type
    430   @tag :array_type
    431   test "nested embeds" do
    432     red = %ItemColor{name: "red"}
    433     blue = %ItemColor{name: "blue"}
    434     item = %Item{
    435       primary_color: red,
    436       secondary_colors: [blue]
    437     }
    438 
    439     order =
    440       %Order{}
    441       |> Ecto.Changeset.change
    442       |> Ecto.Changeset.put_embed(:item, item)
    443     order = TestRepo.insert!(order)
    444 
    445     dbitem = TestRepo.get!(Order, order.id).item
    446     assert dbitem.primary_color.name == "red"
    447     assert Enum.map(dbitem.secondary_colors, & &1.name) == ["blue"]
    448     assert dbitem.id
    449     assert dbitem.primary_color.id
    450 
    451     [dbitem] = TestRepo.all(from o in Order, select: o.item)
    452     assert dbitem.primary_color.name == "red"
    453     assert Enum.map(dbitem.secondary_colors, & &1.name) == ["blue"]
    454     assert dbitem.id
    455     assert dbitem.primary_color.id
    456   end
    457 
    458   @tag :decimal_type
    459   test "decimal type" do
    460     decimal = Decimal.new("1.0")
    461     TestRepo.insert!(%Post{cost: decimal})
    462 
    463     [cost] = TestRepo.all(from p in Post, where: p.cost == ^decimal, select: p.cost)
    464     assert Decimal.equal?(decimal, cost)
    465     [cost] = TestRepo.all(from p in Post, where: p.cost == ^1.0, select: p.cost)
    466     assert Decimal.equal?(decimal, cost)
    467     [cost] = TestRepo.all(from p in Post, where: p.cost == ^1, select: p.cost)
    468     assert Decimal.equal?(decimal, cost)
    469     [cost] = TestRepo.all(from p in Post, where: p.cost == 1.0, select: p.cost)
    470     assert Decimal.equal?(decimal, cost)
    471     [cost] = TestRepo.all(from p in Post, where: p.cost == 1, select: p.cost)
    472     assert Decimal.equal?(decimal, cost)
    473     [cost] = TestRepo.all(from p in Post, select: p.cost * 2)
    474     assert Decimal.equal?(Decimal.new("2.0"), cost)
    475     [cost] = TestRepo.all(from p in Post, select: p.cost - p.cost)
    476     assert Decimal.equal?(Decimal.new("0.0"), cost)
    477   end
    478 
    479   @tag :decimal_type
    480   @tag :decimal_precision
    481   test "decimal typed aggregations" do
    482     decimal = Decimal.new("1.0")
    483     TestRepo.insert!(%Post{cost: decimal})
    484 
    485     assert [1] = TestRepo.all(from p in Post, select: type(sum(p.cost), :integer))
    486     assert [1.0] = TestRepo.all(from p in Post, select: type(sum(p.cost), :float))
    487     [cost] = TestRepo.all(from p in Post, select: type(sum(p.cost), :decimal))
    488     assert Decimal.equal?(decimal, cost)
    489   end
    490 
    491   @tag :decimal_type
    492   test "on coalesce with mixed types" do
    493     decimal = Decimal.new("1.0")
    494     TestRepo.insert!(%Post{cost: decimal})
    495     [cost] = TestRepo.all(from p in Post, select: coalesce(p.cost, 0))
    496     assert Decimal.equal?(decimal, cost)
    497   end
    498 
    499   @tag :union_with_literals
    500   test "unions with literals" do
    501     TestRepo.insert!(%Post{})
    502     TestRepo.insert!(%Post{})
    503 
    504     query1 = from(p in Post, select: %{n: 1})
    505     query2 = from(p in Post, select: %{n: 2})
    506 
    507     assert TestRepo.all(union_all(query1, ^query2)) ==
    508             [%{n: 1}, %{n: 1}, %{n: 2}, %{n: 2}]
    509 
    510     query1 = from(p in Post, select: %{n: 1.0})
    511     query2 = from(p in Post, select: %{n: 2.0})
    512 
    513     assert TestRepo.all(union_all(query1, ^query2)) ==
    514             [%{n: 1.0}, %{n: 1.0}, %{n: 2.0}, %{n: 2.0}]
    515 
    516     query1 = from(p in Post, select: %{n: "foo"})
    517     query2 = from(p in Post, select: %{n: "bar"})
    518 
    519     assert TestRepo.all(union_all(query1, ^query2)) ==
    520             [%{n: "foo"}, %{n: "foo"}, %{n: "bar"}, %{n: "bar"}]
    521   end
    522 
    523   test "schemaless types" do
    524     TestRepo.insert!(%Post{visits: 123})
    525     assert [123] = TestRepo.all(from p in "posts", select: type(p.visits, :integer))
    526   end
    527 
    528   test "schemaless calendar types" do
    529     datetime = ~N[2014-01-16 20:26:51]
    530     assert {1, _} =
    531            TestRepo.insert_all("posts", [[inserted_at: datetime]])
    532     assert {1, _} =
    533            TestRepo.update_all("posts", set: [inserted_at: datetime])
    534     assert [_] =
    535            TestRepo.all(from p in "posts", where: p.inserted_at >= ^datetime, select: p.inserted_at)
    536     assert [_] =
    537            TestRepo.all(from p in "posts", where: p.inserted_at in [^datetime], select: p.inserted_at)
    538     assert [_] =
    539            TestRepo.all(from p in "posts", where: p.inserted_at in ^[datetime], select: p.inserted_at)
    540   end
    541 end