1Code.require_file("../test_helper.exs", __DIR__) 2 3defmodule ExUnit.FiltersTest do 4 use ExUnit.Case, async: true 5 6 doctest ExUnit.Filters 7 8 describe "filter precedence" do 9 setup do 10 [ 11 one: %{ 12 one: true, 13 numeric: true, 14 test: :"test one", 15 test_type: :test 16 }, 17 two: %{ 18 skip: true, 19 numeric: true, 20 test: :"test two", 21 test_type: :test, 22 two: true 23 } 24 ] 25 end 26 27 test "no filters", tags do 28 assert ExUnit.Filters.eval([], [], tags.one, []) == :ok 29 assert ExUnit.Filters.eval([], [], tags.two, []) == {:skipped, "due to skip tag"} 30 end 31 32 test "exclude tests", tags do 33 assert ExUnit.Filters.eval([], [:two], tags.one, []) == :ok 34 assert ExUnit.Filters.eval([], [:test], tags.one, []) == {:excluded, "due to test filter"} 35 assert ExUnit.Filters.eval([], [:test], tags.two, []) == {:excluded, "due to test filter"} 36 37 assert ExUnit.Filters.eval([], [:numeric], tags.one, []) == 38 {:excluded, "due to numeric filter"} 39 40 assert ExUnit.Filters.eval([], [:unknown], tags.one, []) == :ok 41 assert ExUnit.Filters.eval([], [:unknown], tags.two, []) == {:skipped, "due to skip tag"} 42 end 43 44 test "explicitly exclude a test with the :skip tag", tags do 45 # --exclude two 46 assert ExUnit.Filters.eval([], [:two], tags.two, []) == {:excluded, "due to two filter"} 47 48 assert ExUnit.Filters.eval([], [:two, :test], tags.two, []) == 49 {:excluded, "due to two filter"} 50 end 51 52 test "include tests", tags do 53 # use --include, exclude is missing 54 assert ExUnit.Filters.eval([:two], [], tags.one, []) == :ok 55 assert ExUnit.Filters.eval([:unknown], [], tags.one, []) == :ok 56 57 # --only 58 assert ExUnit.Filters.eval([:one], [:test], tags.one, []) == :ok 59 60 assert ExUnit.Filters.eval([:two], [:test], tags.one, []) == 61 {:excluded, "due to test filter"} 62 63 assert ExUnit.Filters.eval([:unknown], [:test], tags.one, []) == 64 {:excluded, "due to test filter"} 65 66 assert ExUnit.Filters.eval([:unknown], [:test], tags.two, []) == 67 {:excluded, "due to test filter"} 68 end 69 70 test "explicitly include a test with the :skip tag", tags do 71 # --include two, exclude is missing 72 assert ExUnit.Filters.eval([:two], [], tags.two, []) == {:skipped, "due to skip tag"} 73 74 # --only two 75 assert ExUnit.Filters.eval([:two], [:test], tags.two, []) == {:skipped, "due to skip tag"} 76 end 77 78 test "exception to the rule: include tests with the :skip tag", tags do 79 # --include skip, exclude is missing 80 assert ExUnit.Filters.eval([:skip], [], tags.two, []) == :ok 81 assert ExUnit.Filters.eval([:skip], [], %{tags.two | skip: "skip me please"}, []) == :ok 82 assert ExUnit.Filters.eval([skip: ~r/alpha/], [], %{tags.two | skip: "alpha"}, []) == :ok 83 84 assert ExUnit.Filters.eval([skip: ~r/alpha/], [], %{tags.two | skip: "beta"}, []) == 85 {:skipped, "beta"} 86 87 # --only skip 88 assert ExUnit.Filters.eval([:skip], [:test], tags.two, []) == :ok 89 90 assert ExUnit.Filters.eval([:skip], [:test], %{tags.two | skip: "skip me please"}, []) == 91 :ok 92 93 assert ExUnit.Filters.eval([skip: ~r/alpha/], [:test], %{tags.two | skip: "alpha"}, []) == 94 :ok 95 96 assert ExUnit.Filters.eval([skip: ~r/alpha/], [:test], %{tags.two | skip: "beta"}, []) == 97 {:excluded, "due to test filter"} 98 end 99 end 100 101 test "evaluating filters" do 102 assert ExUnit.Filters.eval([], [:os], %{}, []) == :ok 103 assert ExUnit.Filters.eval([], [os: :win], %{os: :unix}, []) == :ok 104 assert ExUnit.Filters.eval([], [:os], %{os: :unix}, []) == {:excluded, "due to os filter"} 105 106 assert ExUnit.Filters.eval([], [os: :unix], %{os: :unix}, []) == 107 {:excluded, "due to os filter"} 108 109 assert ExUnit.Filters.eval([os: :win], [], %{}, []) == :ok 110 assert ExUnit.Filters.eval([os: :win], [], %{os: :unix}, []) == :ok 111 assert ExUnit.Filters.eval([os: :win], [:os], %{}, []) == :ok 112 assert ExUnit.Filters.eval([os: :win], [:os], %{os: :win}, []) == :ok 113 114 assert ExUnit.Filters.eval([os: :win, os: :unix], [:os], %{os: :win}, []) == :ok 115 end 116 117 describe "evaluating filters with skip" do 118 test "regular usage" do 119 assert ExUnit.Filters.eval([], [], %{}, []) == :ok 120 assert ExUnit.Filters.eval([], [], %{skip: true}, []) == {:skipped, "due to skip tag"} 121 assert ExUnit.Filters.eval([], [], %{skip: "skipped"}, []) == {:skipped, "skipped"} 122 assert ExUnit.Filters.eval([], [:os], %{skip: "skipped"}, []) == {:skipped, "skipped"} 123 end 124 125 test "exception to the rule: explicitly including tests with the :skip tag" do 126 assert ExUnit.Filters.eval([:skip], [], %{skip: true}, []) == :ok 127 assert ExUnit.Filters.eval([:skip], [], %{skip: "skipped"}, []) == :ok 128 assert ExUnit.Filters.eval([:skip], [:test], %{skip: true}, []) == :ok 129 assert ExUnit.Filters.eval([:skip], [:test], %{skip: "skipped"}, []) == :ok 130 assert ExUnit.Filters.eval([skip: true], [:test], %{skip: true}, []) == :ok 131 132 assert ExUnit.Filters.eval([skip: ~r/skip me/], [:test], %{skip: "skip me please"}, []) == 133 :ok 134 135 assert ExUnit.Filters.eval([skip: ~r/skip me/], [:test], %{skip: "don't skip!"}, []) == 136 {:skipped, "don't skip!"} 137 end 138 end 139 140 test "evaluating filters matches integers" do 141 assert ExUnit.Filters.eval([int: "1"], [], %{int: 1}, []) == :ok 142 assert ExUnit.Filters.eval([int: "1"], [int: 5], %{int: 1}, []) == :ok 143 assert ExUnit.Filters.eval([int: "1"], [:int], %{int: 1}, []) == :ok 144 end 145 146 test "evaluating filter matches atoms" do 147 assert ExUnit.Filters.eval([os: "win"], [], %{os: :win}, []) == :ok 148 assert ExUnit.Filters.eval([os: "win"], [os: :unix], %{os: :win}, []) == :ok 149 assert ExUnit.Filters.eval([os: "win"], [:os], %{os: :win}, []) == :ok 150 assert ExUnit.Filters.eval([module: "Foo"], [:os], %{module: Foo}, []) == :ok 151 end 152 153 test "evaluating filter matches regexes" do 154 assert ExUnit.Filters.eval([os: ~r"win"], [], %{os: :win}, []) == :ok 155 156 assert ExUnit.Filters.eval([os: ~r"mac"], [os: :unix], %{os: :unix}, []) == 157 {:excluded, "due to os filter"} 158 end 159 160 test "evaluating filter uses special rules for line" do 161 tests = [ 162 %ExUnit.Test{tags: %{line: 3, describe_line: 2}}, 163 %ExUnit.Test{tags: %{line: 5, describe_line: nil}}, 164 %ExUnit.Test{tags: %{line: 8, describe_line: 7}}, 165 %ExUnit.Test{tags: %{line: 10, describe_line: 7}}, 166 %ExUnit.Test{tags: %{line: 13, describe_line: 12}} 167 ] 168 169 assert ExUnit.Filters.eval([line: "3"], [:line], %{line: 3, describe_line: 2}, tests) == :ok 170 assert ExUnit.Filters.eval([line: "4"], [:line], %{line: 3, describe_line: 2}, tests) == :ok 171 assert ExUnit.Filters.eval([line: "5"], [:line], %{line: 5, describe_line: nil}, tests) == :ok 172 assert ExUnit.Filters.eval([line: "6"], [:line], %{line: 5, describe_line: nil}, tests) == :ok 173 assert ExUnit.Filters.eval([line: "2"], [:line], %{line: 3, describe_line: 2}, tests) == :ok 174 assert ExUnit.Filters.eval([line: "7"], [:line], %{line: 8, describe_line: 7}, tests) == :ok 175 assert ExUnit.Filters.eval([line: "7"], [:line], %{line: 10, describe_line: 7}, tests) == :ok 176 177 assert ExUnit.Filters.eval([line: "1"], [:line], %{line: 3, describe_line: 2}, tests) == 178 {:excluded, "due to line filter"} 179 180 assert ExUnit.Filters.eval([line: "7"], [:line], %{line: 3, describe_line: 2}, tests) == 181 {:excluded, "due to line filter"} 182 183 assert ExUnit.Filters.eval([line: "7"], [:line], %{line: 5, describe_line: nil}, tests) == 184 {:excluded, "due to line filter"} 185 end 186 187 test "parsing filters" do 188 assert ExUnit.Filters.parse(["run"]) == [:run] 189 assert ExUnit.Filters.parse(["run:true"]) == [run: "true"] 190 assert ExUnit.Filters.parse(["run:test"]) == [run: "test"] 191 assert ExUnit.Filters.parse(["line:9"]) == [line: "9"] 192 end 193 194 test "file paths with line numbers" do 195 assert ExUnit.Filters.parse_path("test/some/path.exs:123") == 196 {"test/some/path.exs", [exclude: [:test], include: [line: "123"]]} 197 198 assert ExUnit.Filters.parse_path("test/some/path.exs") == {"test/some/path.exs", []} 199 200 assert ExUnit.Filters.parse_path("test/some/path.exs:123notreallyalinenumber123") == 201 {"test/some/path.exs:123notreallyalinenumber123", []} 202 203 assert ExUnit.Filters.parse_path("C:\\some\\path.exs:123") == 204 {"C:\\some\\path.exs", [exclude: [:test], include: [line: "123"]]} 205 206 assert ExUnit.Filters.parse_path("C:\\some\\path.exs") == {"C:\\some\\path.exs", []} 207 208 assert ExUnit.Filters.parse_path("C:\\some\\path.exs:123notreallyalinenumber123") == 209 {"C:\\some\\path.exs:123notreallyalinenumber123", []} 210 211 assert ExUnit.Filters.parse_path("test/some/path.exs:123:456") == 212 {"test/some/path.exs", [exclude: [:test], include: [line: "123", line: "456"]]} 213 214 assert ExUnit.Filters.parse_path("C:\\some\\path.exs:123:456") == 215 {"C:\\some\\path.exs", [exclude: [:test], include: [line: "123", line: "456"]]} 216 217 assert ExUnit.Filters.parse_path("test/some/path.exs:123notalinenumber123:456") == 218 {"test/some/path.exs:123notalinenumber123", 219 [exclude: [:test], include: [line: "456"]]} 220 221 assert ExUnit.Filters.parse_path("test/some/path.exs:123:456notalinenumber456") == 222 {"test/some/path.exs:123:456notalinenumber456", []} 223 224 assert ExUnit.Filters.parse_path("C:\\some\\path.exs:123notalinenumber123:456") == 225 {"C:\\some\\path.exs:123notalinenumber123", 226 [exclude: [:test], include: [line: "456"]]} 227 228 assert ExUnit.Filters.parse_path("C:\\some\\path.exs:123:456notalinenumber456") == 229 {"C:\\some\\path.exs:123:456notalinenumber456", []} 230 231 output = 232 ExUnit.CaptureIO.capture_io(:stderr, fn -> 233 assert ExUnit.Filters.parse_path("test/some/path.exs:123:0:-789:456") == 234 {"test/some/path.exs", [exclude: [:test], include: [line: "123", line: "456"]]} 235 end) 236 237 assert output =~ "invalid line number given as ExUnit filter: 0" 238 assert output =~ "invalid line number given as ExUnit filter: -789" 239 end 240end 241