10c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez// Copyright (c) 2012 The Chromium Authors. All rights reserved.
20c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez// Use of this source code is governed by a BSD-style license that can be
30c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez// found in the LICENSE file.
40c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez
50c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez#include "base/version.h"
60c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez
70c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez#include <stddef.h>
80c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez#include <stdint.h>
90c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez
100c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez#include "base/macros.h"
110c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez#include "testing/gtest/include/gtest/gtest.h"
120c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez
130c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chaveznamespace {
140c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez
150c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector ChavezTEST(VersionTest, DefaultConstructor) {
160c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  Version v;
170c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  EXPECT_FALSE(v.IsValid());
180c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez}
190c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez
200c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector ChavezTEST(VersionTest, ValueSemantics) {
210c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  Version v1("1.2.3.4");
220c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  EXPECT_TRUE(v1.IsValid());
230c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  Version v3;
240c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  EXPECT_FALSE(v3.IsValid());
250c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  {
260c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    Version v2(v1);
270c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    v3 = v2;
280c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    EXPECT_TRUE(v2.IsValid());
290c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    EXPECT_EQ(v1, v2);
300c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  }
310c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  EXPECT_EQ(v3, v1);
320c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez}
330c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez
340c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector ChavezTEST(VersionTest, GetVersionFromString) {
350c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  static const struct version_string {
360c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    const char* input;
370c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    size_t parts;
380c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    uint32_t firstpart;
390c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    bool success;
400c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  } cases[] = {
410c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"", 0, 0, false},
420c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {" ", 0, 0, false},
430c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"\t", 0, 0, false},
440c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"\n", 0, 0, false},
450c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"  ", 0, 0, false},
460c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {".", 0, 0, false},
470c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {" . ", 0, 0, false},
480c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"0", 1, 0, true},
490c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"0.", 0, 0, false},
500c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"0.0", 2, 0, true},
510c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"4294967295.0", 2, 4294967295, true},
520c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"4294967296.0", 0, 0, false},
530c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"-1.0", 0, 0, false},
540c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.-1.0", 0, 0, false},
550c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1,--1.0", 0, 0, false},
560c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"+1.0", 0, 0, false},
570c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.+1.0", 0, 0, false},
580c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1+1.0", 0, 0, false},
590c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"++1.0", 0, 0, false},
600c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.0a", 0, 0, false},
610c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.2.3.4.5.6.7.8.9.0", 10, 1, true},
620c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"02.1", 0, 0, false},
630c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"0.01", 2, 0, true},
640c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"f.1", 0, 0, false},
650c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"15.007.20011", 3, 15, true},
660c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"15.5.28.130162", 4, 15, true},
670c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  };
680c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez
690c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  for (size_t i = 0; i < arraysize(cases); ++i) {
700c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    Version version(cases[i].input);
710c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    EXPECT_EQ(cases[i].success, version.IsValid());
720c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    if (cases[i].success) {
730c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_EQ(cases[i].parts, version.components().size());
740c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_EQ(cases[i].firstpart, version.components()[0]);
750c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    }
760c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  }
770c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez}
780c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez
790c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector ChavezTEST(VersionTest, Compare) {
800c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  static const struct version_compare {
810c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    const char* lhs;
820c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    const char* rhs;
830c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    int expected;
840c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  } cases[] = {
850c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.0", "1.0", 0},
860c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.0", "0.0", 1},
870c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.0", "2.0", -1},
880c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.0", "1.1", -1},
890c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.1", "1.0", 1},
900c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.0", "1.0.1", -1},
910c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.1", "1.0.1", 1},
920c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.1", "1.0.1", 1},
930c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.0.0", "1.0", 0},
940c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.0.3", "1.0.20", -1},
950c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"11.0.10", "15.007.20011", -1},
960c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"11.0.10", "15.5.28.130162", -1},
970c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  };
980c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  for (size_t i = 0; i < arraysize(cases); ++i) {
990c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    Version lhs(cases[i].lhs);
1000c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    Version rhs(cases[i].rhs);
1010c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    EXPECT_EQ(lhs.CompareTo(rhs), cases[i].expected) <<
1020c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez        cases[i].lhs << " ? " << cases[i].rhs;
1030c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez
1040c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    // Test comparison operators
1050c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    switch (cases[i].expected) {
1060c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    case -1:
1070c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_LT(lhs, rhs);
1080c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_LE(lhs, rhs);
1090c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_NE(lhs, rhs);
1100c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_FALSE(lhs == rhs);
1110c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_FALSE(lhs >= rhs);
1120c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_FALSE(lhs > rhs);
1130c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      break;
1140c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    case 0:
1150c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_FALSE(lhs < rhs);
1160c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_LE(lhs, rhs);
1170c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_FALSE(lhs != rhs);
1180c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_EQ(lhs, rhs);
1190c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_GE(lhs, rhs);
1200c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_FALSE(lhs > rhs);
1210c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      break;
1220c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    case 1:
1230c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_FALSE(lhs < rhs);
1240c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_FALSE(lhs <= rhs);
1250c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_NE(lhs, rhs);
1260c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_FALSE(lhs == rhs);
1270c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_GE(lhs, rhs);
1280c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      EXPECT_GT(lhs, rhs);
1290c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez      break;
1300c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    }
1310c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  }
1320c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez}
1330c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez
1340c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector ChavezTEST(VersionTest, CompareToWildcardString) {
1350c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  static const struct version_compare {
1360c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    const char* lhs;
1370c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    const char* rhs;
1380c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    int expected;
1390c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  } cases[] = {
1400c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.0", "1.*", 0},
1410c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.0", "0.*", 1},
1420c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.0", "2.*", -1},
1430c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.2.3", "1.2.3.*", 0},
1440c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"10.0", "1.0.*", 1},
1450c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.0", "3.0.*", -1},
1460c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.4", "1.3.0.*", 1},
1470c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.3.9", "1.3.*", 0},
1480c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.4.1", "1.3.*", 1},
1490c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.3", "1.4.5.*", -1},
1500c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.5", "1.4.5.*", 1},
1510c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.3.9", "1.3.*", 0},
1520c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.2.0.0.0.0", "1.2.*", 0},
1530c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  };
1540c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  for (size_t i = 0; i < arraysize(cases); ++i) {
1550c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    const Version version(cases[i].lhs);
1560c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    const int result = version.CompareToWildcardString(cases[i].rhs);
1570c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    EXPECT_EQ(result, cases[i].expected) << cases[i].lhs << "?" << cases[i].rhs;
1580c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  }
1590c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez}
1600c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez
1610c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector ChavezTEST(VersionTest, IsValidWildcardString) {
1620c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  static const struct version_compare {
1630c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    const char* version;
1640c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    bool expected;
1650c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  } cases[] = {
1660c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.0", true},
1670c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"", false},
1680c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.2.3.4.5.6", true},
1690c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.2.3.*", true},
1700c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.2.3.5*", false},
1710c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.2.3.56*", false},
1720c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"1.*.3", false},
1730c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"20.*", true},
1740c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"+2.*", false},
1750c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"*", false},
1760c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    {"*.2", false},
1770c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  };
1780c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  for (size_t i = 0; i < arraysize(cases); ++i) {
1790c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez    EXPECT_EQ(Version::IsValidWildcardString(cases[i].version),
1800c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez        cases[i].expected) << cases[i].version << "?" << cases[i].expected;
1810c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  }
1820c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez}
1830c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez
1840c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez}  // namespace
185