/
nv-lang
/
nova
Обзор
Документация
Войти
/
nv-lang
/
nova
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
std/src/data/semver_test.nv
244 строки
7 KB
Evgeniy Golovin
195: std/ -> std/src/ (git mv, module-path без изменений)
13 июл 2026, 01:13
13 июл 2026, 01:13
be4fcab
Код
Авторство
О чём код?
// SPDX-License-Identifier: MIT OR Apache-2.0 // std/data/semver_test.nv — публичный контракт Version (semver.org 2.0.0): // parse/to_str/compare/equal. module data.semver_test import std.data.semver.{Version, ParseVersionError} test "parse: простая версия" { ro v = "1.2.3".to_version()!! assert(v.major == 1) assert(v.minor == 2) assert(v.patch == 3) assert(v.pre.len() == 0) assert(v.build.len() == 0) } test "parse: pre-release" { ro v = "1.0.0-alpha".to_version()!! assert(v.major == 1) assert(v.pre.len() == 1) assert(v.pre[0] == "alpha") assert(v.is_prerelease()) } test "parse: pre-release с компонентами" { ro v = "1.0.0-alpha.1".to_version()!! assert(v.pre.len() == 2) assert(v.pre[0] == "alpha") assert(v.pre[1] == "1") } test "parse: build metadata" { ro v = "1.0.0+20130313144700".to_version()!! assert(v.build.len() == 1) assert(v.build[0] == "20130313144700") assert(v.has_build()) } test "parse: pre + build" { ro v = "1.0.0-beta+exp.sha.5114f85".to_version()!! assert(v.pre[0] == "beta") assert(v.build.len() == 3) assert(v.build[0] == "exp") assert(v.build[1] == "sha") assert(v.build[2] == "5114f85") } test "parse: большие числа" { ro v = "100.200.300".to_version()!! assert(v.major == 100) assert(v.minor == 200) assert(v.patch == 300) } test "parse: pre с цифрами и точками" { ro v = "1.0.0-x.7.z.92".to_version()!! assert(v.pre.len() == 4) assert(v.pre[3] == "92") } test "parse: ошибка — пустой ввод" { assert(match "".to_version() { Err(EmptyInput) => true _ => false }) } test "parse: ошибка — нет minor" { assert(match "1".to_version() { Err(MissingMinor) => true _ => false }) } test "parse: ошибка — нет patch" { assert(match "1.2".to_version() { Err(MissingPatch) => true _ => false }) } test "parse: ошибка — leading zero в major" { assert(match "01.0.0".to_version() { Err(LeadingZero { .. }) => true _ => false }) } test "parse: ошибка — leading zero в pre numeric" { assert(match "1.0.0-01".to_version() { Err(LeadingZero { .. }) => true _ => false }) } test "parse: ошибка — пустой identifier в pre" { assert(match "1.0.0-".to_version() { Err(EmptyIdentifier { .. }) => true _ => false }) } test "parse: ошибка — мусорный символ в pre-identifier (пиннинг is_ascii_ident_char)" { // Пиннинг фикса D417-класса (2026-07-10): is_ascii_ident_char был // always-true (ведущий || = discarded closure) — любой символ проходил // валидацию иден-та. Канон: только [0-9A-Za-z-]. assert("1.0.0-al pha".to_version().is_err()) assert("1.0.0-alpha!".to_version().is_err()) } test "parse: ошибка — нечисловой major" { assert(match "a.b.c".to_version() { Err(InvalidComponent { .. }) => true _ => false }) } test "to_str: round-trip простая версия" { ro v = Version.new(1, 2, 3) assert(v.to_str() == "1.2.3") ro parsed = v.to_str().to_version()!! assert(parsed == v) } test "to_str: round-trip с pre" { ro v = Version.full(1, 0, 0, ["alpha", "1"], []) assert(v.to_str() == "1.0.0-alpha.1") ro parsed = v.to_str().to_version()!! assert(parsed == v) } test "to_str: round-trip с build" { ro v = Version.full(1, 0, 0, [], ["build", "42"]) assert(v.to_str() == "1.0.0+build.42") ro parsed = v.to_str().to_version()!! assert(parsed == v) } test "to_str: round-trip с pre и build" { ro v = Version.full(1, 0, 0, ["beta"], ["exp", "sha", "5114f85"]) assert(v.to_str() == "1.0.0-beta+exp.sha.5114f85") ro parsed = v.to_str().to_version()!! assert(parsed == v) } test "compare: numeric ordering" { ro a = "1.0.0".to_version()!! ro b = "2.0.0".to_version()!! ro c = "1.1.0".to_version()!! ro d = "1.0.1".to_version()!! assert(a < b) assert(a < c) assert(a < d) assert(d < c) assert(c < b) } test "compare: pre-release < release (semver § 11.3)" { ro pre = "1.0.0-alpha".to_version()!! ro rel = "1.0.0".to_version()!! assert(pre < rel) assert(rel > pre) } test "compare: цепочка pre-release per semver.org example" { // Из § 11: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta // < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0 ro chain = [ "1.0.0-alpha".to_version()!!, "1.0.0-alpha.1".to_version()!!, "1.0.0-alpha.beta".to_version()!!, "1.0.0-beta".to_version()!!, "1.0.0-beta.2".to_version()!!, "1.0.0-beta.11".to_version()!!, "1.0.0-rc.1".to_version()!!, "1.0.0".to_version()!!, ] for i in 0..chain.len() - 1 { assert(chain[i] < chain[i + 1]) } } test "compare: numeric vs alphanumeric pre identifier" { // Numeric < alphanumeric (semver § 11.4.3) ro num = "1.0.0-1".to_version()!! ro alpha = "1.0.0-a".to_version()!! assert(num < alpha) } test "compare: длина pre identifiers" { // Из § 11.4.4: shorter < longer когда префикс совпадает ro short_v = "1.0.0-alpha".to_version()!! ro long_v = "1.0.0-alpha.1".to_version()!! assert(short_v < long_v) } test "compare: build metadata игнорируется (semver § 10)" { ro a = "1.0.0+build.1".to_version()!! ro b = "1.0.0+build.2".to_version()!! // Имеют одинаковый precedence, но структурно разные. assert(a.eq_precedence(b)) assert(a != b) // структурное @equal различает build assert(!(a < b)) assert(!(b < a)) } test "is_stable: только не-pre с major >= 1" { ro stable_a = "1.0.0".to_version()!! ro stable_b = "2.5.10".to_version()!! ro zero_major = "0.9.0".to_version()!! ro prerelease = "1.0.0-alpha".to_version()!! assert(stable_a.is_stable()) assert(stable_b.is_stable()) assert(!zero_major.is_stable()) // 0.x.y — нестабильное assert(!prerelease.is_stable()) // pre-release } test "Version.from + .to_str() работают парно" { ro v Version = "3.14.159".to_version()!! assert(v.major == 3) // Обратная форма — явный to_str() ro s str = v.to_str() assert(s == "3.14.159") ro v2 = "1.2.3".to_version()!! ro s2 str = v2.to_str() assert(s2 == "1.2.3") } test "operator overloading: <, ==, !=" { ro v1 = "1.0.0".to_version()!! ro v2 = "2.0.0".to_version()!! ro v1_copy = "1.0.0".to_version()!! assert(v1 < v2) assert(v2 > v1) assert(v1 == v1_copy) assert(v1 != v2) assert(v1 <= v1_copy) assert(v1 >= v1_copy) }