1Code.require_file("test_helper.exs", __DIR__) 2 3defmodule VersionTest do 4 use ExUnit.Case, async: true 5 6 doctest Version 7 8 alias Version.Parser 9 10 test "compare/2 with valid versions" do 11 assert Version.compare("1.0.1", "1.0.0") == :gt 12 assert Version.compare("1.1.0", "1.0.1") == :gt 13 assert Version.compare("2.1.1", "1.2.2") == :gt 14 assert Version.compare("1.0.0", "1.0.0-dev") == :gt 15 assert Version.compare("1.2.3-dev", "0.1.2") == :gt 16 assert Version.compare("1.0.0-a.b", "1.0.0-a") == :gt 17 assert Version.compare("1.0.0-b", "1.0.0-a.b") == :gt 18 assert Version.compare("1.0.0-a", "1.0.0-0") == :gt 19 assert Version.compare("1.0.0-a.b", "1.0.0-a.a") == :gt 20 21 assert Version.compare("1.0.0", "1.0.1") == :lt 22 assert Version.compare("1.0.1", "1.1.0") == :lt 23 assert Version.compare("1.2.2", "2.1.1") == :lt 24 assert Version.compare("1.0.0-dev", "1.0.0") == :lt 25 assert Version.compare("0.1.2", "1.2.3-dev") == :lt 26 assert Version.compare("1.0.0-a", "1.0.0-a.b") == :lt 27 assert Version.compare("1.0.0-a.b", "1.0.0-b") == :lt 28 assert Version.compare("1.0.0-0", "1.0.0-a") == :lt 29 assert Version.compare("1.0.0-a.a", "1.0.0-a.b") == :lt 30 31 assert Version.compare("1.0.0", "1.0.0") == :eq 32 assert Version.compare("1.0.0-dev", "1.0.0-dev") == :eq 33 assert Version.compare("1.0.0-a", "1.0.0-a") == :eq 34 assert Version.compare("1.5.0-rc.0", "1.5.0-rc0") == :lt 35 end 36 37 test "compare/2 with invalid versions" do 38 assert_raise Version.InvalidVersionError, fn -> 39 Version.compare("1.0", "1.0.0") 40 end 41 42 assert_raise Version.InvalidVersionError, fn -> 43 Version.compare("1.0.0-dev", "1.0") 44 end 45 46 assert_raise Version.InvalidVersionError, fn -> 47 Version.compare("foo", "1.0.0-a") 48 end 49 end 50 51 test "lexes specifications properly" do 52 assert Parser.lexer("== != > >= < <= ~>", []) == [:==, :!=, :>, :>=, :<, :<=, :~>] 53 assert Parser.lexer("2.3.0", []) == [:==, {2, 3, 0, [], []}] 54 assert Parser.lexer("!2.3.0", []) == [:!=, {2, 3, 0, [], []}] 55 assert Parser.lexer(">>=", []) == [:>, :>=] 56 assert Parser.lexer(">2.4.0", []) == [:>, {2, 4, 0, [], []}] 57 assert Parser.lexer("> 2.4.0", []) == [:>, {2, 4, 0, [], []}] 58 assert Parser.lexer(" > 2.4.0", []) == [:>, {2, 4, 0, [], []}] 59 assert Parser.lexer(" or 2.1.0", []) == [:||, :==, {2, 1, 0, [], []}] 60 assert Parser.lexer(" and 2.1.0", []) == [:&&, :==, {2, 1, 0, [], []}] 61 62 assert Parser.lexer(">= 2.0.0 and < 2.1.0", []) == [ 63 :>=, 64 {2, 0, 0, [], []}, 65 :&&, 66 :<, 67 {2, 1, 0, [], []} 68 ] 69 70 assert Parser.lexer(">= 2.0.0 or < 2.1.0", []) == [ 71 :>=, 72 {2, 0, 0, [], []}, 73 :||, 74 :<, 75 {2, 1, 0, [], []} 76 ] 77 end 78 79 test "parse/1" do 80 assert {:ok, %Version{major: 1, minor: 2, patch: 3}} = Version.parse("1.2.3") 81 assert {:ok, %Version{major: 1, minor: 4, patch: 5}} = Version.parse("1.4.5+ignore") 82 assert {:ok, %Version{major: 0, minor: 0, patch: 1}} = Version.parse("0.0.1+sha.0702245") 83 84 assert {:ok, %Version{major: 1, minor: 4, patch: 5, pre: ["6-g3318bd5"]}} = 85 Version.parse("1.4.5-6-g3318bd5") 86 87 assert {:ok, %Version{major: 1, minor: 4, patch: 5, pre: [6, 7, "eight"]}} = 88 Version.parse("1.4.5-6.7.eight") 89 90 assert {:ok, %Version{major: 1, minor: 4, patch: 5, pre: ["6-g3318bd5"]}} = 91 Version.parse("1.4.5-6-g3318bd5+ignore") 92 93 assert Version.parse("foobar") == :error 94 assert Version.parse("2") == :error 95 assert Version.parse("2.") == :error 96 assert Version.parse("2.3") == :error 97 assert Version.parse("2.3.") == :error 98 assert Version.parse("2.3.0-") == :error 99 assert Version.parse("2.3.0+") == :error 100 assert Version.parse("2.3.0.") == :error 101 assert Version.parse("2.3.0.4") == :error 102 assert Version.parse("2.3.-rc.1") == :error 103 assert Version.parse("2.3.+rc.1") == :error 104 assert Version.parse("2.3.0-01") == :error 105 assert Version.parse("2.3.00-1") == :error 106 assert Version.parse("2.3.00") == :error 107 assert Version.parse("2.03.0") == :error 108 assert Version.parse("02.3.0") == :error 109 assert Version.parse("0. 0.0") == :error 110 assert Version.parse("0.1.0-&&pre") == :error 111 end 112 113 test "Kernel.to_string/1" do 114 assert Version.parse!("1.0.0") |> to_string == "1.0.0" 115 assert Version.parse!("1.0.0-dev") |> to_string == "1.0.0-dev" 116 assert Version.parse!("1.0.0+lol") |> to_string == "1.0.0+lol" 117 assert Version.parse!("1.0.0-dev+lol") |> to_string == "1.0.0-dev+lol" 118 assert Version.parse!("1.0.0-0") |> to_string == "1.0.0-0" 119 assert Version.parse!("1.0.0-rc.0") |> to_string == "1.0.0-rc.0" 120 assert %Version{major: 1, minor: 0, patch: 0} |> to_string() == "1.0.0" 121 end 122 123 test "match?/2 with invalid versions" do 124 assert_raise Version.InvalidVersionError, fn -> 125 Version.match?("foo", "2.3.0") 126 end 127 128 assert_raise Version.InvalidVersionError, fn -> 129 Version.match?("2.3", "2.3.0") 130 end 131 132 assert_raise Version.InvalidRequirementError, fn -> 133 Version.match?("2.3.0", "foo") 134 end 135 136 assert_raise Version.InvalidRequirementError, fn -> 137 Version.match?("2.3.0", "2.3") 138 end 139 end 140 141 test "==" do 142 assert Version.match?("2.3.0", "2.3.0") 143 refute Version.match?("2.4.0", "2.3.0") 144 145 assert Version.match?("2.3.0", "== 2.3.0") 146 refute Version.match?("2.4.0", "== 2.3.0") 147 148 assert Version.match?("1.0.0", "1.0.0") 149 assert Version.match?("1.0.0", "1.0.0") 150 151 assert Version.match?("1.2.3-alpha", "1.2.3-alpha") 152 153 assert Version.match?("0.9.3", "== 0.9.3+dev") 154 155 {:ok, vsn} = Version.parse("2.3.0") 156 assert Version.match?(vsn, "2.3.0") 157 end 158 159 test "!=" do 160 assert Version.match?("2.4.0", "!2.3.0") 161 refute Version.match?("2.3.0", "!2.3.0") 162 163 assert Version.match?("2.4.0", "!= 2.3.0") 164 refute Version.match?("2.3.0", "!= 2.3.0") 165 end 166 167 test ">" do 168 assert Version.match?("2.4.0", "> 2.3.0") 169 refute Version.match?("2.2.0", "> 2.3.0") 170 refute Version.match?("2.3.0", "> 2.3.0") 171 172 assert Version.match?("1.2.3", "> 1.2.3-alpha") 173 assert Version.match?("1.2.3-alpha.1", "> 1.2.3-alpha") 174 assert Version.match?("1.2.3-alpha.beta.sigma", "> 1.2.3-alpha.beta") 175 refute Version.match?("1.2.3-alpha.10", "< 1.2.3-alpha.1") 176 refute Version.match?("0.10.2-dev", "> 0.10.2") 177 178 refute Version.match?("1.5.0-rc.0", "> 1.5.0-rc0") 179 assert Version.match?("1.5.0-rc0", "> 1.5.0-rc.0") 180 end 181 182 test ">=" do 183 assert Version.match?("2.4.0", ">= 2.3.0") 184 refute Version.match?("2.2.0", ">= 2.3.0") 185 assert Version.match?("2.3.0", ">= 2.3.0") 186 187 assert Version.match?("2.0.0", ">= 1.0.0") 188 assert Version.match?("1.0.0", ">= 1.0.0") 189 190 refute Version.match?("1.5.0-rc.0", ">= 1.5.0-rc0") 191 assert Version.match?("1.5.0-rc0", ">= 1.5.0-rc.0") 192 end 193 194 test "<" do 195 assert Version.match?("2.2.0", "< 2.3.0") 196 refute Version.match?("2.4.0", "< 2.3.0") 197 refute Version.match?("2.3.0", "< 2.3.0") 198 199 assert Version.match?("0.10.2-dev", "< 0.10.2") 200 201 refute Version.match?("1.0.0", "< 1.0.0-dev") 202 refute Version.match?("1.2.3-dev", "< 0.1.2") 203 end 204 205 test "<=" do 206 assert Version.match?("2.2.0", "<= 2.3.0") 207 refute Version.match?("2.4.0", "<= 2.3.0") 208 assert Version.match?("2.3.0", "<= 2.3.0") 209 end 210 211 describe "~>" do 212 test "regular cases" do 213 assert Version.match?("3.0.0", "~> 3.0") 214 assert Version.match?("3.2.0", "~> 3.0") 215 refute Version.match?("4.0.0", "~> 3.0") 216 refute Version.match?("4.4.0", "~> 3.0") 217 218 assert Version.match?("3.0.2", "~> 3.0.0") 219 assert Version.match?("3.0.0", "~> 3.0.0") 220 refute Version.match?("3.1.0", "~> 3.0.0") 221 refute Version.match?("3.4.0", "~> 3.0.0") 222 223 assert Version.match?("3.6.0", "~> 3.5") 224 assert Version.match?("3.5.0", "~> 3.5") 225 refute Version.match?("4.0.0", "~> 3.5") 226 refute Version.match?("5.0.0", "~> 3.5") 227 228 assert Version.match?("3.5.2", "~> 3.5.0") 229 assert Version.match?("3.5.4", "~> 3.5.0") 230 refute Version.match?("3.6.0", "~> 3.5.0") 231 refute Version.match?("3.6.3", "~> 3.5.0") 232 233 assert Version.match?("0.9.3", "~> 0.9.3-dev") 234 refute Version.match?("0.10.0", "~> 0.9.3-dev") 235 236 refute Version.match?("0.3.0-dev", "~> 0.2.0") 237 238 assert Version.match?("1.11.0-dev", "~> 1.11-dev") 239 assert Version.match?("1.11.0", "~> 1.11-dev") 240 assert Version.match?("1.12.0", "~> 1.11-dev") 241 refute Version.match?("1.10.0", "~> 1.11-dev") 242 refute Version.match?("2.0.0", "~> 1.11-dev") 243 244 refute Version.match?("1.5.0-rc.0", "~> 1.5.0-rc0") 245 assert Version.match?("1.5.0-rc0", "~> 1.5.0-rc.0") 246 247 assert_raise Version.InvalidRequirementError, fn -> 248 Version.match?("3.0.0", "~> 3") 249 end 250 end 251 252 test "~> will never include pre-release versions of its upper bound" do 253 refute Version.match?("2.2.0-dev", "~> 2.1.0") 254 refute Version.match?("2.2.0-dev", "~> 2.1.0", allow_pre: false) 255 refute Version.match?("2.2.0-dev", "~> 2.1.0-dev") 256 refute Version.match?("2.2.0-dev", "~> 2.1.0-dev", allow_pre: false) 257 end 258 end 259 260 test "allow_pre" do 261 assert Version.match?("1.1.0", "~> 1.0", allow_pre: true) 262 assert Version.match?("1.1.0", "~> 1.0", allow_pre: false) 263 assert Version.match?("1.1.0-beta", "~> 1.0", allow_pre: true) 264 refute Version.match?("1.1.0-beta", "~> 1.0", allow_pre: false) 265 assert Version.match?("1.0.1-beta", "~> 1.0.0-beta", allow_pre: false) 266 267 assert Version.match?("1.1.0", ">= 1.0.0", allow_pre: true) 268 assert Version.match?("1.1.0", ">= 1.0.0", allow_pre: false) 269 assert Version.match?("1.1.0-beta", ">= 1.0.0", allow_pre: true) 270 refute Version.match?("1.1.0-beta", ">= 1.0.0", allow_pre: false) 271 assert Version.match?("1.1.0-beta", ">= 1.0.0-beta", allow_pre: false) 272 end 273 274 test "and" do 275 assert Version.match?("0.9.3", "> 0.9.0 and < 0.10.0") 276 refute Version.match?("0.10.2", "> 0.9.0 and < 0.10.0") 277 end 278 279 test "or" do 280 assert Version.match?("0.9.1", "0.9.1 or 0.9.3 or 0.9.5") 281 assert Version.match?("0.9.3", "0.9.1 or 0.9.3 or 0.9.5") 282 assert Version.match?("0.9.5", "0.9.1 or 0.9.3 or 0.9.5") 283 284 refute Version.match?("0.9.6", "0.9.1 or 0.9.3 or 0.9.5") 285 end 286 287 test "compile requirement" do 288 {:ok, req} = Version.parse_requirement("1.2.3") 289 req = Version.compile_requirement(req) 290 291 assert Version.match?("1.2.3", req) 292 refute Version.match?("1.2.4", req) 293 end 294end 295