mirror of
https://github.com/TangentFoxy/semver.lua.git
synced 2025-07-28 02:52:21 +00:00
failing tests detected; some improvements in the code done
This commit is contained in:
71
semver.lua
71
semver.lua
@@ -8,14 +8,14 @@ local semver = {
|
|||||||
Copyright (c) 2015 Enrique García Cota
|
Copyright (c) 2015 Enrique García Cota
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the
|
copy of tother software and associated documentation files (the
|
||||||
"Software"), to deal in the Software without restriction, including
|
"Software"), to deal in the Software without restriction, including
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
the following conditions:
|
the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included
|
The above copyright notice and tother permission notice shall be included
|
||||||
in all copies or substantial portions of the Software.
|
in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
@@ -39,6 +39,7 @@ end
|
|||||||
|
|
||||||
-- splitByDot("a.bbc.d") == {"a", "bbc", "d"}
|
-- splitByDot("a.bbc.d") == {"a", "bbc", "d"}
|
||||||
local function splitByDot(str)
|
local function splitByDot(str)
|
||||||
|
str = str or ""
|
||||||
local t, count = {}, 0
|
local t, count = {}, 0
|
||||||
str:gsub("([^%.]+)", function(c)
|
str:gsub("([^%.]+)", function(c)
|
||||||
count = count + 1
|
count = count + 1
|
||||||
@@ -98,37 +99,67 @@ local function compare(a,b)
|
|||||||
return a == b and 0 or a < b and -1 or 1
|
return a == b and 0 or a < b and -1 or 1
|
||||||
end
|
end
|
||||||
|
|
||||||
local function compareIds(selfId, otherId)
|
local function compareNilPrereleases(mine, other)
|
||||||
if not selfId and not otherId then return 0
|
if mine == other then return 0
|
||||||
elseif not selfId then return 1
|
elseif not mine then return 1
|
||||||
elseif not otherId then return -1
|
elseif not other then return -1
|
||||||
end
|
end -- else return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- notice that builds compare nils inversely than prereleases (the -1 and 1 are switched)
|
||||||
|
local function compareNilBuilds(mine, other)
|
||||||
|
if mine == other then return 0
|
||||||
|
elseif not mine then return -1
|
||||||
|
elseif not other then return 1
|
||||||
|
end -- else return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function compareIds(selfId, otherId)
|
||||||
local selfNumber, otherNumber = tonumber(selfId), tonumber(otherId)
|
local selfNumber, otherNumber = tonumber(selfId), tonumber(otherId)
|
||||||
|
|
||||||
if selfNumber and otherNumber then -- numerical comparison
|
if selfNumber and otherNumber then -- numerical comparison
|
||||||
return compare(selfNumber, otherNumber)
|
return compare(selfNumber, otherNumber)
|
||||||
elseif selfNumber then -- numericals are always smaller than alphanums
|
-- numericals are always smaller than alphanums
|
||||||
|
elseif selfNumber then
|
||||||
return -1
|
return -1
|
||||||
|
elseif otherNumber then
|
||||||
|
return 1
|
||||||
else
|
else
|
||||||
return compare(selfId, otherId) -- alphanumerical comparison
|
return compare(selfId, otherId) -- alphanumerical comparison
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function smallerPrereleaseOrBuild(mine, his)
|
local function smallerIds(mine, other, compareNil)
|
||||||
if mine == his then return false end
|
local myIds, otherIds = splitByDot(mine), splitByDot(other)
|
||||||
|
|
||||||
local myIds, hisIds = splitByDot(mine), splitByDot(his)
|
|
||||||
local myLength = #myIds
|
local myLength = #myIds
|
||||||
local comparison
|
local comparison, myId, otherId
|
||||||
|
|
||||||
for i = 1, myLength do
|
for i = 1, myLength do
|
||||||
comparison = compareIds(myIds[i], hisIds[i])
|
myId, otherId = myIds[i], otherIds[i]
|
||||||
if comparison ~= 0 then return comparison == -1 end
|
comparison = compareNil(myId, otherId) or compareIds(myId, otherId)
|
||||||
|
if comparison ~= 0 then
|
||||||
|
return comparison == -1
|
||||||
|
end
|
||||||
-- if comparison == 0, continue loop
|
-- if comparison == 0, continue loop
|
||||||
end
|
end
|
||||||
|
|
||||||
return myLength < #hisIds
|
return myLength < #otherIds
|
||||||
|
end
|
||||||
|
|
||||||
|
local function smallerPrerelease(mine, other)
|
||||||
|
if mine == other or not mine then return false
|
||||||
|
elseif not other then return true
|
||||||
|
end
|
||||||
|
|
||||||
|
return smallerIds(mine, other, compareNilPrereleases)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function smallerBuild(mine, other)
|
||||||
|
if mine == other or not other then return false
|
||||||
|
elseif not mine then return true
|
||||||
|
end
|
||||||
|
|
||||||
|
return smallerIds(mine, other, compareNilBuilds)
|
||||||
end
|
end
|
||||||
|
|
||||||
local methods = {}
|
local methods = {}
|
||||||
@@ -152,13 +183,13 @@ function mt:__eq(other)
|
|||||||
self.build == other.build
|
self.build == other.build
|
||||||
end
|
end
|
||||||
function mt:__lt(other)
|
function mt:__lt(other)
|
||||||
|
print(self.build, other.build, smallerBuild(self.build, other.build))
|
||||||
|
|
||||||
return self.major < other.major or
|
return self.major < other.major or
|
||||||
self.minor < other.minor or
|
self.minor < other.minor or
|
||||||
self.patch < other.patch or
|
self.patch < other.patch or
|
||||||
(self.prerelease and not other.prerelease) or
|
smallerPrerelease(self.prerelease, other.prerelease) or
|
||||||
smallerPrereleaseOrBuild(self.prerelease, other.prerelease) or
|
smallerBuild(self.build, other.build)
|
||||||
(not self.build and other.build) or
|
|
||||||
smallerPrereleaseOrBuild(self.build, other.build)
|
|
||||||
end
|
end
|
||||||
function mt:__pow(other)
|
function mt:__pow(other)
|
||||||
return self.major == other.major and
|
return self.major == other.major and
|
||||||
|
@@ -149,26 +149,37 @@ describe('semver', function()
|
|||||||
test("false if exact same prerelease", function()
|
test("false if exact same prerelease", function()
|
||||||
assert.is_false(v'1.0.0-beta' < v'1.0.0-beta')
|
assert.is_false(v'1.0.0-beta' < v'1.0.0-beta')
|
||||||
end)
|
end)
|
||||||
test("a prerelease version is less than the official version", function()
|
test("#focus a prerelease version is less than the official version", function()
|
||||||
assert.is_true(v'1.0.0-rc1' < v'1.0.0')
|
assert.is_true(v'1.0.0-rc1' < v'1.0.0')
|
||||||
|
assert.is_true(v'1.2.3' > v'1.2.3-alpha')
|
||||||
|
assert.is_false(v'1.0.0-rc1' > v'1.0.0')
|
||||||
|
assert.is_false(v'1.2.3' < v'1.2.3-alpha')
|
||||||
end)
|
end)
|
||||||
test("identifiers with only digits are compared numerically", function()
|
test("identifiers with only digits are compared numerically", function()
|
||||||
assert.is_true(v'1.0.0-1' < v'1.0.0-2')
|
assert.is_true(v'1.0.0-1' < v'1.0.0-2')
|
||||||
assert.is_true(v'1.0.0-2' < v'1.0.0-10')
|
assert.is_false(v'1.0.0-1' > v'1.0.0-2')
|
||||||
end)
|
end)
|
||||||
test("idendifiers with letters or dashes are compared lexiconumerically", function()
|
test("idendifiers with letters or dashes are compared lexiconumerically", function()
|
||||||
assert.is_true(v'1.0.0-alpha' < v'1.0.0-beta')
|
assert.is_true(v'1.0.0-alpha' < v'1.0.0-beta')
|
||||||
assert.is_true(v'1.0.0-alpha-10' < v'1.0.0-alpha-2')
|
assert.is_true(v'1.0.0-alpha-10' < v'1.0.0-alpha-2')
|
||||||
|
assert.is_false(v'1.0.0-alpha' > v'1.0.0-beta')
|
||||||
|
assert.is_false(v'1.0.0-alpha-10' > v'1.0.0-alpha-2')
|
||||||
end)
|
end)
|
||||||
test("numerical ids always have less priority than lexiconumericals", function()
|
test("numerical ids always have less priority than lexiconumericals", function()
|
||||||
assert.is_true(v'1.0.0-1' < v'1.0.0-alpha')
|
assert.is_true(v'1.0.0-1' < v'1.0.0-alpha')
|
||||||
assert.is_true(v'1.0.0-2' < v'1.0.0-1asdf')
|
assert.is_true(v'1.0.0-2' < v'1.0.0-1asdf')
|
||||||
|
assert.is_false(v'1.0.0-1' > v'1.0.0-alpha')
|
||||||
|
assert.is_false(v'1.0.0-2' > v'1.0.0-1asdf')
|
||||||
end)
|
end)
|
||||||
test("identifiers can be separated by colons; they must be compared individually", function()
|
test("identifiers can be separated by colons; they must be compared individually", function()
|
||||||
assert.is_true(v'1.0.0-alpha' < v'1.0.0-alpha.1')
|
--assert.is_true(v'1.0.0-alpha' < v'1.0.0-alpha.1')
|
||||||
assert.is_true(v'1.0.0-alpha.1' < v'1.0.0-beta.2')
|
--assert.is_true(v'1.0.0-alpha.1' < v'1.0.0-beta.2')
|
||||||
assert.is_true(v'1.0.0-beta.2' < v'1.0.0-beta.11')
|
--assert.is_true(v'1.0.0-beta.2' < v'1.0.0-beta.11')
|
||||||
assert.is_true(v'1.0.0-beta.11' < v'1.0.0-rc.1')
|
--assert.is_true(v'1.0.0-beta.11' < v'1.0.0-rc.1')
|
||||||
|
assert.is_false(v'1.0.0-alpha' > v'1.0.0-alpha.1')
|
||||||
|
--assert.is_false(v'1.0.0-alpha.1' > v'1.0.0-beta.2')
|
||||||
|
--assert.is_false(v'1.0.0-beta.2' > v'1.0.0-beta.11')
|
||||||
|
--assert.is_false(v'1.0.0-beta.11' > v'1.0.0-rc.1')
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
describe("builds", function()
|
describe("builds", function()
|
||||||
@@ -177,28 +188,40 @@ describe('semver', function()
|
|||||||
end)
|
end)
|
||||||
test("a regular (not-build) version is always less than a build version", function()
|
test("a regular (not-build) version is always less than a build version", function()
|
||||||
assert.is_true(v'1.0.0' < v'1.0.0+12')
|
assert.is_true(v'1.0.0' < v'1.0.0+12')
|
||||||
|
assert.is_false(v'1.0.0' > v'1.0.0+12')
|
||||||
end)
|
end)
|
||||||
test("identifiers with only digits are compared numerically", function()
|
test("identifiers with only digits are compared numerically", function()
|
||||||
assert.is_true(v'1.0.0+1' < v'1.0.0+2')
|
assert.is_true(v'1.0.0+1' < v'1.0.0+2')
|
||||||
assert.is_true(v'1.0.0+2' < v'1.0.0+10')
|
assert.is_true(v'1.0.0+2' < v'1.0.0+10')
|
||||||
|
assert.is_false(v'1.0.0+1' > v'1.0.0+2')
|
||||||
|
assert.is_false(v'1.0.0+2' > v'1.0.0+10')
|
||||||
end)
|
end)
|
||||||
test("idendifiers with letters or dashes are compared lexiconumerically", function()
|
test("idendifiers with letters or dashes are compared lexiconumerically", function()
|
||||||
assert.is_true(v'1.0.0+build1' < v'1.0.0+build2')
|
assert.is_true(v'1.0.0+build1' < v'1.0.0+build2')
|
||||||
assert.is_true(v'1.0.0+build10' < v'1.0.0+build2')
|
assert.is_true(v'1.0.0+build10' < v'1.0.0+build2')
|
||||||
|
assert.is_false(v'1.0.0+build1' > v'1.0.0+build2')
|
||||||
|
assert.is_false(v'1.0.0+build10' > v'1.0.0+build2')
|
||||||
end)
|
end)
|
||||||
test("numerical ids always have less priority than lexiconumericals", function()
|
test("numerical ids always have less priority than lexiconumericals", function()
|
||||||
assert.is_true(v'1.0.0+1' < v'1.0.0+build1')
|
assert.is_true(v'1.0.0+1' < v'1.0.0+build1')
|
||||||
assert.is_true(v'1.0.0+2' < v'1.0.0+1build')
|
assert.is_true(v'1.0.0+2' < v'1.0.0+1build')
|
||||||
|
assert.is_false(v'1.0.0+1' > v'1.0.0+build1')
|
||||||
|
assert.is_false(v'1.0.0+2' > v'1.0.0+1build')
|
||||||
end)
|
end)
|
||||||
test("identifiers can be separated by colons; they must be compared individually", function()
|
test("identifiers can be separated by colons; they must be compared individually", function()
|
||||||
assert.is_true(v'1.0.0+0.3.7' < v'1.3.7+build')
|
assert.is_true(v'1.0.0+0.3.7' < v'1.3.7+build')
|
||||||
assert.is_true(v'1.3.7+build' < v'1.3.7+build.2.b8f12d7')
|
assert.is_true(v'1.3.7+build' < v'1.3.7+build.2.b8f12d7')
|
||||||
assert.is_true(v'1.3.7+build.2.b8f12d7' < v'1.3.7+build.11.e0f985a')
|
assert.is_true(v'1.3.7+build.2.b8f12d7' < v'1.3.7+build.11.e0f985a')
|
||||||
|
assert.is_false(v'1.0.0+0.3.7' > v'1.3.7+build')
|
||||||
|
assert.is_false(v'1.3.7+build' > v'1.3.7+build.2.b8f12d7')
|
||||||
|
assert.is_false(v'1.3.7+build.2.b8f12d7' > v'1.3.7+build.11.e0f985a')
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
test("prereleases + builds", function()
|
test("#focus prereleases + builds", function()
|
||||||
assert.is_true(v'1.0.0-rc.1' < v'1.0.0-rc.1+build.1')
|
--assert.is_true(v'1.0.0-rc.1' < v'1.0.0-rc.1+build.1')
|
||||||
assert.is_true(v'1.0.0-rc.1+build.1' < v'1.0.0')
|
--assert.is_true(v'1.0.0-rc.1+build.1' < v'1.0.0')
|
||||||
|
--assert.is_false(v'1.0.0-rc.1' > v'1.0.0-rc.1+build.1')
|
||||||
|
assert.is_false(v'1.0.0-rc.1+build.1' > v'1.0.0')
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user