github.com/joomcode/cue@v0.4.4-0.20221111115225-539fe3512047/internal/cuetest/cuetest.go (about) 1 // Copyright 2021 The CUE Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package testing is a helper package for test packages in the CUE project. 16 // As such it should only be imported in _test.go files. 17 package cuetest 18 19 import ( 20 "fmt" 21 "os" 22 "regexp" 23 "testing" 24 ) 25 26 const ( 27 // envUpdate is used in the definition of UpdateGoldenFiles 28 envUpdate = "CUE_UPDATE" 29 30 // envNonIssues can be set to a regular expression which indicates what 31 // issues we no longer consider issues, i.e. they should have been fixed. 32 // This should generally result in tests that would otherwise be skipped no 33 // longer being skipped. e.g. CUE_NON_ISSUES=. will cause all issue 34 // tracker conditions (e.g. [golang.org/issues/1234]) to be considered 35 // non-issues. 36 envNonIssues = "CUE_NON_ISSUES" 37 38 envFormatTxtar = "CUE_FORMAT_TXTAR" 39 ) 40 41 var ( 42 // issuesConditions is a set of regular expressions that defines the set of 43 // conditions that can be used to declare links to issues in various issue 44 // trackers. e.g. in testscript condition form 45 // 46 // [golang.org/issues/1234] 47 // [github.com/govim/govim/issues/4321] 48 issuesConditions = []*regexp.Regexp{ 49 regexp.MustCompile(`^golang\.org/issues?/\d+$`), 50 regexp.MustCompile(`^cuelang\.org/issues?/\d+$`), 51 } 52 ) 53 54 // UpdateGoldenFiles determines whether testscript scripts should update txtar 55 // archives in the event of cmp failures. It corresponds to 56 // testscript.Params.UpdateGoldenFiles. See the docs for 57 // testscript.Params.UpdateGoldenFiles for more details. 58 var UpdateGoldenFiles = os.Getenv(envUpdate) != "" 59 60 // FormatTxtar ensures that .cue files in txtar test archives are well 61 // formatted, updating the archive as required prior to running a test. 62 var FormatTxtar = os.Getenv(envFormatTxtar) != "" 63 64 // Condition adds support for CUE-specific testscript conditions within 65 // testscript scripts. Supported conditions include: 66 // 67 // [long] - evalutates to true when the long build tag is specified 68 // 69 // [golang.org/issue/N] - evaluates to true unless CUE_NON_ISSUES 70 // is set to a regexp that matches the condition, i.e. golang.org/issue/N 71 // in this case 72 // 73 // [cuelang.org/issue/N] - evaluates to true unless CUE_NON_ISSUES 74 // is set to a regexp that matches the condition, i.e. cuelang.org/issue/N 75 // in this case 76 // 77 func Condition(cond string) (bool, error) { 78 isIssue, nonIssue, err := checkIssueCondition(cond) 79 if err != nil { 80 return false, err 81 } 82 if isIssue { 83 return !nonIssue, nil 84 } 85 switch cond { 86 case "long": 87 return Long, nil 88 } 89 return false, fmt.Errorf("unknown condition %v", cond) 90 } 91 92 // IssueSkip causes the test t to be skipped unless the issue identified 93 // by s is deemed to be a non-issue by CUE_NON_ISSUES. 94 func IssueSkip(t *testing.T, s string) { 95 isIssue, nonIssue, err := checkIssueCondition(s) 96 if err != nil { 97 t.Fatal(err) 98 } 99 if !isIssue { 100 t.Fatalf("issue %q does not match a known issue pattern", s) 101 } 102 if nonIssue { 103 t.Skipf("issue %s", s) 104 } 105 } 106 107 // checkIssueCondition examines s to determine whether it is an issue 108 // condition, in which case isIssue is true. If isIssue, then we check 109 // CUE_NON_ISSUES for a match, in which case nonIssue is true (a value of true 110 // indicates roughly that we don't believe issue s is an issue any more). In 111 // case of any errors err is set. 112 func checkIssueCondition(s string) (isIssue bool, nonIssue bool, err error) { 113 var r *regexp.Regexp 114 if v := os.Getenv(envNonIssues); v != "" { 115 r, err = regexp.Compile(v) 116 if err != nil { 117 return false, false, fmt.Errorf("failed to compile regexp %q specified via %v: %v", v, envNonIssues, err) 118 } 119 } 120 for _, c := range issuesConditions { 121 if c.MatchString(s) { 122 isIssue = true 123 } 124 } 125 if !isIssue { 126 return false, false, nil 127 } 128 return isIssue, r != nil && r.MatchString(s), nil 129 }