Skip to content

Commit

Permalink
fix: add "/" op and fix special cases in schema (#122)
Browse files Browse the repository at this point in the history
After @thisthat noticed I was missing "/", I added a test that with a
massive targeting rule that doesn't make sense in terms of feature
flagging, but uses every single default JSON logic op in their various
forms. In doing that I found a missed a few special cases:

missing special cases:

"+" can be used with a single param to cast to number
"-" can be used with a single param to multiply by -1
"substr" can be used with 3 args to to return a "middle" substring

bugs:

"reduce" needs 3 args
"max/min" take an array directly and no mapper function, so they can
take any amount of args
"<" and "<=" require at least 2 args

Signed-off-by: Todd Baert <todd.baert@dynatrace.com>
  • Loading branch information
toddbaert authored Jan 15, 2024
1 parent b812f93 commit 4a0be4f
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 122 deletions.
113 changes: 68 additions & 45 deletions json/targeting.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
{
"description": "When returned from rules, strings are used to as keys to retrieve the associated value from the \"variants\" object. Be sure that the returned string is present as a key in the variants!.",
"type": "string"
},
{
"description": "When returned from rules, strings are used to as keys to retrieve the associated value from the \"variants\" object. Be sure that the returned string is present as a key in the variants!.",
"type": "array"
}
]
},
Expand Down Expand Up @@ -129,19 +133,35 @@
}
}
},
"ifRule": {
"binaryOrTernaryOp": {
"type": "array",
"minItems": 2,
"maxItems": 3,
"items": {
"$ref": "#/$defs/args"
}
},
"binaryOrTernaryRule": {
"type": "object",
"additionalProperties": false,
"properties": {
"if": {
"title": "If Operator",
"description": "The if statement takes 3 arguments: a condition (if), what to do if its true (then), and what to do if its false (else). Note that the form accepting more than 3 arguments (if/else) is not supported in flagd; use nesting instead.",
"type": "array",
"minItems": 2,
"maxItems": 3,
"items": {
"$ref": "#/$defs/args"
}
"description": "The if statement takes 3 arguments: a condition (if), what to do if its true (then), and what to do if its false (else, optional). Note that the form accepting more than 3 arguments (if/else) is not supported in flagd; use nesting instead.",
"$ref": "#/$defs/binaryOrTernaryOp"
},
"substr": {
"title": "Substring Operation",
"description": "Get a portion of a string. Give a positive start position to return everything beginning at that index. Give a negative start position to work backwards from the end of the string, then return everything. Give a positive length to express how many characters to return.",
"$ref": "#/$defs/binaryOrTernaryOp"
},
"<": {
"title": "Less-Than/Between Operation. Can be used to test that one value is between two others.",
"$ref": "#/$defs/binaryOrTernaryOp"
},
"<=": {
"title": "Less-Than-Or-Equal-To/Between Operation. Can be used to test that one value is between two others.",
"$ref": "#/$defs/binaryOrTernaryOp"
}
}
},
Expand Down Expand Up @@ -192,16 +212,15 @@
"description": "Finds the remainder after the first argument is divided by the second argument.",
"$ref": "#/$defs/binaryOp"
},
"/": {
"title": "Division Operation",
"$ref": "#/$defs/binaryOp"
},
"map": {
"title": "Map Operation",
"description": "Perform an action on every member of an array. Note, that inside the logic being used to map, var operations are relative to the array element being worked on.",
"$ref": "#/$defs/binaryOp"
},
"reduce": {
"title": "Reduce Operation",
"description": "Combine all the elements in an array into a single value, like adding up a list of numbers. Note, that inside the logic being used to reduce, var operations only have access to an object with a \"current\" and a \"accumulator\".",
"$ref": "#/$defs/binaryOp"
},
"filter": {
"title": "Filter Operation",
"description": "Keep only elements of the array that pass a test. Note, that inside the logic being used to filter, var operations are relative to the array element being worked on.",
Expand All @@ -226,11 +245,22 @@
"title": "In Operation",
"description": "If the second argument is an array, tests that the first argument is a member of the array.",
"$ref": "#/$defs/binaryOp"
},
"substr": {
"title": "Substring Operation",
"description": "Get a portion of a string, given a positive start position as an index (indexes of course start at zero).",
"$ref": "#/$defs/binaryOp"
}
}
},
"reduceRule": {
"type": "object",
"additionalProperties": false,
"properties": {
"reduce": {
"title": "Reduce Operation",
"description": "Combine all the elements in an array into a single value, like adding up a list of numbers. Note, that inside the logic being used to reduce, var operations only have access to an object with a \"current\" and a \"accumulator\".",
"type": "array",
"minItems": 3,
"maxItems": 3,
"items": {
"$ref": "#/$defs/args"
}
}
}
},
Expand All @@ -247,11 +277,6 @@
"type": "object",
"additionalProperties": false,
"properties": {
"+": {
"title": "Addition Operation",
"description": "Addition; associative, will accept and unlimited amount of arguments.",
"$ref": "#/$defs/associativeOp"
},
"*": {
"title": "Multiplication Operation",
"description": "Multiplication; associative, will accept and unlimited amount of arguments.",
Expand Down Expand Up @@ -282,16 +307,6 @@
"title": "Double Negation Operation",
"description": "Double negation, or 'cast to a boolean'. Takes a single argument.",
"$ref": "#/$defs/unaryOp"
},
"max": {
"title": "Maximum Operation",
"description": "Return the maximum from a list of values.",
"$ref": "#/$defs/unaryOp"
},
"min": {
"title": "Minimum Operation",
"description": "Return the minimum from a list of values.",
"$ref": "#/$defs/unaryOp"
}
}
},
Expand All @@ -317,22 +332,27 @@
"description": "Simple boolean test, with 1 or more arguments. At a more sophisticated level, \"and\" returns the first falsy argument, or the last argument.",
"$ref": "#/$defs/variadicOp"
},
"<": {
"title": "Less-Than/Between Operation. Can be used to test that one value is between two others.",
"description": "",
"$ref": "#/$defs/variadicOp"
},
"<=": {
"title": "Less-Than-Or-Equal-To/Between Operation. Can be used to test that one value is between two others.",
"description": "",
"+": {
"title": "Addition Operation",
"description": "Addition; associative, will accept and unlimited amount of arguments.",
"$ref": "#/$defs/variadicOp"
},
"-": {
"title": "Subtraction Operation",
"$ref": "#/$defs/variadicOp"
},
"max": {
"title": "Maximum Operation",
"description": "Return the maximum from a list of values.",
"$ref": "#/$defs/variadicOp"
},
"min": {
"title": "Minimum Operation",
"description": "Return the minimum from a list of values.",
"$ref": "#/$defs/variadicOp"
},
"merge": {
"title": "Subtraction Operation",
"title": "Merge Operation",
"description": "Takes one or more arrays, and merges them into one array. If arguments aren't arrays, they get cast to arrays.",
"$ref": "#/$defs/variadicOp"
},
Expand Down Expand Up @@ -432,7 +452,7 @@
}
},
"fractionalWeightArg": {
"$comment": "if we remove the \"some to 100\" restriction, update the descriptions below!",
"$comment": "if we remove the \"sum to 100\" restriction, update the descriptions below!",
"description": "Distribution for all possible variants, with their associated weighting out of 100.",
"type": "array",
"minItems": 2,
Expand Down Expand Up @@ -529,10 +549,10 @@
"$ref": "#/$defs/missingSomeRule"
},
{
"$ref": "#/$defs/ifRule"
"$ref": "#/$defs/binaryRule"
},
{
"$ref": "#/$defs/binaryRule"
"$ref": "#/$defs/binaryOrTernaryRule"
},
{
"$ref": "#/$defs/associativeRule"
Expand All @@ -543,6 +563,9 @@
{
"$ref": "#/$defs/variadicRule"
},
{
"$ref": "#/$defs/reduceRule"
},
{
"$ref": "#/$defs/stringCompareRule"
},
Expand Down
101 changes: 59 additions & 42 deletions json/targeting.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ type: object
the associated value from the "variants" object. Be sure that the returned
string is present as a key in the variants!.
type: string
- description: When returned from rules, strings are used to as keys to retrieve
the associated value from the "variants" object. Be sure that the returned
string is present as a key in the variants!.
type: array
varRule:
title: Var Operation
description: Retrieve data from the provided data object.
Expand Down Expand Up @@ -93,21 +97,37 @@ type: object
- type: array
items:
type: string
ifRule:
binaryOrTernaryOp:
type: array
minItems: 2
maxItems: 3
items:
$ref: "#/$defs/args"
binaryOrTernaryRule:
type: object
additionalProperties: false
properties:
if:
title: If Operator
description: 'The if statement takes 3 arguments: a condition (if), what to
do if its true (then), and what to do if its false (else). Note that the
do if its true (then), and what to do if its false (else, optional). Note that the
form accepting more than 3 arguments (if/else) is not supported in flagd;
use nesting instead.'
type: array
minItems: 2
maxItems: 3
items:
$ref: "#/$defs/args"
$ref: "#/$defs/binaryOrTernaryOp"
substr:
title: Substring Operation
description: Get a portion of a string. Give a positive start position to return everything beginning at that index.
Give a negative start position to work backwards from the end of the string, then return everything.
Give a positive length to express how many characters to return.
$ref: "#/$defs/binaryOrTernaryOp"
"<":
title: Less-Than/Between Operation. Can be used to test that one value is
between two others.
$ref: "#/$defs/binaryOrTernaryOp"
"<=":
title: Less-Than-Or-Equal-To/Between Operation. Can be used to test that one
value is between two others.
$ref: "#/$defs/binaryOrTernaryOp"
binaryOp:
type: array
minItems: 2
Expand Down Expand Up @@ -147,18 +167,15 @@ type: object
description: Finds the remainder after the first argument is divided by the
second argument.
$ref: "#/$defs/binaryOp"
"/":
title: Division Operation
$ref: "#/$defs/binaryOp"
map:
title: Map Operation
description: Perform an action on every member of an array. Note, that inside
the logic being used to map, var operations are relative to the array element
being worked on.
$ref: "#/$defs/binaryOp"
reduce:
title: Reduce Operation
description: Combine all the elements in an array into a single value, like
adding up a list of numbers. Note, that inside the logic being used to reduce,
var operations only have access to an object with a "current" and a "accumulator".
$ref: "#/$defs/binaryOp"
filter:
title: Filter Operation
description: Keep only elements of the array that pass a test. Note, that
Expand Down Expand Up @@ -188,11 +205,20 @@ type: object
description: If the second argument is an array, tests that the first argument
is a member of the array.
$ref: "#/$defs/binaryOp"
substr:
title: Substring Operation
description: Get a portion of a string, given a positive start position as
an index (indexes of course start at zero).
$ref: "#/$defs/binaryOp"
reduceRule:
type: object
additionalProperties: false
properties:
reduce:
title: Reduce Operation
description: Combine all the elements in an array into a single value, like
adding up a list of numbers. Note, that inside the logic being used to reduce,
var operations only have access to an object with a "current" and a "accumulator".
type: array
minItems: 3
maxItems: 3
items:
$ref: "#/$defs/args"
associativeOp:
type: array
minItems: 2
Expand All @@ -204,10 +230,6 @@ type: object
type: object
additionalProperties: false
properties:
"+":
title: Addition Operation
description: Addition; associative, will accept and unlimited amount of arguments.
$ref: "#/$defs/associativeOp"
"*":
title: Multiplication Operation
description: Multiplication; associative, will accept and unlimited amount
Expand All @@ -233,14 +255,6 @@ type: object
title: Double Negation Operation
description: Double negation, or 'cast to a boolean'. Takes a single argument.
$ref: "#/$defs/unaryOp"
max:
title: Maximum Operation
description: Return the maximum from a list of values.
$ref: "#/$defs/unaryOp"
min:
title: Minimum Operation
description: Return the minimum from a list of values.
$ref: "#/$defs/unaryOp"
variadicOp:
type: array
minItems: 1
Expand All @@ -261,21 +275,23 @@ type: object
description: Simple boolean test, with 1 or more arguments. At a more sophisticated
level, "and" returns the first falsy argument, or the last argument.
$ref: "#/$defs/variadicOp"
"<":
title: Less-Than/Between Operation. Can be used to test that one value is
between two others.
description: ''
$ref: "#/$defs/variadicOp"
"<=":
title: Less-Than-Or-Equal-To/Between Operation. Can be used to test that one
value is between two others.
description: ''
"+":
title: Addition Operation
description: Addition; associative, will accept and unlimited amount of arguments.
$ref: "#/$defs/variadicOp"
"-":
title: Subtraction Operation
$ref: "#/$defs/variadicOp"
max:
title: Maximum Operation
description: Return the maximum from a list of values.
$ref: "#/$defs/variadicOp"
min:
title: Minimum Operation
description: Return the minimum from a list of values.
$ref: "#/$defs/variadicOp"
merge:
title: Subtraction Operation
title: Merge Operation
description: Takes one or more arrays, and merges them into one array. If
arguments aren't arrays, they get cast to arrays.
$ref: "#/$defs/variadicOp"
Expand Down Expand Up @@ -343,7 +359,7 @@ type: object
- $ref: "#/$defs/semVerString"
- $ref: "#/$defs/varRule"
fractionalWeightArg:
$comment: if we remove the "some to 100" restriction, update the descriptions
$comment: if we remove the "sum to 100" restriction, update the descriptions
below!
description: Distribution for all possible variants, with their associated weighting
out of 100.
Expand Down Expand Up @@ -402,11 +418,12 @@ type: object
- $ref: "#/$defs/varRule"
- $ref: "#/$defs/missingRule"
- $ref: "#/$defs/missingSomeRule"
- $ref: "#/$defs/ifRule"
- $ref: "#/$defs/binaryRule"
- $ref: "#/$defs/binaryOrTernaryRule"
- $ref: "#/$defs/associativeRule"
- $ref: "#/$defs/unaryRule"
- $ref: "#/$defs/variadicRule"
- $ref: "#/$defs/reduceRule"
- $ref: "#/$defs/stringCompareRule"
- $ref: "#/$defs/ruleSemVer"
- $ref: "#/$defs/fractionalRule"
1 change: 1 addition & 0 deletions json/test/negative/empty-variants.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"$schema": "../../flagd-definitions.json",
"flags": {
"myBoolFlag": {
"state": "ENABLED",
Expand Down
Loading

0 comments on commit 4a0be4f

Please sign in to comment.