Skip to content

Commit

Permalink
more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jesseduffield committed Apr 11, 2020
1 parent f693c3f commit f119ee6
Show file tree
Hide file tree
Showing 4 changed files with 297 additions and 161 deletions.
272 changes: 272 additions & 0 deletions pkg/commands/config_parsing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
package commands

import (
"io"
"io/ioutil"

"github.com/buger/jsonparser"
)

func unescape(b []byte) string {
buf := make([]byte, 0, len(b))
buf, err := jsonparser.Unescape(b, buf)
if err != nil {
return string(b)
}
return string(buf)
}

func UnmarshalPackageConfig(r io.Reader) (*PackageConfig, error) {
configData, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}

pkgConfig := &PackageConfig{}

type stringMapping struct {
path []string
ptr *string
}

parseStrings := func(data []byte, mappings []stringMapping) {
for _, mapping := range mappings {
value, err := jsonparser.GetString(data, mapping.path...)
if err == nil {
*mapping.ptr = value
}
}
}

parseStrings(configData,
[]stringMapping{
{
path: []string{"name"},
ptr: &pkgConfig.Name,
},
{
path: []string{"version"},
ptr: &pkgConfig.Version,
},
{
path: []string{"license"},
ptr: &pkgConfig.License,
},
{
path: []string{"description"},
ptr: &pkgConfig.Description,
},
{
path: []string{"homepage"},
ptr: &pkgConfig.Homepage,
},
{
path: []string{"main"},
ptr: &pkgConfig.Main,
},
{
path: []string{"engines", "node"},
ptr: &pkgConfig.Engines.Node,
},
{
path: []string{"engines", "npm"},
ptr: &pkgConfig.Engines.Npm,
},
{
path: []string{"repository"},
ptr: &pkgConfig.Repository.SingleLine,
},
{
path: []string{"repository", "type"},
ptr: &pkgConfig.Repository.Type,
},
{
path: []string{"repository", "url"},
ptr: &pkgConfig.Repository.Url,
},
{
path: []string{"author"},
ptr: &pkgConfig.Author.SingleLine,
},
{
path: []string{"author", "email"},
ptr: &pkgConfig.Author.Email,
},
{
path: []string{"author", "name"},
ptr: &pkgConfig.Author.Name,
},
{
path: []string{"author", "url"},
ptr: &pkgConfig.Author.Url,
},
{
path: []string{"bugs"},
ptr: &pkgConfig.Bugs.Url,
},
{
path: []string{"bugs", "url"},
ptr: &pkgConfig.Bugs.Url,
},
},
)

for _, mapping := range []struct {
field string
ptr *bool
}{
{
field: "deprecated",
ptr: &pkgConfig.Deprecated,
},
{
field: "private",
ptr: &pkgConfig.Private,
},
} {
value, err := jsonparser.GetBoolean(configData, mapping.field)
if err == nil {
*mapping.ptr = value
}
}

for _, mapping := range []struct {
field string
ptr *[]string
}{
{
field: "files",
ptr: &pkgConfig.Files,
},
{
field: "keywords",
ptr: &pkgConfig.Keywords,
},
{
field: "os",
ptr: &pkgConfig.Os,
},
{
field: "cpu",
ptr: &pkgConfig.Cpu,
},
{
field: "bundleDependencies",
ptr: &pkgConfig.BundledDependencies,
},
{
// both this spelling and the spelling above are honoured
field: "bundledDependencies",
ptr: &pkgConfig.BundledDependencies,
},
} {
value, dataType, _, err := jsonparser.Get(configData, mapping.field)
if err != nil {
if err == jsonparser.KeyPathNotFoundError {
continue
}
return nil, err
}
switch dataType {
case jsonparser.Array:
_, _ = jsonparser.ArrayEach(value, func(innerValue []byte, dataType jsonparser.ValueType, offset int, err error) {
if dataType == jsonparser.String {
*mapping.ptr = append(*mapping.ptr, unescape(innerValue))
}
})
case jsonparser.String:
*mapping.ptr = append(*mapping.ptr, string(value))
}
}

for _, mapping := range []struct {
field string
ptr *map[string]string
}{
{
field: "scripts",
ptr: &pkgConfig.Scripts,
},
{
field: "directories",
ptr: &pkgConfig.Directories,
},
{
field: "dependencies",
ptr: &pkgConfig.Dependencies,
},
{
field: "devDependencies",
ptr: &pkgConfig.DevDependencies,
},
{
field: "peerDependencies",
ptr: &pkgConfig.PeerDependencies,
},
{
field: "optionalDependencies",
ptr: &pkgConfig.OptionalDependencies,
},
} {
value, dataType, _, err := jsonparser.Get(configData, mapping.field)
if err != nil {
if err == jsonparser.KeyPathNotFoundError {
continue
}
return nil, err
}
switch dataType {
case jsonparser.Object:
_ = jsonparser.ObjectEach(value, func(key []byte, innerValue []byte, dataType jsonparser.ValueType, offset int) error {
if dataType == jsonparser.String {
if *mapping.ptr == nil {
*mapping.ptr = map[string]string{}
}
(*mapping.ptr)[string(key)] = unescape(innerValue)
}
return nil
})
}
}
value, dataType, _, err := jsonparser.Get(configData, "contributors")
if err != nil {
if err != jsonparser.KeyPathNotFoundError {
return nil, err
}
} else {
switch dataType {
case jsonparser.Array:
_, _ = jsonparser.ArrayEach(value, func(innerValue []byte, dataType jsonparser.ValueType, offset int, err error) {
switch dataType {
case jsonparser.String:
pkgConfig.Contributors = append(pkgConfig.Contributors, Author{SingleLine: unescape(innerValue)})
case jsonparser.Object:
contributor := Author{}
parseStrings(innerValue,
[]stringMapping{
{
path: []string{""},
ptr: &contributor.SingleLine,
},
{
path: []string{"email"},
ptr: &contributor.Email,
},
{
path: []string{"name"},
ptr: &contributor.Name,
},
{
path: []string{"url"},
ptr: &contributor.Url,
},
},
)
pkgConfig.Contributors = append(pkgConfig.Contributors, contributor)
}
})
}
}

return pkgConfig, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestUnmarshalPackageConfig(t *testing.T) {
scenarios := []scenario{
{
"1.json",
&PackageConfig{Name: "body", Version: "5.1.0", License: "", Private: false, Description: "Body parsing", Files: []string(nil), Keywords: []string{}, Os: []string(nil), Cpu: []string(nil), Main: "index", Engines: struct {
&PackageConfig{Name: "body", Version: "5.1.0", License: "", Private: false, Description: "Body parsing", Files: []string(nil), Keywords: nil, Os: []string(nil), Cpu: []string(nil), Main: "index", Engines: struct {
Node string
Npm string
}{Node: "", Npm: ""}, Scripts: map[string]string{"test": "node ./test/index.js"}, Repository: Repository{Type: "", Url: "", SingleLine: "git://github.com/Raynos/body.git"}, Author: Author{Name: "", Email: "", Url: "", SingleLine: "Raynos <raynos2@gmail.com>"}, Contributors: []Author{Author{Name: "Jake Verbaten", Email: "", Url: "", SingleLine: ""}}, Bugs: struct {
Expand All @@ -29,7 +29,7 @@ func TestUnmarshalPackageConfig(t *testing.T) {
&PackageConfig{Name: "lodash", Version: "4.17.5", License: "MIT", Private: false, Description: "Lodash modular utilities.", Files: []string(nil), Keywords: []string{"modules, stdlib, util"}, Os: []string(nil), Cpu: []string(nil), Main: "lodash.js", Engines: struct {
Node string
Npm string
}{Node: "", Npm: ""}, Scripts: map[string]string{"test": "echo \"See https://travis-ci.org/lodash-archive/lodash-cli for testing details.\""}, Repository: Repository{Type: "", Url: "", SingleLine: "lodash/lodash"}, Author: Author{Name: "", Email: "", Url: "", SingleLine: "John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)"}, Contributors: []Author{Author{Name: "", Email: "", Url: "", SingleLine: "John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)"}, Author{Name: "", Email: "", Url: "", SingleLine: "Mathias Bynens <mathias@qiwi.be> (https://mathiasbynens.be/)"}}, Bugs: struct {
}{Node: "", Npm: ""}, Scripts: map[string]string{"test": `echo "See https://travis-ci.org/lodash-archive/lodash-cli for testing details."`}, Repository: Repository{Type: "", Url: "", SingleLine: "lodash/lodash"}, Author: Author{Name: "", Email: "", Url: "", SingleLine: "John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)"}, Contributors: []Author{Author{Name: "", Email: "", Url: "", SingleLine: "John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)"}, Author{Name: "", Email: "", Url: "", SingleLine: "Mathias Bynens <mathias@qiwi.be> (https://mathiasbynens.be/)"}}, Bugs: struct {
Url string "json:\"url\""
}{Url: ""}, Deprecated: false, Homepage: "https://lodash.com/", Directories: map[string]string(nil), Dependencies: map[string]string(nil), DevDependencies: map[string]string(nil), PeerDependencies: map[string]string(nil), OptionalDependencies: map[string]string(nil), BundledDependencies: []string(nil)},
},
Expand All @@ -44,12 +44,12 @@ func TestUnmarshalPackageConfig(t *testing.T) {
},
{
"4.json",
&PackageConfig{Name: "moment-range", Version: "2.2.0", License: "", Private: false, Description: "Fancy date ranges for Moment.js", Files: []string(nil), Keywords: []string(nil), Os: []string(nil), Cpu: []string(nil), Main: "./dist/moment-range", Engines: struct {
&PackageConfig{Name: "@activepipe/stylelint-colorvars-check", Version: "1.0.7", License: "ISC", Description: "Stylelint rules to ensure color variables have been declared using an @value statement", Homepage: "", Main: "index.js", Deprecated: false, Private: false, Files: []string(nil), Keywords: []string(nil), Os: []string(nil), Cpu: []string(nil), BundledDependencies: []string(nil), Scripts: map[string]string{"test": "echo \"Error: no test specified\" && exit 1"}, Directories: map[string]string(nil), Dependencies: map[string]string(nil), DevDependencies: map[string]string(nil), PeerDependencies: map[string]string(nil), OptionalDependencies: map[string]string(nil), Engines: struct {
Node string
Npm string
}{Node: "*", Npm: ""}, Scripts: map[string]string{"build": "grunt es6transpiler replace umd uglify", "jsdoc": "jsdoc -c .jsdoc", "test": "grunt mochaTest"}, Repository: Repository{Type: "git", Url: "https://git@github.com/gf3/moment-range.git", SingleLine: ""}, Author: Author{Name: "", Email: "", Url: "", SingleLine: "Gianni Chiappetta <gianni@runlevel6.org> (http://butt.zone)"}, Contributors: []Author{Author{Name: "", Email: "", Url: "", SingleLine: "Adam Biggs <adam.biggs@lightmaker.com>"}, Author{Name: "", Email: "", Url: "", SingleLine: "Matt Patterson <matt@reprocessed.org> (http://reprocessed.org/)"}, Author{Name: "", Email: "", Url: "", SingleLine: "Stuart Kelly <stuart.leigh83@gmail.com>"}, Author{Name: "", Email: "", Url: "", SingleLine: "Kevin Ross <kevin.ross@alienfast.com> (http://www.alienfast.com)"}, Author{Name: "", Email: "", Url: "", SingleLine: "Scott Hovestadt <scott.hovestadt@gmail.com>"}, Author{Name: "", Email: "", Url: "", SingleLine: "Nebel <nebel08@gmail.com>"}, Author{Name: "", Email: "", Url: "", SingleLine: "Aristide Niyungeko <niyungeko@gmail.com>"}, Author{Name: "", Email: "", Url: "", SingleLine: "Tymon Tobolski <i@teamon.eu> (http://teamon.eu)"}, Author{Name: "", Email: "", Url: "", SingleLine: "Bradley Ayers <bradley.ayers@gmail.com>"}, Author{Name: "", Email: "", Url: "", SingleLine: "Thomas Walpole <twalpole@gmail.com>"}, Author{Name: "", Email: "", Url: "", SingleLine: "Daniel Sarfati <daniel@knockrentals.com>"}}, Bugs: struct {
}{Node: "", Npm: ""}, Repository: Repository{Type: "", Url: "", SingleLine: ""}, Author: Author{Name: "John McClumpha", Email: "john@activepipe.com", Url: "", SingleLine: ""}, Contributors: []Author(nil), Bugs: struct {
Url string "json:\"url\""
}{Url: "https://github.com/gf3/moment-range/issues"}, Deprecated: false, Homepage: "https://github.com/gf3/moment-range", Directories: map[string]string{"lib": "./lib"}, Dependencies: map[string]string(nil), DevDependencies: map[string]string{"grunt": "~0.4.1", "grunt-cli": "^0.1.13", "grunt-contrib-uglify": "^0.6.0", "grunt-es6-transpiler": "^1.0.2", "grunt-mocha-test": "~0.7.0", "grunt-text-replace": "^0.4.0", "grunt-umd": "^2.3.3", "jsdoc": "^3.3.0", "mocha": "^2.1.0", "moment": ">= 1", "should": "^5.0.1"}, PeerDependencies: map[string]string{"moment": ">= 1"}, OptionalDependencies: map[string]string(nil), BundledDependencies: []string(nil)},
}{Url: ""}},
},
}

Expand Down
Loading

0 comments on commit f119ee6

Please sign in to comment.