diff options
author | Dan Willemsen <dwillemsen@google.com> | 2015-09-23 15:26:20 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@google.com> | 2015-12-09 14:29:12 -0800 |
commit | 34cc69e4bf36cb65bb181b42ccb0f8c792a32cfb (patch) | |
tree | ecaff919037e29033fa9b3bbfb33baa8e93196cf /common/paths_test.go | |
parent | fafa3dc7e267675610a34b0c335be350eb30936d (diff) | |
download | build_soong-34cc69e4bf36cb65bb181b42ccb0f8c792a32cfb.tar.gz build_soong-34cc69e4bf36cb65bb181b42ccb0f8c792a32cfb.tar.bz2 build_soong-34cc69e4bf36cb65bb181b42ccb0f8c792a32cfb.zip |
Use `Path` instead of string for file paths
This centralizes verification and common operations, like converting the
path to a source file to the path for a built object.
It also embeds the configuration knowledge into the path, so that we can
remove "${SrcDir}/path" from the ninja file. When SrcDir is '.', that
leads to paths like './path' instead of just 'path' like make is doing,
causing differences in compiled binaries.
Change-Id: Ib4e8910a6e867ce1b7b420d927c04f1142a7589e
Diffstat (limited to 'common/paths_test.go')
-rw-r--r-- | common/paths_test.go | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/common/paths_test.go b/common/paths_test.go new file mode 100644 index 00000000..16ede0d2 --- /dev/null +++ b/common/paths_test.go @@ -0,0 +1,167 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package common + +import ( + "errors" + "fmt" + "reflect" + "strings" + "testing" +) + +type strsTestCase struct { + in []string + out string + err []error +} + +var commonValidatePathTestCases = []strsTestCase{ + { + in: []string{""}, + out: "", + }, + { + in: []string{"a/b"}, + out: "a/b", + }, + { + in: []string{"a/b", "c"}, + out: "a/b/c", + }, + { + in: []string{"a/.."}, + out: ".", + }, + { + in: []string{"."}, + out: ".", + }, + { + in: []string{".."}, + out: "", + err: []error{errors.New("Path is outside directory: ..")}, + }, + { + in: []string{"../a"}, + out: "", + err: []error{errors.New("Path is outside directory: ../a")}, + }, + { + in: []string{"b/../../a"}, + out: "", + err: []error{errors.New("Path is outside directory: ../a")}, + }, + { + in: []string{"/a"}, + out: "", + err: []error{errors.New("Path is outside directory: /a")}, + }, +} + +var validateSafePathTestCases = append(commonValidatePathTestCases, []strsTestCase{ + { + in: []string{"$host/../$a"}, + out: "$a", + }, +}...) + +var validatePathTestCases = append(commonValidatePathTestCases, []strsTestCase{ + { + in: []string{"$host/../$a"}, + out: "", + err: []error{errors.New("Path contains invalid character($): $host/../$a")}, + }, + { + in: []string{"$host/.."}, + out: "", + err: []error{errors.New("Path contains invalid character($): $host/..")}, + }, +}...) + +func TestValidateSafePath(t *testing.T) { + for _, testCase := range validateSafePathTestCases { + ctx := &configErrorWrapper{} + out := validateSafePath(ctx, testCase.in...) + check(t, "validateSafePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err) + } +} + +func TestValidatePath(t *testing.T) { + for _, testCase := range validatePathTestCases { + ctx := &configErrorWrapper{} + out := validatePath(ctx, testCase.in...) + check(t, "validatePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err) + } +} + +func TestOptionalPath(t *testing.T) { + var path OptionalPath + checkInvalidOptionalPath(t, path) + + path = OptionalPathForPath(nil) + checkInvalidOptionalPath(t, path) +} + +func checkInvalidOptionalPath(t *testing.T, path OptionalPath) { + if path.Valid() { + t.Errorf("Uninitialized OptionalPath should not be valid") + } + if path.String() != "" { + t.Errorf("Uninitialized OptionalPath String() should return \"\", not %q", path.String()) + } + defer func() { + if r := recover(); r == nil { + t.Errorf("Expected a panic when calling Path() on an uninitialized OptionalPath") + } + }() + path.Path() +} + +func check(t *testing.T, testType, testString string, + got interface{}, err []error, + expected interface{}, expectedErr []error) { + + printedTestCase := false + e := func(s string, expected, got interface{}) { + if !printedTestCase { + t.Errorf("test case %s: %s", testType, testString) + printedTestCase = true + } + t.Errorf("incorrect %s", s) + t.Errorf(" expected: %s", p(expected)) + t.Errorf(" got: %s", p(got)) + } + + if !reflect.DeepEqual(expectedErr, err) { + e("errors:", expectedErr, err) + } + + if !reflect.DeepEqual(expected, got) { + e("output:", expected, got) + } +} + +func p(in interface{}) string { + if v, ok := in.([]interface{}); ok { + s := make([]string, len(v)) + for i := range v { + s[i] = fmt.Sprintf("%#v", v[i]) + } + return "[" + strings.Join(s, ", ") + "]" + } else { + return fmt.Sprintf("%#v", in) + } +} |