prereleases and builds now working 100% like the spec

This commit is contained in:
Enrique García Cota
2012-01-15 13:30:24 +01:00
parent b1d083e382
commit 48ecb3b539
2 changed files with 63 additions and 24 deletions

View File

@@ -19,12 +19,37 @@ end
local function parseExtra(extra)
if not present(extra) then return end
local sign, data = extra:match("([-+])([%w-][%.%w-]*)")
assert(sign and data, ("The string %q must start with - or + followed by dashes, alphanumerics or dots."):format(extra))
if sign == "-" then return data, nil end
return nil,data
local prereleaseWithSign, buildWithSign = extra:match("^(-[^+]+)(+.+)$")
if not (prereleaseWithSign and buildWithSign) then
prereleaseWithSign = extra:match("^(-.+)$")
buildWithSign = extra:match("^(+.+)$")
end
assert(prereleaseWithSign or buildWithSign, ("The parameter %q must begin with + or - to denote a prerelease or a buld"):format(extra))
local prerelease, build
if prereleaseWithSign then
prerelease = prereleaseWithSign:match("^-(%w[%.%w-]*)$")
assert(prerelease, ("The prerelease %q is not a slash followed by alphanumerics, dots and slashes"):format(prereleaseWithSign))
end
if buildWithSign then
build = buildWithSign:match("^%+(%w[%.%w-]*)$")
assert(build, ("The build %q is not a + sign followed by alphanumerics, dots and slashes"):format(buildWithSign))
end
return prerelease, build
end
local function parseString(str)
local sMajor, sMinor, sPatch, extra = str:match("^(%d+)%.?(%d*)%.?(%d*)(.-)$")
assert(type(sMajor) == 'string', ("Could not extract version number(s) from %q"):format(str))
local major, minor, patch = tonumber(sMajor), tonumber(sMinor), tonumber(sPatch)
local prerelease, build = parseExtra(extra)
return major,minor,patch,prerelease,build
end
-- return 0 if a == b, -1 if a < b, and 1 if a > b
local function compare(a,b)
return a == b and 0 or a < b and -1 or 1
@@ -107,24 +132,19 @@ function mt:__pow(other)
end
function mt:__tostring()
local buffer = { ("%d.%d.%d"):format(self.major, self.minor, self.patch) }
if self.prerelease then buffer[2] = "-" .. self.prerelease
elseif self.build then buffer[2] = "+" .. self.build
end
if self.prerelease then table.insert(buffer, "-" .. self.prerelease) end
if self.build then table.insert(buffer, "+" .. self.build) end
return table.concat(buffer)
end
-- defined as local at the begining of the file
version = function(major, minor, patch, extra)
version = function(major, minor, patch, prerelease, build)
assert(major, "At least one parameter is needed")
if type(major) == 'string' then
local sMajor, sMinor, sPatch
sMajor, sMinor, sPatch, extra = major:match("^(%d+)%.?(%d*)%.?(%d*)(.-)$")
assert(type(sMajor) == 'string', ("Could not extract version number(s) from %q"):format(major))
major, minor, patch = tonumber(sMajor), tonumber(sMinor), tonumber(sPatch)
major,minor,patch,prerelease,build = parseString(major)
end
patch = patch or 0
minor = minor or 0
@@ -132,8 +152,6 @@ version = function(major, minor, patch, extra)
checkPositiveInteger(minor, "minor")
checkPositiveInteger(patch, "patch")
local prerelease, build = parseExtra(extra)
local result = {major=major, minor=minor, patch=patch, prerelease=prerelease, build=build}
return setmetatable(result, mt)
end

View File

@@ -26,10 +26,13 @@ context('semver', function()
end)
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)
it('parses builds', function()
checkVersion(v(1,2,3,"+build.1"), 1,2,3,nil,"build.1")
checkVersion(v(1,2,3,nil,"build.1"), 1,2,3,nil,"build.1")
end)
it('parses prereleases + builds', function()
checkVersion(v(1,2,3,"alpha","build.1"), 1,2,3,"alpha","build.1")
end)
end)
@@ -52,6 +55,9 @@ context('semver', function()
test("1.2.3+build.15", function()
checkVersion( v'1.2.3+build.15', 1,2,3,nil,'build.15' )
end)
test("1.2.3-rc1+build.15", function()
checkVersion( v'1.2.3-rc1+build.15', 1,2,3,'rc1','build.15' )
end)
end)
describe('errors', function()
@@ -80,6 +86,12 @@ context('semver', function()
test('a non-string or number is passed', function()
assert_error(function() v({}) end)
end)
test('an invalid prerelease', function()
assert_error(function() v'1.2.3-%?' end)
end)
test('an invalid build', function()
assert_error(function() v'1.2.3+%?' end)
end)
end)
end)
@@ -89,10 +101,13 @@ context('semver', function()
end)
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)
it("works with a build", function()
assert_equal("1.2.3+foobar", tostring(v(1,2,3, '+foobar')))
assert_equal("1.2.3+foobar", tostring(v(1,2,3,nil,'foobar')))
end)
it("works with a prerelease and a build", function()
assert_equal("1.2.3-alpha+foobar", tostring(v'1.2.3-alpha+foobar'))
end)
end)
@@ -181,6 +196,10 @@ context('semver', function()
assert_less_than(v'1.3.7+build.2.b8f12d7', v'1.3.7+build.11.e0f985a')
end)
end)
test("prereleases + builds", function()
assert_less_than(v'1.0.0-rc.1', v'1.0.0-rc.1+build.1')
assert_less_than(v'1.0.0-rc.1+build.1', v'1.0.0')
end)
end)
describe("nextPatch", function()
@@ -193,8 +212,8 @@ context('semver', function()
it("increases the minor number by 1", function()
assert_equal(v'1.2.0', v'1.1.0':nextMinor())
end)
it("resets the patch number", function()
assert_equal(v'1.2.0', v'1.1.7':nextMinor())
it("resets the patch number, prerelease and build", function()
assert_equal(v'1.2.0', v'1.1.7-a+b':nextMinor())
end)
end)
@@ -202,8 +221,8 @@ context('semver', function()
it("increases the major number by 1", function()
assert_equal(v'2.0.0', v'1.0.0':nextMajor())
end)
it("resets the patch number", function()
assert_equal(v'2.0.0', v'1.2.3':nextMajor())
it("resets the minor, patch, prerelease and build", function()
assert_equal(v'2.0.0', v'1.2.3-a+b':nextMajor())
end)
end)
@@ -220,9 +239,11 @@ context('semver', function()
assert_false(v(2,0,0) ^ v(1,0,0))
end)
test("patch versions are always compatible", function()
test("patches, prereleases and builds are ignored", function()
assert_true(v(1,2,3) ^ v(1,2,0))
assert_true(v(1,2,3) ^ v(1,2,5))
assert_true(v(1,2,3,'foo') ^ v(1,2,3))
assert_true(v(1,2,3,nil,'bar') ^ v(1,2,3))
end)
test("it's safe to upgrade to a newer minor version", function()