| 1 | import semver |
| 2 | |
| 3 | struct TestVersion { |
| 4 | raw string |
| 5 | major int |
| 6 | minor int |
| 7 | patch int |
| 8 | prerelease string |
| 9 | metadata string |
| 10 | } |
| 11 | |
| 12 | struct TestRange { |
| 13 | raw_version string |
| 14 | range_satisfied string |
| 15 | range_unsatisfied string |
| 16 | } |
| 17 | |
| 18 | struct TestCoerce { |
| 19 | invalid string |
| 20 | valid string |
| 21 | } |
| 22 | |
| 23 | const versions_to_test = [ |
| 24 | TestVersion{'1.2.4', 1, 2, 4, '', ''}, |
| 25 | TestVersion{'1.2.4-prerelease-1', 1, 2, 4, 'prerelease-1', ''}, |
| 26 | TestVersion{'1.2.4+20191231', 1, 2, 4, '', '20191231'}, |
| 27 | TestVersion{'1.2.4-prerelease-1+20191231', 1, 2, 4, 'prerelease-1', '20191231'}, |
| 28 | TestVersion{'1.2.4+20191231-prerelease-1', 1, 2, 4, '', '20191231-prerelease-1'}, |
| 29 | ] |
| 30 | const ranges_to_test = [ |
| 31 | TestRange{'1.1.0', '1.1.0', '1.1.1'}, |
| 32 | TestRange{'1.1.0', '=1.1.0', '=1.1.1'}, |
| 33 | TestRange{'1.1.0', '>=1.0.0', '<1.1.0'}, |
| 34 | TestRange{'1.1.0', '>=1.0.0 <=1.1.0', '>=1.0.0 <1.1.0'}, |
| 35 | TestRange{'2.3.1', '>=1.0.0 <=1.1.0 || >2.0.0 <2.3.4', '>=1.0.0 <1.1.0'}, |
| 36 | TestRange{'2.3.1', '>=1.0.0 <=1.1.0 || >2.0.0 <2.3.4', '>=1.0.0 <1.1.0 || >4.0.0 <5.0.0'}, |
| 37 | TestRange{'2.3.1', '~2.3.0', '~2.4.0'}, |
| 38 | TestRange{'3.0.0', '~3.0.0', '~4.0.0'}, |
| 39 | TestRange{'2.3.1', '^2.0.0', '^2.4.0'}, |
| 40 | TestRange{'0.3.1', '^0.3.0', '^2.4.0'}, |
| 41 | TestRange{'0.0.4', '^0.0.1', '^0.1.0'}, |
| 42 | TestRange{'2.3.4', '^0.0.1 || ^2.3.0', '^3.1.0 || ^4.2.0'}, |
| 43 | TestRange{'2.3.4', '>2 || <3', '>3 || >4'}, |
| 44 | TestRange{'2.3.4', '2.3.4 - 2.3.5', '2.5.1 - 2.8.3'}, |
| 45 | TestRange{'2.3.4', '2.2 - 2.3', '2.4 - 2.8'}, |
| 46 | TestRange{'2.3.4', '2.3.x', '2.4.x'}, |
| 47 | TestRange{'2.3.4', '2.x', '3.x'}, |
| 48 | TestRange{'2.3.4', '*', '3.x'}, |
| 49 | ] |
| 50 | const coerce_to_test = [ |
| 51 | TestCoerce{'1.2.0.4', '1.2.0'}, |
| 52 | TestCoerce{'1.2.0', '1.2.0'}, |
| 53 | TestCoerce{'1.2', '1.2.0'}, |
| 54 | TestCoerce{'1', '1.0.0'}, |
| 55 | TestCoerce{'1-alpha', '1.0.0-alpha'}, |
| 56 | TestCoerce{'1+meta', '1.0.0+meta'}, |
| 57 | TestCoerce{'1-alpha+meta', '1.0.0-alpha+meta'}, |
| 58 | ] |
| 59 | const invalid_versions_to_test = [ |
| 60 | 'a.b.c', |
| 61 | '1.2', |
| 62 | '1.2.x', |
| 63 | '1.2.3.4', |
| 64 | '1.2.3-alpha@', |
| 65 | '1.2.3+meta%', |
| 66 | ] |
| 67 | const invalid_ranges_to_test = [ |
| 68 | '^a', |
| 69 | '~b', |
| 70 | 'a - c', |
| 71 | '>a', |
| 72 | 'a', |
| 73 | 'a.x', |
| 74 | ] |
| 75 | |
| 76 | fn test_from() { |
| 77 | for item in versions_to_test { |
| 78 | ver := semver.from(item.raw) or { |
| 79 | assert false |
| 80 | return |
| 81 | } |
| 82 | assert ver.major == item.major |
| 83 | assert ver.minor == item.minor |
| 84 | assert ver.patch == item.patch |
| 85 | assert ver.metadata == item.metadata |
| 86 | assert ver.prerelease == item.prerelease |
| 87 | assert ver.str() == item.raw |
| 88 | } |
| 89 | for ver in invalid_versions_to_test { |
| 90 | semver.from(ver) or { |
| 91 | assert true |
| 92 | continue |
| 93 | } |
| 94 | assert false |
| 95 | } |
| 96 | } |
| 97 | |
| 98 | fn test_increment() { |
| 99 | version1 := semver.build(1, 2, 3) |
| 100 | version1_inc := version1.increment(.major) |
| 101 | assert version1_inc.major == 2 |
| 102 | assert version1_inc.minor == 0 |
| 103 | assert version1_inc.patch == 0 |
| 104 | version2_inc := version1.increment(.minor) |
| 105 | assert version2_inc.major == 1 |
| 106 | assert version2_inc.minor == 3 |
| 107 | assert version2_inc.patch == 0 |
| 108 | version3_inc := version1.increment(.patch) |
| 109 | assert version3_inc.major == 1 |
| 110 | assert version3_inc.minor == 2 |
| 111 | assert version3_inc.patch == 4 |
| 112 | } |
| 113 | |
| 114 | fn test_compare() { |
| 115 | first := semver.build(1, 0, 0) |
| 116 | patch := semver.build(1, 0, 1) |
| 117 | minor := semver.build(1, 2, 3) |
| 118 | major := semver.build(2, 0, 0) |
| 119 | assert first <= first |
| 120 | assert first >= first |
| 121 | assert !(first < first) |
| 122 | assert !(first > first) |
| 123 | assert patch > first |
| 124 | assert first <= patch |
| 125 | assert !(first >= patch) |
| 126 | assert !(patch <= first) |
| 127 | assert patch > first |
| 128 | assert first < patch |
| 129 | assert !(first > patch) |
| 130 | assert !(patch < first) |
| 131 | assert minor > patch |
| 132 | assert patch < minor |
| 133 | assert !(patch > minor) |
| 134 | assert !(minor < patch) |
| 135 | assert major > minor |
| 136 | assert minor < major |
| 137 | assert !(minor > major) |
| 138 | assert !(major < minor) |
| 139 | } |
| 140 | |
| 141 | fn test_satisfies() { |
| 142 | for item in ranges_to_test { |
| 143 | ver := semver.from(item.raw_version) or { |
| 144 | assert false |
| 145 | return |
| 146 | } |
| 147 | assert ver.satisfies(item.range_satisfied) |
| 148 | assert !ver.satisfies(item.range_unsatisfied) |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | fn test_satisfies_invalid() { |
| 153 | ver := semver.from('1.0.0') or { |
| 154 | assert false |
| 155 | return |
| 156 | } |
| 157 | for item in invalid_ranges_to_test { |
| 158 | assert ver.satisfies(item) == false |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | fn test_coerce() { |
| 163 | for item in coerce_to_test { |
| 164 | valid := semver.from(item.valid) or { |
| 165 | assert false |
| 166 | return |
| 167 | } |
| 168 | fixed := semver.coerce(item.invalid) or { |
| 169 | assert false |
| 170 | return |
| 171 | } |
| 172 | assert fixed == valid |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | fn test_coerce_invalid() { |
| 177 | semver.coerce('a') or { |
| 178 | assert true |
| 179 | return |
| 180 | } |
| 181 | assert false |
| 182 | } |
| 183 | |
| 184 | fn test_is_valid() { |
| 185 | for item in versions_to_test { |
| 186 | assert semver.is_valid(item.raw) |
| 187 | } |
| 188 | for item in invalid_versions_to_test { |
| 189 | assert semver.is_valid(item) == false |
| 190 | } |
| 191 | } |
| 192 | |