builds done. I have just realized that builds and prereleases can happen simoultaneously. :(

This commit is contained in:
Enrique García Cota
2012-01-15 03:17:09 +01:00
parent 0f826b8a39
commit b1d083e382
2 changed files with 55 additions and 11 deletions

View File

@@ -16,12 +16,13 @@ local function present(value)
return value and value ~= '' return value and value ~= ''
end end
local function parsePrerelease(extra) local function parseExtra(extra)
if not present(extra) then return end if not present(extra) then return end
local prerelease = extra:match("-([%w-][%.%w-]*)") local sign, data = extra:match("([-+])([%w-][%.%w-]*)")
assert(prerelease, ("The prerelease %q must start with a dash and be followed by dashes, alphanumerics or dots."):format(extra)) assert(sign and data, ("The string %q must start with - or + followed by dashes, alphanumerics or dots."):format(extra))
return prerelease if sign == "-" then return data, nil end
return nil,data
end end
-- return 0 if a == b, -1 if a < b, and 1 if a > b -- return 0 if a == b, -1 if a < b, and 1 if a > b
@@ -88,14 +89,17 @@ function mt:__eq(other)
return self.major == other.major and return self.major == other.major and
self.minor == other.minor and self.minor == other.minor and
self.patch == other.patch and self.patch == other.patch and
self.prerelease == other.prerelease self.prerelease == other.prerelease and
self.build == other.build
end end
function mt:__lt(other) function mt:__lt(other)
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 (self.prerelease and not other.prerelease) or
smallerExtra(self.prerelease, other.prerelease) smallerExtra(self.prerelease, other.prerelease) or
(not self.build and other.build) or
smallerExtra(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
@@ -103,7 +107,9 @@ function mt:__pow(other)
end end
function mt:__tostring() function mt:__tostring()
local buffer = { ("%d.%d.%d"):format(self.major, self.minor, self.patch) } local buffer = { ("%d.%d.%d"):format(self.major, self.minor, self.patch) }
if self.prerelease then table.insert(buffer, "-" .. self.prerelease) end if self.prerelease then buffer[2] = "-" .. self.prerelease
elseif self.build then buffer[2] = "+" .. self.build
end
return table.concat(buffer) return table.concat(buffer)
end end
@@ -126,9 +132,9 @@ version = function(major, minor, patch, extra)
checkPositiveInteger(minor, "minor") checkPositiveInteger(minor, "minor")
checkPositiveInteger(patch, "patch") checkPositiveInteger(patch, "patch")
local prerelease = parsePrerelease(extra) local prerelease, build = parseExtra(extra)
local result = {major=major, minor=minor, patch=patch, prerelease=prerelease} local result = {major=major, minor=minor, patch=patch, prerelease=prerelease, build=build}
return setmetatable(result, mt) return setmetatable(result, mt)
end end

View File

@@ -1,10 +1,11 @@
local v = require 'semver' local v = require 'semver'
local function checkVersion(ver, major, minor, patch, prerelease) local function checkVersion(ver, major, minor, patch, prerelease, build)
assert_equal(major, ver.major) assert_equal(major, ver.major)
assert_equal(minor, ver.minor) assert_equal(minor, ver.minor)
assert_equal(patch, ver.patch) assert_equal(patch, ver.patch)
assert_equal(prerelease, ver.prerelease) assert_equal(prerelease, ver.prerelease)
assert_equal(build, ver.build)
end end
context('semver', function() context('semver', function()
@@ -24,9 +25,12 @@ context('semver', function()
checkVersion(v(1), 1,0,0) checkVersion(v(1), 1,0,0)
end) end)
it('parses prereleases, if they exist', function() it('parses prereleases', function()
checkVersion(v(1,2,3,"-alpha"), 1,2,3,"alpha") checkVersion(v(1,2,3,"-alpha"), 1,2,3,"alpha")
end) end)
it('parses builds', function()
checkVersion(v(1,2,3,"+build.1"), 1,2,3,nil,"build.1")
end)
end) end)
describe("from strings", function() describe("from strings", function()
@@ -45,6 +49,9 @@ context('semver', function()
test("1.2.3-alpha", function() test("1.2.3-alpha", function()
checkVersion( v'1.2.3-alpha', 1,2,3,'alpha' ) checkVersion( v'1.2.3-alpha', 1,2,3,'alpha' )
end) end)
test("1.2.3+build.15", function()
checkVersion( v'1.2.3+build.15', 1,2,3,nil,'build.15' )
end)
end) end)
describe('errors', function() describe('errors', function()
@@ -84,6 +91,9 @@ context('semver', function()
it("works with a prerelease", function() it("works with a prerelease", function()
assert_equal("1.2.3-beta", tostring(v(1,2,3,'-beta'))) assert_equal("1.2.3-beta", tostring(v(1,2,3,'-beta')))
end) end)
it("works with a build", function()
assert_equal("1.2.3+foobar", tostring(v(1,2,3, '+foobar')))
end)
end) end)
describe("==", function() describe("==", function()
@@ -96,6 +106,9 @@ context('semver', function()
it("false if all is the same except the prerelease", function() it("false if all is the same except the prerelease", function()
assert_not_equal(v(1,2,3), v'1.2.3-alpha') assert_not_equal(v(1,2,3), v'1.2.3-alpha')
end) end)
it("false if all is the same except the build", function()
assert_not_equal(v(1,2,3), v'1.2.3+peter.1')
end)
end) end)
describe("<", function() describe("<", function()
@@ -143,6 +156,31 @@ context('semver', function()
assert_less_than(v'1.0.0-beta.11', v'1.0.0-rc.1') assert_less_than(v'1.0.0-beta.11', v'1.0.0-rc.1')
end) end)
end) end)
describe("builds", function()
test("false if exact same build", function()
assert_false(v'1.0.0+build1' < v'1.0.0+build1')
end)
test("a regular (not-build) version is always less than a build version", function()
assert_less_than(v'1.0.0', v'1.0.0+12')
end)
test("identifiers with only digits are compared numerically", function()
assert_less_than(v'1.0.0+1', v'1.0.0+2')
assert_less_than(v'1.0.0+2', v'1.0.0+10')
end)
test("idendifiers with letters or dashes are compared lexiconumerically", function()
assert_less_than(v'1.0.0+build1', v'1.0.0+build2')
assert_less_than(v'1.0.0+build10', v'1.0.0+build2')
end)
test("numerical ids always have less priority than lexiconumericals", function()
assert_less_than(v'1.0.0+1', v'1.0.0+build1')
assert_less_than(v'1.0.0+2', v'1.0.0+1build')
end)
test("identifiers can be separated by colons; they must be compared individually", function()
assert_less_than(v'1.0.0+0.3.7', v'1.3.7+build')
assert_less_than(v'1.3.7+build', v'1.3.7+build.2.b8f12d7')
assert_less_than(v'1.3.7+build.2.b8f12d7', v'1.3.7+build.11.e0f985a')
end)
end)
end) end)
describe("nextPatch", function() describe("nextPatch", function()