Skip to content

Commit

Permalink
Updated core functions to render descriptions #247
Browse files Browse the repository at this point in the history
When looking at a support request, feeding in the fixed JSONPath, resulted in an unhelpful message:

`'' is falsy'`

This is because some of the core functions are missing the rule description from being rendered. This update fixes those rules missing that context.
  • Loading branch information
daveshanley committed Mar 8, 2023
1 parent aff7a3f commit fb8b20e
Show file tree
Hide file tree
Showing 13 changed files with 89 additions and 10 deletions.
11 changes: 10 additions & 1 deletion functions/core/casing.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,17 @@ func (c Casing) RunRule(nodes []*yaml.Node, context model.RuleFunctionContext) [

rx := regexp.MustCompile(leadingPattern)
if !rx.MatchString(nodes[0].Value) {

var msg string
if context.Rule.Description != "" {
msg = fmt.Sprintf("%s: '%s' is not %s case!", context.Rule.Description,
nodes[0].Value, casingType)
} else {
msg = fmt.Sprintf("'%s' is not %s case!", nodes[0].Value, casingType)
}

results = append(results, model.RuleFunctionResult{
Message: fmt.Sprintf("'%s' is not %s case!", nodes[0].Value, casingType),
Message: msg,
StartNode: nodes[0],
EndNode: nodes[0],
Path: pathValue,
Expand Down
19 changes: 19 additions & 0 deletions functions/core/casing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ func TestCasing_RunRule_CamelSuccess(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule
ctx.Rule = &rule

def := &Casing{}
res := def.RunRule(nodes, ctx)
Expand All @@ -44,6 +46,7 @@ func TestCasing_RunRule_CamelFail(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule
def := &Casing{}
res := def.RunRule(nodes, ctx)

Expand All @@ -65,6 +68,7 @@ func TestCasing_RunRule_PascalSuccess(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule
def := &Casing{}
res := def.RunRule(nodes, ctx)

Expand All @@ -86,6 +90,7 @@ func TestCasing_RunRule_PascalFail(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := &Casing{}
res := def.RunRule(nodes, ctx)
Expand All @@ -108,6 +113,7 @@ func TestCasing_RunRule_KebabSuccess(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := &Casing{}
res := def.RunRule(nodes, ctx)
Expand All @@ -130,6 +136,7 @@ func TestCasing_RunRule_KebabFail(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := &Casing{}
res := def.RunRule(nodes, ctx)
Expand All @@ -152,6 +159,7 @@ func TestCasing_RunRule_CobolSuccess(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := &Casing{}
res := def.RunRule(nodes, ctx)
Expand All @@ -174,6 +182,7 @@ func TestCasing_RunRule_CobolFail(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := &Casing{}
res := def.RunRule(nodes, ctx)
Expand All @@ -196,6 +205,7 @@ func TestCasing_RunRule_SnakeSuccess(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := &Casing{}
res := def.RunRule(nodes, ctx)
Expand All @@ -218,6 +228,7 @@ func TestCasing_RunRule_SnakeFail(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := &Casing{}
res := def.RunRule(nodes, ctx)
Expand All @@ -240,6 +251,7 @@ func TestCasing_RunRule_MacroSuccess(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := &Casing{}
res := def.RunRule(nodes, ctx)
Expand All @@ -262,6 +274,7 @@ func TestCasing_RunRule_MacroFail(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := &Casing{}
res := def.RunRule(nodes, ctx)
Expand All @@ -285,6 +298,7 @@ func TestCasing_RunRule_CamelNoDigits_Success(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := &Casing{}
res := def.RunRule(nodes, ctx)
Expand All @@ -308,6 +322,7 @@ func TestCasing_RunRule_CamelNoDigits_Fail(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := &Casing{}
res := def.RunRule(nodes, ctx)
Expand All @@ -331,6 +346,7 @@ func TestCasing_RunRule_Snake_SeparatingChar_Success(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := &Casing{}
res := def.RunRule(nodes, ctx)
Expand All @@ -354,6 +370,7 @@ func TestCasing_RunRule_Snake_SeparatingChar_Fail(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := &Casing{}
res := def.RunRule(nodes, ctx)
Expand All @@ -378,6 +395,7 @@ func TestCasing_RunRule_Snake_AllowLeading_Success(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := &Casing{}
res := def.RunRule(nodes, ctx)
Expand All @@ -402,6 +420,7 @@ func TestCasing_RunRule_Snake_AllowLeading_Fail(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "casing", "", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := &Casing{}
res := def.RunRule(nodes, ctx)
Expand Down
6 changes: 4 additions & 2 deletions functions/core/core_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import "github.com/daveshanley/vacuum/model"

func buildCoreTestRule(given, severity, function, field string, functionOptions map[string]string) model.Rule {
return model.Rule{
Given: given,
Severity: severity,
Given: given,
Severity: severity,
Description: "test rule",
Then: &model.RuleAction{
Field: field,
Function: function,
Expand All @@ -24,6 +25,7 @@ func buildCoreTestContext(action *model.RuleAction, options map[string]string) m
func buildCoreTestContextFromRule(action *model.RuleAction, rule model.Rule) model.RuleFunctionContext {
ruleAction := model.CastToRuleAction(rule.Then)
return model.RuleFunctionContext{
Rule: &rule,
RuleAction: action,
Options: ruleAction.FunctionOptions,
}
Expand Down
9 changes: 8 additions & 1 deletion functions/core/defined.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,15 @@ func (d Defined) RunRule(nodes []*yaml.Node, context model.RuleFunctionContext)
for _, node := range nodes {
fieldNode, _ := utils.FindKeyNode(context.RuleAction.Field, node.Content)
if fieldNode == nil {

var msg string
if context.Rule.Description != "" {
msg = fmt.Sprintf("%s: '%s' must be defined", context.Rule.Description, context.RuleAction.Field)
} else {
msg = fmt.Sprintf("'%s' must be defined", context.RuleAction.Field)
}
results = append(results, model.RuleFunctionResult{
Message: fmt.Sprintf("'%s' must be defined", context.RuleAction.Field),
Message: msg,
StartNode: node,
EndNode: node,
Path: pathValue,
Expand Down
2 changes: 2 additions & 0 deletions functions/core/defined_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func TestDefined_RunRule_Success(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "defined", "cake", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), nil)
ctx.Given = path
ctx.Rule = &rule

def := Defined{}
res := def.RunRule(nodes, ctx)
Expand All @@ -51,6 +52,7 @@ func TestDefined_RunRule_Fail(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "defined", "cake", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), nil)
ctx.Given = path
ctx.Rule = &rule

def := Defined{}
res := def.RunRule(nodes, ctx)
Expand Down
9 changes: 8 additions & 1 deletion functions/core/enumeration.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,15 @@ func (e Enumeration) RunRule(nodes []*yaml.Node, context model.RuleFunctionConte

for _, node := range nodes {
if !e.checkValueAgainstAllowedValues(node.Value, values) {
var msg string
if context.Rule.Description != "" {
msg = fmt.Sprintf("%s: '%s' must equal to one of the following: %v", context.Rule.Description,
node.Value, values)
} else {
msg = fmt.Sprintf("'%s' must equal to one of the following: %v", node.Value, values)
}
results = append(results, model.RuleFunctionResult{
Message: fmt.Sprintf("'%s' must equal to one of the following: %v", node.Value, values),
Message: msg,
StartNode: node,
EndNode: node,
Path: pathValue,
Expand Down
3 changes: 3 additions & 0 deletions functions/core/enumeration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func TestEnumeration_RunRule_Success(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "pattern", "", opts)
ctx := buildCoreTestContextFromRule(model.CastToRuleAction(rule.Then), rule)
ctx.Given = path
ctx.Rule = &rule

def := &Enumeration{}
res := def.RunRule(nodes, ctx)
Expand All @@ -50,6 +51,7 @@ func TestEnumeration_RunRule_Fail(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "enumeration", "", opts)
ctx := buildCoreTestContextFromRule(model.CastToRuleAction(rule.Then), rule)
ctx.Given = path
ctx.Rule = &rule

def := &Enumeration{}
res := def.RunRule(nodes, ctx)
Expand All @@ -68,6 +70,7 @@ func TestEnumeration_RunRule_FalseFail(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "enumeration", "", opts)
ctx := buildCoreTestContextFromRule(model.CastToRuleAction(rule.Then), rule)
ctx.Given = path
ctx.Rule = &rule

def := &Enumeration{}
res := def.RunRule(nodes, ctx)
Expand Down
9 changes: 8 additions & 1 deletion functions/core/falsy.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,15 @@ func (f Falsy) RunRule(nodes []*yaml.Node, context model.RuleFunctionContext) []
fieldNode, fieldNodeValue := utils.FindKeyNode(context.RuleAction.Field, node.Content)
if (fieldNode != nil && fieldNodeValue != nil) &&
(fieldNodeValue.Value != "" && fieldNodeValue.Value != "false" || fieldNodeValue.Value != "0") {
var msg string
if context.RuleAction.Field != "" {
msg = fmt.Sprintf("%s: '%s' must be falsy", context.Rule.Description, context.RuleAction.Field)
} else {
msg = fmt.Sprintf("%s: property must be falsy", context.Rule.Description)
}

results = append(results, model.RuleFunctionResult{
Message: fmt.Sprintf("'%s' must be falsy", context.RuleAction.Field),
Message: msg,
StartNode: node,
EndNode: node,
Path: pathValue,
Expand Down
3 changes: 3 additions & 0 deletions functions/core/falsy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ tags:
rule := buildCoreTestRule(path, model.SeverityError, "falsy", "description", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), nil)
ctx.Given = path
ctx.Rule = &rule

tru := Falsy{}
res := tru.RunRule(nodes, ctx)
Expand Down Expand Up @@ -54,6 +55,7 @@ notTags:
rule := buildCoreTestRule(path, model.SeverityError, "falsy", "description", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), nil)
ctx.Given = path
ctx.Rule = &rule

tru := Falsy{}
res := tru.RunRule(nodes, ctx)
Expand All @@ -80,6 +82,7 @@ tags:
rule := buildCoreTestRule(path, model.SeverityError, "Falsy", "description", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), nil)
ctx.Given = path
ctx.Rule = &rule

tru := Falsy{}
res := tru.RunRule(nodes, ctx)
Expand Down
9 changes: 8 additions & 1 deletion functions/core/undefined.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,15 @@ func (u Undefined) RunRule(nodes []*yaml.Node, context model.RuleFunctionContext

fieldNode, _ := utils.FindKeyNode(context.RuleAction.Field, node.Content)
if fieldNode != nil {

var msg string
if context.Rule.Description != "" {
msg = fmt.Sprintf("%s: '%s' must be undefined", context.Rule.Description, context.RuleAction.Field)
} else {
msg = fmt.Sprintf("'%s' must be undefined", context.RuleAction.Field)
}
results = append(results, model.RuleFunctionResult{
Message: fmt.Sprintf("'%s' must be undefined", context.RuleAction.Field),
Message: msg,
StartNode: fieldNode,
EndNode: fieldNode,
Path: pathValue,
Expand Down
2 changes: 2 additions & 0 deletions functions/core/undefined_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func TestUndefined_RunRule_Success(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "undefined", "cake", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), nil)
ctx.Given = path
ctx.Rule = &rule

def := Undefined{}
res := def.RunRule(nodes, ctx)
Expand All @@ -51,6 +52,7 @@ func TestUndefined_RunRule_Fail(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "undefined", "cake", nil)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), nil)
ctx.Given = path
ctx.Rule = &rule

def := Undefined{}
res := def.RunRule(nodes, ctx)
Expand Down
12 changes: 9 additions & 3 deletions functions/core/xor.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,22 @@ func (x Xor) RunRule(nodes []*yaml.Node, context model.RuleFunctionContext) []mo
}

if seenCount != 1 {
var msg string
if context.Rule.Description != "" {
msg = fmt.Sprintf("%s: '%s' and '%s' must not be both defined or undefined",
context.Rule.Description, properties[0], properties[1])
} else {
msg = fmt.Sprintf("'%s' and '%s' must not be both defined or undefined",
properties[0], properties[1])
}
results = append(results, model.RuleFunctionResult{
Message: fmt.Sprintf("'%s' and '%s' must not be both defined or undefined",
properties[0], properties[1]),
Message: msg,
StartNode: node,
EndNode: node,
Path: pathValue,
Rule: context.Rule,
})
}

}

return results
Expand Down
5 changes: 5 additions & 0 deletions functions/core/xor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func TestXor_RunRule_SuccessPropsStringArray(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "xor", "", nil)
ctx := model.RuleFunctionContext{RuleAction: model.CastToRuleAction(rule.Then), Rule: &rule, Options: opts}
ctx.Given = path
ctx.Rule = &rule

def := Xor{}
res := def.RunRule(nodes, ctx)
Expand All @@ -54,6 +55,7 @@ func TestXor_RunRule_Success(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "xor", "", opts)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := Xor{}
res := def.RunRule(nodes, ctx)
Expand All @@ -77,6 +79,7 @@ func TestXor_RunRule_NoProps(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "xor", "", opts)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := Xor{}
res := def.RunRule(nodes, ctx)
Expand All @@ -101,6 +104,7 @@ func TestXor_RunRule_Fail(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "xor", "", opts)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := Xor{}
res := def.RunRule(nodes, ctx)
Expand All @@ -125,6 +129,7 @@ func TestXor_RunRule_Fail_AllUndefined(t *testing.T) {
rule := buildCoreTestRule(path, model.SeverityError, "xor", "", opts)
ctx := buildCoreTestContext(model.CastToRuleAction(rule.Then), opts)
ctx.Given = path
ctx.Rule = &rule

def := Xor{}
res := def.RunRule(nodes, ctx)
Expand Down

0 comments on commit fb8b20e

Please sign in to comment.