%%% @copyright 2024 Erlware, LLC.
-module(ec_semver_tests).

-include_lib("eunit/include/eunit.hrl").

eql_test() ->
    ?assertMatch(true, ec_semver:eql("1.0.0-alpha",
                           "1.0.0-alpha")),
    ?assertMatch(true, ec_semver:eql("v1.0.0-alpha",
                           "1.0.0-alpha")),
    ?assertMatch(true, ec_semver:eql("1",
                           "1.0.0")),
    ?assertMatch(true, ec_semver:eql("v1",
                           "v1.0.0")),
    ?assertMatch(true, ec_semver:eql("1.0",
                           "1.0.0")),
    ?assertMatch(true, ec_semver:eql("1.0.0",
                           "1")),
    ?assertMatch(true, ec_semver:eql("1.0.0.0",
                           "1")),
    ?assertMatch(true, ec_semver:eql("1.0+alpha.1",
                           "1.0.0+alpha.1")),
    ?assertMatch(true, ec_semver:eql("1.0-alpha.1+build.1",
                           "1.0.0-alpha.1+build.1")),
    ?assertMatch(true, ec_semver:eql("1.0-alpha.1+build.1",
                           "1.0.0.0-alpha.1+build.1")),
    ?assertMatch(true, ec_semver:eql("1.0-alpha.1+build.1",
                           "v1.0.0.0-alpha.1+build.1")),
    ?assertMatch(true, ec_semver:eql("1.0-pre-alpha.1",
                           "1.0.0-pre-alpha.1")),
    ?assertMatch(true, ec_semver:eql("aa", "aa")),
    ?assertMatch(true, ec_semver:eql("AA.BB", "AA.BB")),
    ?assertMatch(true, ec_semver:eql("BBB-super", "BBB-super")),
    ?assertMatch(true, not ec_semver:eql("1.0.0",
                               "1.0.1")),
    ?assertMatch(true, not ec_semver:eql("1.0.0-alpha",
                               "1.0.1+alpha")),
    ?assertMatch(true, not ec_semver:eql("1.0.0+build.1",
                               "1.0.1+build.2")),
    ?assertMatch(true, not ec_semver:eql("1.0.0.0+build.1",
                               "1.0.0.1+build.2")),
    ?assertMatch(true, not ec_semver:eql("FFF", "BBB")),
    ?assertMatch(true, not ec_semver:eql("1", "1BBBB")).

gt_test() ->
    ?assertMatch(true, ec_semver:gt("1.0.0-alpha.1",
                          "1.0.0-alpha")),
    ?assertMatch(true, ec_semver:gt("1.0.0.1-alpha.1",
                          "1.0.0.1-alpha")),
    ?assertMatch(true, ec_semver:gt("1.0.0.4-alpha.1",
                          "1.0.0.2-alpha")),
    ?assertMatch(true, ec_semver:gt("1.0.0.0-alpha.1",
                          "1.0.0-alpha")),
    ?assertMatch(true, ec_semver:gt("1.0.0-beta.2",
                          "1.0.0-alpha.1")),
    ?assertMatch(true, ec_semver:gt("1.0.0-beta.11",
                          "1.0.0-beta.2")),
    ?assertMatch(true, ec_semver:gt("1.0.0-pre-alpha.14",
                          "1.0.0-pre-alpha.3")),
    ?assertMatch(true, ec_semver:gt("1.0.0-beta.11",
                          "1.0.0.0-beta.2")),
    ?assertMatch(true, ec_semver:gt("1.0.0-rc.1", "1.0.0-beta.11")),
    ?assertMatch(true, ec_semver:gt("1.0.0-rc.1+build.1", "1.0.0-rc.1")),
    ?assertMatch(true, ec_semver:gt("1.0.0", "1.0.0-rc.1+build.1")),
    ?assertMatch(true, ec_semver:gt("1.0.0+0.3.7", "1.0.0")),
    ?assertMatch(true, ec_semver:gt("1.3.7+build", "1.0.0+0.3.7")),
    ?assertMatch(true, ec_semver:gt("1.3.7+build.2.b8f12d7",
                          "1.3.7+build")),
    ?assertMatch(true, ec_semver:gt("1.3.7+build.2.b8f12d7",
                          "1.3.7.0+build")),
    ?assertMatch(true, ec_semver:gt("1.3.7+build.11.e0f985a",
                          "1.3.7+build.2.b8f12d7")),
    ?assertMatch(true, ec_semver:gt("aa.cc",
                          "aa.bb")),
    ?assertMatch(true, not ec_semver:gt("1.0.0-alpha",
                              "1.0.0-alpha.1")),
    ?assertMatch(true, not ec_semver:gt("1.0.0-alpha",
                              "1.0.0.0-alpha.1")),
    ?assertMatch(true, not ec_semver:gt("1.0.0-alpha.1",
                              "1.0.0-beta.2")),
    ?assertMatch(true, not ec_semver:gt("1.0.0-beta.2",
                              "1.0.0-beta.11")),
    ?assertMatch(true, not ec_semver:gt("1.0.0-beta.11",
                              "1.0.0-rc.1")),
    ?assertMatch(true, not ec_semver:gt("1.0.0-pre-alpha.3",
                              "1.0.0-pre-alpha.14")),
    ?assertMatch(true, not ec_semver:gt("1.0.0-rc.1",
                              "1.0.0-rc.1+build.1")),
    ?assertMatch(true, not ec_semver:gt("1.0.0-rc.1+build.1",
                              "1.0.0")),
    ?assertMatch(true, not ec_semver:gt("1.0.0",
                              "1.0.0+0.3.7")),
    ?assertMatch(true, not ec_semver:gt("1.0.0+0.3.7",
                              "1.3.7+build")),
    ?assertMatch(true, not ec_semver:gt("1.3.7+build",
                              "1.3.7+build.2.b8f12d7")),
    ?assertMatch(true, not ec_semver:gt("1.3.7+build.2.b8f12d7",
                              "1.3.7+build.11.e0f985a")),
    ?assertMatch(true, not ec_semver:gt("1.0.0-alpha",
                              "1.0.0-alpha")),
    ?assertMatch(true, not ec_semver:gt("1",
                              "1.0.0")),
    ?assertMatch(true, not ec_semver:gt("aa.bb",
                              "aa.bb")),
    ?assertMatch(true, not ec_semver:gt("aa.cc",
                              "aa.dd")),
    ?assertMatch(true, not ec_semver:gt("1.0",
                              "1.0.0")),
    ?assertMatch(true, not ec_semver:gt("1.0.0",
                              "1")),
    ?assertMatch(true, not ec_semver:gt("1.0+alpha.1",
                              "1.0.0+alpha.1")),
    ?assertMatch(true, not ec_semver:gt("1.0-alpha.1+build.1",
                              "1.0.0-alpha.1+build.1")).

lt_test() ->
    ?assertMatch(true, ec_semver:lt("1.0.0-alpha",
                          "1.0.0-alpha.1")),
    ?assertMatch(true, ec_semver:lt("1.0.0-alpha",
                          "1.0.0.0-alpha.1")),
    ?assertMatch(true, ec_semver:lt("1.0.0-alpha.1",
                          "1.0.0-beta.2")),
    ?assertMatch(true, ec_semver:lt("1.0.0-beta.2",
                          "1.0.0-beta.11")),
    ?assertMatch(true, ec_semver:lt("1.0.0-pre-alpha.3",
                          "1.0.0-pre-alpha.14")),
    ?assertMatch(true, ec_semver:lt("1.0.0-beta.11",
                          "1.0.0-rc.1")),
    ?assertMatch(true, ec_semver:lt("1.0.0.1-beta.11",
                          "1.0.0.1-rc.1")),
    ?assertMatch(true, ec_semver:lt("1.0.0-rc.1",
                          "1.0.0-rc.1+build.1")),
    ?assertMatch(true, ec_semver:lt("1.0.0-rc.1+build.1",
                          "1.0.0")),
    ?assertMatch(true, ec_semver:lt("1.0.0",
                          "1.0.0+0.3.7")),
    ?assertMatch(true, ec_semver:lt("1.0.0+0.3.7",
                          "1.3.7+build")),
    ?assertMatch(true, ec_semver:lt("1.3.7+build",
                          "1.3.7+build.2.b8f12d7")),
    ?assertMatch(true, ec_semver:lt("1.3.7+build.2.b8f12d7",
                          "1.3.7+build.11.e0f985a")),
    ?assertMatch(true, not ec_semver:lt("1.0.0-alpha",
                              "1.0.0-alpha")),
    ?assertMatch(true, not ec_semver:lt("1",
                              "1.0.0")),
    ?assertMatch(true, ec_semver:lt("1",
                          "1.0.0.1")),
    ?assertMatch(true, ec_semver:lt("AA.DD",
                          "AA.EE")),
    ?assertMatch(true, not ec_semver:lt("1.0",
                              "1.0.0")),
    ?assertMatch(true, not ec_semver:lt("1.0.0.0",
                              "1")),
    ?assertMatch(true, not ec_semver:lt("1.0+alpha.1",
                              "1.0.0+alpha.1")),
    ?assertMatch(true, not ec_semver:lt("AA.DD", "AA.CC")),
    ?assertMatch(true, not ec_semver:lt("1.0-alpha.1+build.1",
                              "1.0.0-alpha.1+build.1")),
    ?assertMatch(true, not ec_semver:lt("1.0.0-alpha.1",
                              "1.0.0-alpha")),
    ?assertMatch(true, not ec_semver:lt("1.0.0-beta.2",
                              "1.0.0-alpha.1")),
    ?assertMatch(true, not ec_semver:lt("1.0.0-beta.11",
                              "1.0.0-beta.2")),
    ?assertMatch(true, not ec_semver:lt("1.0.0-pre-alpha.14",
                              "1.0.0-pre-alpha.3")),
    ?assertMatch(true, not ec_semver:lt("1.0.0-rc.1", "1.0.0-beta.11")),
    ?assertMatch(true, not ec_semver:lt("1.0.0-rc.1+build.1", "1.0.0-rc.1")),
    ?assertMatch(true, not ec_semver:lt("1.0.0", "1.0.0-rc.1+build.1")),
    ?assertMatch(true, not ec_semver:lt("1.0.0+0.3.7", "1.0.0")),
    ?assertMatch(true, not ec_semver:lt("1.3.7+build", "1.0.0+0.3.7")),
    ?assertMatch(true, not ec_semver:lt("1.3.7+build.2.b8f12d7",
                              "1.3.7+build")),
    ?assertMatch(true, not ec_semver:lt("1.3.7+build.11.e0f985a",
                              "1.3.7+build.2.b8f12d7")).

gte_test() ->
    ?assertMatch(true, ec_semver:gte("1.0.0-alpha",
                           "1.0.0-alpha")),

    ?assertMatch(true, ec_semver:gte("1",
                           "1.0.0")),

    ?assertMatch(true, ec_semver:gte("1.0",
                           "1.0.0")),

    ?assertMatch(true, ec_semver:gte("1.0.0",
                           "1")),

    ?assertMatch(true, ec_semver:gte("1.0.0.0",
                           "1")),

    ?assertMatch(true, ec_semver:gte("1.0+alpha.1",
                           "1.0.0+alpha.1")),

    ?assertMatch(true, ec_semver:gte("1.0-alpha.1+build.1",
                           "1.0.0-alpha.1+build.1")),

    ?assertMatch(true, ec_semver:gte("1.0.0-alpha.1+build.1",
                           "1.0.0.0-alpha.1+build.1")),
    ?assertMatch(true, ec_semver:gte("1.0.0-alpha.1",
                           "1.0.0-alpha")),
    ?assertMatch(true, ec_semver:gte("1.0.0-pre-alpha.2",
                           "1.0.0-pre-alpha")),
    ?assertMatch(true, ec_semver:gte("1.0.0-beta.2",
                           "1.0.0-alpha.1")),
    ?assertMatch(true, ec_semver:gte("1.0.0-beta.11",
                           "1.0.0-beta.2")),
    ?assertMatch(true, ec_semver:gte("aa.bb", "aa.bb")),
    ?assertMatch(true, ec_semver:gte("dd", "aa")),
    ?assertMatch(true, ec_semver:gte("1.0.0-rc.1", "1.0.0-beta.11")),
    ?assertMatch(true, ec_semver:gte("1.0.0-rc.1+build.1", "1.0.0-rc.1")),
    ?assertMatch(true, ec_semver:gte("1.0.0", "1.0.0-rc.1+build.1")),
    ?assertMatch(true, ec_semver:gte("1.0.0+0.3.7", "1.0.0")),
    ?assertMatch(true, ec_semver:gte("1.3.7+build", "1.0.0+0.3.7")),
    ?assertMatch(true, ec_semver:gte("1.3.7+build.2.b8f12d7",
                           "1.3.7+build")),
    ?assertMatch(true, ec_semver:gte("1.3.7+build.11.e0f985a",
                           "1.3.7+build.2.b8f12d7")),
    ?assertMatch(true, not ec_semver:gte("1.0.0-alpha",
                               "1.0.0-alpha.1")),
    ?assertMatch(true, not ec_semver:gte("1.0.0-pre-alpha",
                               "1.0.0-pre-alpha.1")),
    ?assertMatch(true, not ec_semver:gte("CC", "DD")),
    ?assertMatch(true, not ec_semver:gte("1.0.0-alpha.1",
                               "1.0.0-beta.2")),
    ?assertMatch(true, not ec_semver:gte("1.0.0-beta.2",
                               "1.0.0-beta.11")),
    ?assertMatch(true, not ec_semver:gte("1.0.0-beta.11",
                               "1.0.0-rc.1")),
    ?assertMatch(true, not ec_semver:gte("1.0.0-rc.1",
                               "1.0.0-rc.1+build.1")),
    ?assertMatch(true, not ec_semver:gte("1.0.0-rc.1+build.1",
                               "1.0.0")),
    ?assertMatch(true, not ec_semver:gte("1.0.0",
                               "1.0.0+0.3.7")),
    ?assertMatch(true, not ec_semver:gte("1.0.0+0.3.7",
                               "1.3.7+build")),
    ?assertMatch(true, not ec_semver:gte("1.0.0",
                               "1.0.0+build.1")),
    ?assertMatch(true, not ec_semver:gte("1.3.7+build",
                               "1.3.7+build.2.b8f12d7")),
    ?assertMatch(true, not ec_semver:gte("1.3.7+build.2.b8f12d7",
                               "1.3.7+build.11.e0f985a")).
lte_test() ->
    ?assertMatch(true, ec_semver:lte("1.0.0-alpha",
                           "1.0.0-alpha.1")),
    ?assertMatch(true, ec_semver:lte("1.0.0-alpha.1",
                           "1.0.0-beta.2")),
    ?assertMatch(true, ec_semver:lte("1.0.0-beta.2",
                           "1.0.0-beta.11")),
    ?assertMatch(true, ec_semver:lte("1.0.0-pre-alpha.2",
                           "1.0.0-pre-alpha.11")),
    ?assertMatch(true, ec_semver:lte("1.0.0-beta.11",
                           "1.0.0-rc.1")),
    ?assertMatch(true, ec_semver:lte("1.0.0-rc.1",
                           "1.0.0-rc.1+build.1")),
    ?assertMatch(true, ec_semver:lte("1.0.0-rc.1+build.1",
                           "1.0.0")),
    ?assertMatch(true, ec_semver:lte("1.0.0",
                           "1.0.0+0.3.7")),
    ?assertMatch(true, ec_semver:lte("1.0.0+0.3.7",
                           "1.3.7+build")),
    ?assertMatch(true, ec_semver:lte("1.3.7+build",
                           "1.3.7+build.2.b8f12d7")),
    ?assertMatch(true, ec_semver:lte("1.3.7+build.2.b8f12d7",
                           "1.3.7+build.11.e0f985a")),
    ?assertMatch(true, ec_semver:lte("1.0.0-alpha",
                           "1.0.0-alpha")),
    ?assertMatch(true, ec_semver:lte("1",
                           "1.0.0")),
    ?assertMatch(true, ec_semver:lte("1.0",
                           "1.0.0")),
    ?assertMatch(true, ec_semver:lte("1.0.0",
                           "1")),
    ?assertMatch(true, ec_semver:lte("1.0+alpha.1",
                           "1.0.0+alpha.1")),
    ?assertMatch(true, ec_semver:lte("1.0.0.0+alpha.1",
                           "1.0.0+alpha.1")),
    ?assertMatch(true, ec_semver:lte("1.0-alpha.1+build.1",
                           "1.0.0-alpha.1+build.1")),
    ?assertMatch(true, ec_semver:lte("aa","cc")),
    ?assertMatch(true, ec_semver:lte("cc","cc")),
    ?assertMatch(true, not ec_semver:lte("1.0.0-alpha.1",
                              "1.0.0-alpha")),
    ?assertMatch(true, not ec_semver:lte("1.0.0-pre-alpha.2",
                               "1.0.0-pre-alpha")),
    ?assertMatch(true, not ec_semver:lte("cc", "aa")),
    ?assertMatch(true, not ec_semver:lte("1.0.0-beta.2",
                              "1.0.0-alpha.1")),
    ?assertMatch(true, not ec_semver:lte("1.0.0-beta.11",
                              "1.0.0-beta.2")),
    ?assertMatch(true, not ec_semver:lte("1.0.0-rc.1", "1.0.0-beta.11")),
    ?assertMatch(true, not ec_semver:lte("1.0.0-rc.1+build.1", "1.0.0-rc.1")),
    ?assertMatch(true, not ec_semver:lte("1.0.0", "1.0.0-rc.1+build.1")),
    ?assertMatch(true, not ec_semver:lte("1.0.0+0.3.7", "1.0.0")),
    ?assertMatch(true, not ec_semver:lte("1.3.7+build", "1.0.0+0.3.7")),
    ?assertMatch(true, not ec_semver:lte("1.3.7+build.2.b8f12d7",
                              "1.3.7+build")),
    ?assertMatch(true, not ec_semver:lte("1.3.7+build.11.e0f985a",
                              "1.3.7+build.2.b8f12d7")).

between_test() ->
    ?assertMatch(true, ec_semver:between("1.0.0-alpha",
                               "1.0.0-alpha.3",
                               "1.0.0-alpha.2")),
    ?assertMatch(true, ec_semver:between("1.0.0-alpha.1",
                               "1.0.0-beta.2",
                               "1.0.0-alpha.25")),
    ?assertMatch(true, ec_semver:between("1.0.0-beta.2",
                               "1.0.0-beta.11",
                               "1.0.0-beta.7")),
    ?assertMatch(true, ec_semver:between("1.0.0-pre-alpha.2",
                               "1.0.0-pre-alpha.11",
                               "1.0.0-pre-alpha.7")),
    ?assertMatch(true, ec_semver:between("1.0.0-beta.11",
                               "1.0.0-rc.3",
                               "1.0.0-rc.1")),
    ?assertMatch(true, ec_semver:between("1.0.0-rc.1",
                               "1.0.0-rc.1+build.3",
                               "1.0.0-rc.1+build.1")),

    ?assertMatch(true, ec_semver:between("1.0.0.0-rc.1",
                               "1.0.0-rc.1+build.3",
                               "1.0.0-rc.1+build.1")),
    ?assertMatch(true, ec_semver:between("1.0.0-rc.1+build.1",
                               "1.0.0",
                               "1.0.0-rc.33")),
    ?assertMatch(true, ec_semver:between("1.0.0",
                               "1.0.0+0.3.7",
                               "1.0.0+0.2")),
    ?assertMatch(true, ec_semver:between("1.0.0+0.3.7",
                               "1.3.7+build",
                               "1.2")),
    ?assertMatch(true, ec_semver:between("1.3.7+build",
                               "1.3.7+build.2.b8f12d7",
                               "1.3.7+build.1")),
    ?assertMatch(true, ec_semver:between("1.3.7+build.2.b8f12d7",
                               "1.3.7+build.11.e0f985a",
                               "1.3.7+build.10.a36faa")),
    ?assertMatch(true, ec_semver:between("1.0.0-alpha",
                               "1.0.0-alpha",
                               "1.0.0-alpha")),
    ?assertMatch(true, ec_semver:between("1",
                               "1.0.0",
                               "1.0.0")),
    ?assertMatch(true, ec_semver:between("1.0",
                               "1.0.0",
                               "1.0.0")),

    ?assertMatch(true, ec_semver:between("1.0",
                               "1.0.0.0",
                               "1.0.0.0")),
    ?assertMatch(true, ec_semver:between("1.0.0",
                               "1",
                               "1")),
    ?assertMatch(true, ec_semver:between("1.0+alpha.1",
                               "1.0.0+alpha.1",
                               "1.0.0+alpha.1")),
    ?assertMatch(true, ec_semver:between("1.0-alpha.1+build.1",
                               "1.0.0-alpha.1+build.1",
                               "1.0.0-alpha.1+build.1")),
    ?assertMatch(true, ec_semver:between("aaa",
                               "ddd",
                               "cc")),
    ?assertMatch(true, not ec_semver:between("1.0.0-alpha.1",
                                   "1.0.0-alpha.22",
                                   "1.0.0")),
    ?assertMatch(true, not ec_semver:between("1.0.0-pre-alpha.1",
                                   "1.0.0-pre-alpha.22",
                                   "1.0.0")),
    ?assertMatch(true, not ec_semver:between("1.0.0",
                                   "1.0.0-alpha.1",
                                   "2.0")),
    ?assertMatch(true, not ec_semver:between("1.0.0-beta.1",
                                   "1.0.0-beta.11",
                                   "1.0.0-alpha")),
    ?assertMatch(true, not ec_semver:between("1.0.0-beta.11", "1.0.0-rc.1",
                                   "1.0.0-rc.22")),
    ?assertMatch(true, not ec_semver:between("aaa", "ddd", "zzz")).

pes_test() ->
    ?assertMatch(true, ec_semver:pes("1.0.0-rc.0", "1.0.0-rc.0")),
    ?assertMatch(true, ec_semver:pes("1.0.0-rc.1", "1.0.0-rc.0")),
    ?assertMatch(true, ec_semver:pes("1.0.0", "1.0.0-rc.0")),
    ?assertMatch(false, ec_semver:pes("1.0.0-rc.0", "1.0.0-rc.1")),
    ?assertMatch(true, ec_semver:pes("2.6.0", "2.6")),
    ?assertMatch(true, ec_semver:pes("2.7", "2.6")),
    ?assertMatch(true, ec_semver:pes("2.8", "2.6")),
    ?assertMatch(true, ec_semver:pes("2.9", "2.6")),
    ?assertMatch(true, ec_semver:pes("A.B", "A.A")),
    ?assertMatch(true, not ec_semver:pes("3.0.0", "2.6")),
    ?assertMatch(true, not ec_semver:pes("2.5", "2.6")),
    ?assertMatch(true, ec_semver:pes("2.6.5", "2.6.5")),
    ?assertMatch(true, ec_semver:pes("2.6.6", "2.6.5")),
    ?assertMatch(true, ec_semver:pes("2.6.7", "2.6.5")),
    ?assertMatch(true, ec_semver:pes("2.6.8", "2.6.5")),
    ?assertMatch(true, ec_semver:pes("2.6.9", "2.6.5")),
    ?assertMatch(true, ec_semver:pes("2.6.0.9", "2.6.0.5")),
    ?assertMatch(true, not ec_semver:pes("2.7", "2.6.5")),
    ?assertMatch(true, not ec_semver:pes("2.1.7", "2.1.6.5")),
    ?assertMatch(true, not ec_semver:pes("A.A", "A.B")),
    ?assertMatch(true, not ec_semver:pes("2.5", "2.6.5")).

parse_test() ->
    ?assertEqual({1, {[],[]}}, ec_semver:parse(<<"1">>)),
    ?assertEqual({{1,2,34},{[],[]}}, ec_semver:parse(<<"1.2.34">>)),
    ?assertEqual({<<"a">>, {[],[]}}, ec_semver:parse(<<"a">>)),
    ?assertEqual({{<<"a">>,<<"b">>}, {[],[]}}, ec_semver:parse(<<"a.b">>)),
    ?assertEqual({1, {[],[]}}, ec_semver:parse(<<"1">>)),
    ?assertEqual({{1,2}, {[],[]}}, ec_semver:parse(<<"1.2">>)),
    ?assertEqual({{1,2,2}, {[],[]}}, ec_semver:parse(<<"1.2.2">>)),
    ?assertEqual({{1,99,2}, {[],[]}}, ec_semver:parse(<<"1.99.2">>)),
    ?assertEqual({{1,99,2}, {[<<"alpha">>],[]}}, ec_semver:parse(<<"1.99.2-alpha">>)),
    ?assertEqual({{1,99,2}, {[<<"alpha">>,1], []}}, ec_semver:parse(<<"1.99.2-alpha.1">>)),
    ?assertEqual({{1,99,2}, {[<<"pre-alpha">>,1], []}}, ec_semver:parse(<<"1.99.2-pre-alpha.1">>)),
    ?assertEqual({{1,99,2}, {[], [<<"build">>, 1, <<"a36">>]}},
        ec_semver:parse(<<"1.99.2+build.1.a36">>)),
    ?assertEqual({{1,99,2,44}, {[], [<<"build">>, 1, <<"a36">>]}},
        ec_semver:parse(<<"1.99.2.44+build.1.a36">>)),
    ?assertEqual({{1,99,2}, {[<<"alpha">>, 1], [<<"build">>, 1, <<"a36">>]}},
        ec_semver:parse("1.99.2-alpha.1+build.1.a36")),
    ?assertEqual({{1,99,2}, {[<<"pre-alpha">>, 1], [<<"build">>, 1, <<"a36">>]}},
        ec_semver:parse("1.99.2-pre-alpha.1+build.1.a36")).

version_format_test() ->
    ?assertEqual(["1", [], []], ec_semver:format({1, {[],[]}})),
    ?assertEqual(["1", ".", "2", ".", "34", [], []], ec_semver:format({{1,2,34},{[],[]}})),
    ?assertEqual(<<"a">>, erlang:iolist_to_binary(ec_semver:format({<<"a">>, {[],[]}}))),
    ?assertEqual(<<"a.b">>, erlang:iolist_to_binary(ec_semver:format({{<<"a">>,<<"b">>}, {[],[]}}))),
    ?assertEqual(<<"1">>, erlang:iolist_to_binary(ec_semver:format({1, {[],[]}}))),
    ?assertEqual(<<"1.2">>, erlang:iolist_to_binary(ec_semver:format({{1,2}, {[],[]}}))),
    ?assertEqual(<<"1.2.2">>, erlang:iolist_to_binary(ec_semver:format({{1,2,2}, {[],[]}}))),
    ?assertEqual(<<"1.99.2">>, erlang:iolist_to_binary(ec_semver:format({{1,99,2}, {[],[]}}))),
    ?assertEqual(<<"1.99.2-alpha">>, erlang:iolist_to_binary(ec_semver:format({{1,99,2}, {[<<"alpha">>],[]}}))),
    ?assertEqual(<<"1.99.2-alpha.1">>, erlang:iolist_to_binary(ec_semver:format({{1,99,2}, {[<<"alpha">>,1], []}}))),
    ?assertEqual(<<"1.99.2-pre-alpha.1">>, erlang:iolist_to_binary(ec_semver:format({{1,99,2}, {[<<"pre-alpha">>,1], []}}))),
    ?assertEqual(<<"1.99.2+build.1.a36">>,
                 erlang:iolist_to_binary(ec_semver:format({{1,99,2}, {[], [<<"build">>, 1, <<"a36">>]}}))),
    ?assertEqual(<<"1.99.2.44+build.1.a36">>,
                 erlang:iolist_to_binary(ec_semver:format({{1,99,2,44}, {[], [<<"build">>, 1, <<"a36">>]}}))),
    ?assertEqual(<<"1.99.2-alpha.1+build.1.a36">>,
                 erlang:iolist_to_binary(ec_semver:format({{1,99,2}, {[<<"alpha">>, 1], [<<"build">>, 1, <<"a36">>]}}))),
    ?assertEqual(<<"1.99.2-pre-alpha.1+build.1.a36">>,
        erlang:iolist_to_binary(ec_semver:format({{1,99,2}, {[<<"pre-alpha">>, 1], [<<"build">>, 1, <<"a36">>]}}))),
    ?assertEqual(<<"1">>, erlang:iolist_to_binary(ec_semver:format({1, {[],[]}}))).
