forked from TrueCloudLab/neoneo-go
Merge pull request #1541 from nspcc-dev/core/fix_nef_getversion
smartcontract: fix nef.GetVersion
This commit is contained in:
commit
543871fb2c
2 changed files with 88 additions and 60 deletions
|
@ -82,52 +82,51 @@ func NewFile(script []byte) (File, error) {
|
|||
}
|
||||
|
||||
// GetVersion returns Version from the given string. It accepts the following formats:
|
||||
// `major.minor.build-[...]`
|
||||
// `major.minor.build.revision-[...]`
|
||||
// `major[-...].minor[-...].build[-...]` and `major[-...].minor[-...].build[-...].revision[-...]`
|
||||
// where `major`, `minor`, `build` and `revision` are 32-bit integers with base=10
|
||||
func GetVersion(version string) (Version, error) {
|
||||
var (
|
||||
result Version
|
||||
err error
|
||||
)
|
||||
versions := strings.SplitN(version, ".", 4)
|
||||
if len(versions) < 3 {
|
||||
return result, errors.New("invalid version format")
|
||||
}
|
||||
major, err := strconv.ParseInt(versions[0], 10, 32)
|
||||
result.Major, err = parseDashedVersion(versions[0])
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("failed to parse major version: %w", err)
|
||||
}
|
||||
result.Major = int32(major)
|
||||
|
||||
minor, err := strconv.ParseInt(versions[1], 10, 32)
|
||||
result.Minor, err = parseDashedVersion(versions[1])
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("failed to parse minor version: %w", err)
|
||||
|
||||
}
|
||||
result.Minor = int32(minor)
|
||||
|
||||
b := versions[2]
|
||||
if len(versions) == 3 {
|
||||
b = strings.SplitN(b, "-", 2)[0]
|
||||
}
|
||||
build, err := strconv.ParseInt(b, 10, 32)
|
||||
result.Build, err = parseDashedVersion(versions[2])
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("failed to parse build version: %w", err)
|
||||
}
|
||||
result.Build = int32(build)
|
||||
|
||||
if len(versions) == 4 {
|
||||
r := strings.SplitN(versions[3], "-", 2)[0]
|
||||
revision, err := strconv.ParseInt(r, 10, 32)
|
||||
result.Revision, err = parseDashedVersion(versions[3])
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("failed to parse revision version: %w", err)
|
||||
}
|
||||
result.Revision = int32(revision)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// parseDashedVersion extracts int from string of the format `int[-...]` where `int` is
|
||||
// a 32-bit integer with base=10.
|
||||
func parseDashedVersion(version string) (int32, error) {
|
||||
version = strings.SplitN(version, "-", 2)[0]
|
||||
result, err := strconv.ParseInt(version, 10, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int32(result), nil
|
||||
}
|
||||
|
||||
// EncodeBinary implements io.Serializable interface.
|
||||
func (v *Version) EncodeBinary(w *io.BinWriter) {
|
||||
w.WriteU32LE(uint32(v.Major))
|
||||
|
|
|
@ -93,48 +93,77 @@ func TestBytesFromBytes(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetVersion(t *testing.T) {
|
||||
_, err := GetVersion("qwerty")
|
||||
require.Error(t, err)
|
||||
|
||||
_, err = GetVersion("1.pre")
|
||||
require.Error(t, err)
|
||||
|
||||
_, err = GetVersion("1.1.pre")
|
||||
require.Error(t, err)
|
||||
|
||||
_, err = GetVersion("1.1.1.pre")
|
||||
require.Error(t, err)
|
||||
|
||||
actual, err := GetVersion("1.1.1-pre")
|
||||
require.NoError(t, err)
|
||||
expected := Version{
|
||||
testCases := map[string]struct {
|
||||
input string
|
||||
fails bool
|
||||
expected Version
|
||||
}{
|
||||
"major only": {
|
||||
input: "1",
|
||||
fails: true,
|
||||
},
|
||||
"major and minor only": {
|
||||
input: "1.1",
|
||||
fails: true,
|
||||
},
|
||||
"major, minor and revision only": {
|
||||
input: "1.1.1",
|
||||
expected: Version{
|
||||
Major: 1,
|
||||
Minor: 1,
|
||||
Build: 1,
|
||||
Revision: 0,
|
||||
}
|
||||
require.Equal(t, expected, actual)
|
||||
|
||||
actual, err = GetVersion("0.90.0-pre")
|
||||
require.NoError(t, err)
|
||||
expected = Version{
|
||||
Major: 0,
|
||||
Minor: 90,
|
||||
Build: 0,
|
||||
Revision: 0,
|
||||
}
|
||||
require.Equal(t, expected, actual)
|
||||
|
||||
actual, err = GetVersion("1.1.1.1-pre")
|
||||
require.NoError(t, err)
|
||||
expected = Version{
|
||||
},
|
||||
},
|
||||
"full version": {
|
||||
input: "1.1.1.1",
|
||||
expected: Version{
|
||||
Major: 1,
|
||||
Minor: 1,
|
||||
Build: 1,
|
||||
Revision: 1,
|
||||
},
|
||||
},
|
||||
"dashed, without revision": {
|
||||
input: "1-pre.2-pre.3-pre",
|
||||
expected: Version{
|
||||
Major: 1,
|
||||
Minor: 2,
|
||||
Build: 3,
|
||||
Revision: 0,
|
||||
},
|
||||
},
|
||||
"dashed, full version": {
|
||||
input: "1-pre.2-pre.3-pre.4-pre",
|
||||
expected: Version{
|
||||
Major: 1,
|
||||
Minor: 2,
|
||||
Build: 3,
|
||||
Revision: 4,
|
||||
},
|
||||
},
|
||||
"dashed build": {
|
||||
input: "1.2.3-pre.4",
|
||||
expected: Version{
|
||||
Major: 1,
|
||||
Minor: 2,
|
||||
Build: 3,
|
||||
Revision: 4,
|
||||
},
|
||||
},
|
||||
"extra versions": {
|
||||
input: "1.2.3.4.5",
|
||||
fails: true,
|
||||
},
|
||||
}
|
||||
for name, test := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
actual, err := GetVersion(test.input)
|
||||
if test.fails {
|
||||
require.NotNil(t, err)
|
||||
} else {
|
||||
require.Equal(t, test.expected, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
require.Equal(t, expected, actual)
|
||||
|
||||
_, err = GetVersion("1.1.1.1.1")
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue