-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Validate script arguments If a user provides unknown arguments to a script this is silently ignored. This can lead to time consuming typos, e.g. 'versoin' instead of 'version'. This change set ensures that no unknown arguments can be applied to a script. It also detects all errors before stopping execution so unknown arguments, missing required arguments and non-parsable arguments are reported in one go. $ shuttle --project examples/moon-base run required-arg b=1 d shuttle failed Arguments not valid: 'd' not <argument>=<value> 'a' not supplied but is required 'b' unknown Script 'required-arg' accepts the following arguments: a (required) Lastly acceptable arguments are printed on any of the above errors to help users detect their mistakes fast. * Sort validation errors for consitent output
- Loading branch information
1 parent
ca3b5b4
commit c68e9b7
Showing
4 changed files
with
266 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
package executors | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/lunarway/shuttle/pkg/config" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestValidateUnknownArgs(t *testing.T) { | ||
tt := []struct { | ||
name string | ||
scriptArgs []config.ShuttleScriptArgs | ||
inputArgs map[string]string | ||
output []validationError | ||
}{ | ||
{ | ||
name: "no input or script", | ||
scriptArgs: nil, | ||
inputArgs: nil, | ||
output: nil, | ||
}, | ||
{ | ||
name: "single input without script", | ||
scriptArgs: nil, | ||
inputArgs: map[string]string{ | ||
"foo": "1", | ||
}, | ||
output: []validationError{ | ||
{"foo", "unknown"}, | ||
}, | ||
}, | ||
{ | ||
name: "multiple input without script", | ||
scriptArgs: nil, | ||
inputArgs: map[string]string{ | ||
"foo": "1", | ||
"bar": "2", | ||
}, | ||
output: []validationError{ | ||
{"bar", "unknown"}, | ||
{"foo", "unknown"}, | ||
}, | ||
}, | ||
{ | ||
name: "single input and script", | ||
scriptArgs: []config.ShuttleScriptArgs{ | ||
{ | ||
Name: "foo", | ||
}, | ||
}, | ||
inputArgs: map[string]string{ | ||
"foo": "1", | ||
}, | ||
output: nil, | ||
}, | ||
{ | ||
name: "multple input and script", | ||
scriptArgs: []config.ShuttleScriptArgs{ | ||
{ | ||
Name: "foo", | ||
}, | ||
{ | ||
Name: "bar", | ||
}, | ||
}, | ||
inputArgs: map[string]string{ | ||
"bar": "2", | ||
"foo": "1", | ||
}, | ||
output: nil, | ||
}, | ||
{ | ||
name: "multple input and script with one unknown", | ||
scriptArgs: []config.ShuttleScriptArgs{ | ||
{ | ||
Name: "foo", | ||
}, | ||
{ | ||
Name: "bar", | ||
}, | ||
}, | ||
inputArgs: map[string]string{ | ||
"foo": "1", | ||
"bar": "2", | ||
"baz": "3", | ||
}, | ||
output: []validationError{ | ||
{"baz", "unknown"}, | ||
}, | ||
}, | ||
} | ||
for _, tc := range tt { | ||
t.Run(tc.name, func(t *testing.T) { | ||
output := validateUnknownArgs(tc.scriptArgs, tc.inputArgs) | ||
// sort as the order is not guarenteed by validateUnknownArgs | ||
sortValidationErrors(output) | ||
assert.Equal(t, tc.output, output, "output not as expected") | ||
}) | ||
} | ||
} | ||
|
||
func TestSortValidationErrors(t *testing.T) { | ||
tt := []struct { | ||
name string | ||
input []validationError | ||
output []validationError | ||
}{ | ||
{ | ||
name: "sorted", | ||
input: []validationError{ | ||
{"bar", ""}, | ||
{"baz", ""}, | ||
{"foo", ""}, | ||
}, | ||
output: []validationError{ | ||
{"bar", ""}, | ||
{"baz", ""}, | ||
{"foo", ""}, | ||
}, | ||
}, | ||
{ | ||
name: "not sorted", | ||
input: []validationError{ | ||
{"baz", ""}, | ||
{"foo", ""}, | ||
{"bar", ""}, | ||
}, | ||
output: []validationError{ | ||
{"bar", ""}, | ||
{"baz", ""}, | ||
{"foo", ""}, | ||
}, | ||
}, | ||
} | ||
for _, tc := range tt { | ||
t.Run(tc.name, func(t *testing.T) { | ||
sortValidationErrors(tc.input) | ||
assert.Equal(t, tc.output, tc.input, "output not as expected") | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters