1defmodule Ecto.Query.Builder.OrderByTest do 2 use ExUnit.Case, async: true 3 4 import Ecto.Query.Builder.OrderBy 5 doctest Ecto.Query.Builder.OrderBy 6 7 import Ecto.Query 8 9 describe "escape" do 10 test "handles expressions and params" do 11 assert {Macro.escape(quote do [asc: &0.y] end), %{}} == 12 escape(:order_by, quote do x.y end, [x: 0], __ENV__) 13 14 assert {Macro.escape(quote do [asc: &0.x, asc: &1.y] end), %{}} == 15 escape(:order_by, quote do [x.x, y.y] end, [x: 0, y: 1], __ENV__) 16 17 assert {Macro.escape(quote do [asc: &0.x, desc: &1.y] end), %{}} == 18 escape(:order_by, quote do [asc: x.x, desc: y.y] end, [x: 0, y: 1], __ENV__) 19 20 assert {Macro.escape(quote do [asc: &0.x, desc: &1.y] end), %{}} == 21 escape(:order_by, quote do [x.x, desc: y.y] end, [x: 0, y: 1], __ENV__) 22 23 assert {Macro.escape(quote do [asc: &0.x] end), %{}} == 24 escape(:order_by, quote do :x end, [x: 0], __ENV__) 25 26 assert {Macro.escape(quote do [asc: &0.x, desc: &0.y] end), %{}} == 27 escape(:order_by, quote do [:x, desc: :y] end, [x: 0], __ENV__) 28 29 import Kernel, except: [>: 2] 30 assert {Macro.escape(quote do [asc: 1 > 2] end), %{}} == 31 escape(:order_by, quote do 1 > 2 end, [], __ENV__) 32 end 33 34 test "raises on unbound variables" do 35 assert_raise Ecto.Query.CompileError, "unbound variable `x` in query", fn -> 36 escape(:order_by, quote do x.y end, [], __ENV__) 37 end 38 end 39 40 test "raises on unknown expression" do 41 message = "expected :asc, :desc or interpolated value in `order_by`, got: `:test`" 42 assert_raise Ecto.Query.CompileError, message, fn -> 43 escape(:order_by, quote do [test: x.y] end, [x: 0], __ENV__) 44 end 45 end 46 end 47 48 describe "at runtime" do 49 test "accepts fields, lists or keyword lists" do 50 key = :title 51 dir = :desc 52 assert order_by("q", [q], ^key).order_bys == order_by("q", [q], [asc: q.title]).order_bys 53 assert order_by("q", [q], [^key]).order_bys == order_by("q", [q], [asc: q.title]).order_bys 54 assert order_by("q", [q], [desc: ^key]).order_bys == order_by("q", [q], [desc: q.title]).order_bys 55 assert order_by("q", [q], [{^dir, ^key}]).order_bys == order_by("q", [q], [desc: q.title]).order_bys 56 end 57 58 test "raises on invalid direction" do 59 message = "expected :asc or :desc in `order_by`, got: `:temp`" 60 assert_raise Ecto.Query.CompileError, message, fn -> 61 temp = :temp 62 order_by("posts", [p], [{^var!(temp), p.y}]) 63 end 64 end 65 66 test "raises on invalid field" do 67 message = "expected a field as an atom, a list or keyword list in `order_by`, got: `\"temp\"`" 68 assert_raise ArgumentError, message, fn -> 69 temp = "temp" 70 order_by("posts", [p], [asc: ^temp]) 71 end 72 end 73 74 test "raises on invalid interpolation" do 75 message = "expected a field as an atom, a list or keyword list in `order_by`, got: `\"temp\"`" 76 assert_raise ArgumentError, message, fn -> 77 temp = "temp" 78 order_by("posts", [p], ^temp) 79 end 80 end 81 end 82end 83