diff --git a/.gitignore b/.gitignore index 8ec7a5f..8e8f863 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,6 @@ bin/ .DS_Store .idea/ *.iml + +# TCK tests configs +/tests/tck/TestCases/ diff --git a/Makefile b/Makefile index 009c08f..19c7744 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,10 @@ -RESOURCES_DIR=resources -TCK_DIR=$(RESOURCES_DIR)/tck -TCK_REPO=https://github.com/dmn-tck/tck.git -TEST_CONFIG_FILE=./test-cases_feel.yaml - GO_FILES := $(shell find . -name '*.go') GO_FLAGS := all: build test: - go test -v ./... + go test $$(go list ./... | grep -v /tests/tck) cover: go test -coverprofile=coverage.out ./... @@ -28,14 +23,21 @@ bin/feel: ${GO_FILES} clean: rm -rf build dist bin/* - rm -rf $(TCK_DIR) + rm -rf resources/ + rm -rf tests/tck/TestCases/ .PHONY: test gofmt build-cli clean .SECONDARY: $(buildarchdirs) .PHONY: extract-testcases extract-testcases: - mkdir -p $(RESOURCES_DIR) - git clone --depth 1 $(TCK_REPO) $(TCK_DIR) - go run ./cmd/testcase-extractor --dir $(TCK_DIR) --output-file $(TEST_CONFIG_FILE) - rm -rf $(TCK_DIR) + mkdir -p resources/ + git clone --depth 1 https://github.com/dmn-tck/tck.git resources/tck/ + go run ./cmd/testcase-extractor --dir resources/tck --output-dir tests/tck/ + rm -rf resources/ + + +.PHONY: test-tck +test-tck: + go test ./tests/tck + diff --git a/cmd/testcase-extractor/fs/fs.go b/cmd/testcase-extractor/fs/fs.go new file mode 100644 index 0000000..a8818fd --- /dev/null +++ b/cmd/testcase-extractor/fs/fs.go @@ -0,0 +1,59 @@ +package fs + +import ( + "fmt" + "os" + "path/filepath" +) + +// EnsureDir make sure the dir exists - checks that dir exists, +// if not creates it, including parent dirs. +func EnsureDir(outputDirPath string) { + err := os.MkdirAll(outputDirPath, 0755) + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "Error creating directory: %v\n", err) + return + } +} + +// FindFiles traverses the directory tree starting at dir and returns files +// matching the wildcard pattern +func FindFiles(dir, wildcard string, inSubDirs bool) []string { + var filePaths []string + + if _, err := os.Stat(dir); os.IsNotExist(err) { + _, _ = fmt.Fprintf(os.Stderr, "Error: Directory '%s' does not exist\n", dir) + os.Exit(1) + } + + var err error + if inSubDirs { + err = filepath.WalkDir(dir, func(path string, d os.DirEntry, err error) error { + if err != nil { + return err + } + if !d.IsDir() { + matched, err := filepath.Match(wildcard, d.Name()) + if err != nil { + return err + } + if matched { + filePaths = append(filePaths, path) + } + } + return nil + }) + } else { + var matches []string + matches, err = filepath.Glob(wildcard) + + filePaths = append(filePaths, matches...) + } + + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(1) + } + + return filePaths +} diff --git a/cmd/testcase-extractor/main.go b/cmd/testcase-extractor/main.go index b755e71..7d10417 100644 --- a/cmd/testcase-extractor/main.go +++ b/cmd/testcase-extractor/main.go @@ -5,7 +5,11 @@ import ( "errors" "flag" "fmt" - "github.com/pbinitiative/feel/cmd/testcase-extractor/tck/model" + "github.com/pbinitiative/feel/cmd/testcase-extractor/fs" + "github.com/pbinitiative/feel/cmd/testcase-extractor/model/dmn" + "github.com/pbinitiative/feel/cmd/testcase-extractor/model/tck" + "github.com/pbinitiative/feel/cmd/testcase-extractor/model/tcktestconfig" + "github.com/pbinitiative/feel/cmd/testcase-extractor/model/testconfig" "gopkg.in/yaml.v3" "os" "path/filepath" @@ -14,53 +18,6 @@ import ( "time" ) -type TckDefinitions struct { - Decisions []*TckDecision `xml:"decision"` -} - -type TckDecision struct { - Name string `xml:"name,attr"` - // TODO[JSot]: Add support for "contextEntry>literalExpression>text" - LiteralExpression string `xml:"literalExpression>text"` -} - -type TestConfig struct { - Model TestConfigModel `yaml:"model"` - TestCases []TestCase `yaml:"test-cases"` -} - -type TestConfigModel struct { - Dir *string `yaml:"dir"` - Name *string `yaml:"name"` -} - -type TestCase struct { - Id *string `yaml:"id"` - Description *string `yaml:"description"` - Tests []Test `yaml:"tests"` -} - -type Test struct { - FeelExpression *string `yaml:"feel-expression"` - *ExpectedResult `yaml:"expected"` -} - -type ExpectedResult struct { - Components *[]Component `yaml:"components,omitempty"` - Value *ExpectedValue `yaml:"result,omitempty"` - Values *[]ExpectedResult `yaml:"results,omitempty"` -} - -type Component struct { - Name string `yaml:"name"` - *ExpectedResult `yaml:"expected"` -} - -type ExpectedValue struct { - Value *string `yaml:"value"` - Type *string `yaml:"type,omitempty"` -} - const ( dmnModelFileWildcard = "*-feel-*.dmn" testCaseFileSuffix = "-test-01.xml" @@ -69,18 +26,18 @@ const ( func parseFlags() ( dir *string, - outputFilename *string, + outputDir *string, forceStats *bool, ) { dir = flag.String( "dir", ".", - "Directory to start search for DMN model files and Test Cases files.", + "Directory to start search for TCK DMN model files and Test Cases files.", ) - outputFilename = flag.String( - "output-file", - "-", - `Name of file to save output to. Default is "-" (STDOUT).`, + outputDir = flag.String( + "output-dir", + "./feel", + `Dir to save output to. Default is "./feel".`, ) forceStats = flag.Bool( "force-stats", @@ -92,13 +49,14 @@ func parseFlags() ( return } -func resolveOutputFile(outputFilename string) *os.File { +func ensureOutputFile(outputFilename string) *os.File { var outputFile *os.File var err error if outputFilename == "-" { outputFile = os.Stdout } else { + fs.EnsureDir(filepath.Dir(outputFilename)) outputFile, err = os.Create(outputFilename) if err != nil { printError("Error getting output filename absolute path: %v\n", err) @@ -109,43 +67,9 @@ func resolveOutputFile(outputFilename string) *os.File { return outputFile } -// findFiles traverses the directory tree starting at dir and returns files -// matching the wildcard pattern -func findFiles(dir, wildcard string) []string { - var filePaths []string - - if _, err := os.Stat(dir); os.IsNotExist(err) { - printError("Error: Directory '%s' does not exist\n", dir) - os.Exit(1) - } - - err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if !info.IsDir() { - matched, err := filepath.Match(wildcard, info.Name()) - if err != nil { - return err - } - if matched { - filePaths = append(filePaths, path) - } - } - return nil - }) - - if err != nil { - printError("Error: %v\n", err) - os.Exit(1) - } - - return filePaths -} - func extractTckTestCases( testCasesFilePath string, - tckTestCasesCh chan *model.TestCases, + tckTestCasesCh chan *tck.TestCases, ) { defer close(tckTestCasesCh) @@ -154,7 +78,7 @@ func extractTckTestCases( printError("Error: could not read Test Cases file %v: %v\n", testCasesFilePath, err) } - var testCases *model.TestCases + var testCases *tck.TestCases err = xml.Unmarshal(bytes, &testCases) if err != nil { printError("Error: could not read Test Cases file %v: %v\n", testCasesFilePath, err) @@ -163,67 +87,67 @@ func extractTckTestCases( tckTestCasesCh <- testCases } -func extractTckDecisions(decisionsFilePath string, tckDecisionsCh chan []*TckDecision) { - defer close(tckDecisionsCh) +func extractDmnDecisions(decisionsFilePath string, dmnDecisionsCh chan []*dmn.Decision) { + defer close(dmnDecisionsCh) bytes, err := os.ReadFile(decisionsFilePath) if err != nil { printError("Error: could not read Test Cases file: %v\n", err) } - var definitions *TckDefinitions + var definitions *dmn.Definitions err = xml.Unmarshal(bytes, &definitions) if err != nil { printError("Error: could not read Test Cases file: %v\n", err) } - tckDecisionsCh <- definitions.Decisions + dmnDecisionsCh <- definitions.Decisions } -func compileTestConfigs(dmnFiles []string, searchDir string) []TestConfig { - testConfigsCh := make(chan TestConfig) +func compileTestConfigs(dmnFiles []string, searchDir string) []tcktestconfig.TestConfig { + testConfigsCh := make(chan tcktestconfig.TestConfig) for _, dmnFile := range dmnFiles { go compileTestConfig(dmnFile, searchDir, testConfigsCh) } - testConfigs := make([]TestConfig, 0) - for _ = range len(dmnFiles) { + testConfigs := make([]tcktestconfig.TestConfig, 0) + for range len(dmnFiles) { testConfigs = append(testConfigs, <-testConfigsCh) } sort.Slice(testConfigs, func(i, j int) bool { - return *testConfigs[i].Model.Name < *testConfigs[j].Model.Name + return testConfigs[i].Model.Name < testConfigs[j].Model.Name }) return testConfigs } -func compileExpectedResult(tckValue *model.ValueType) ExpectedResult { +func compileExpectedResult(tckValue *tck.ValueType) testconfig.ExpectedResult { switch { case tckValue.Components != nil: - components := make([]Component, 0) + components := make([]testconfig.Component, 0) for _, tckComponent := range *tckValue.Components { expectedResult := compileExpectedResult(tckComponent.ValueType) components = append( components, - Component{ - tckComponent.NameAttr, - &expectedResult, + testconfig.Component{ + Name: tckComponent.NameAttr, + ExpectedResult: expectedResult, }, ) } - return ExpectedResult{Components: &components} + return testconfig.ExpectedResult{Components: &components} case tckValue.Value != nil: - return ExpectedResult{ - Value: &ExpectedValue{ - tckValue.Value.Content, - stripNamespacePrefix(tckValue.Value.Type), + return testconfig.ExpectedResult{ + Value: &testconfig.ExpectedValue{ + Value: tckValue.Value.Content, + Type: stripNamespacePrefix(tckValue.Value.Type), }, } case tckValue.List != nil: - results := make([]ExpectedResult, 0) + results := make([]testconfig.ExpectedResult, 0) for _, result := range tckValue.List.Items { expectedResult := compileExpectedResult(result) results = append( @@ -232,7 +156,7 @@ func compileExpectedResult(tckValue *model.ValueType) ExpectedResult { ) } - return ExpectedResult{Values: &results} + return testconfig.ExpectedResult{Values: &results} default: panic(errors.New("unsupported Test Case Result type. Should not happen")) } @@ -241,7 +165,7 @@ func compileExpectedResult(tckValue *model.ValueType) ExpectedResult { func compileTestConfig( dmnFile string, searchDir string, - testConfigsCh chan TestConfig, + testConfigsCh chan tcktestconfig.TestConfig, ) { testCaseDir := strings.TrimPrefix(filepath.Dir(dmnFile), searchDir) testCaseFile := strings.TrimSuffix( @@ -249,49 +173,54 @@ func compileTestConfig( filepath.Ext(dmnFile), ) + testCaseFileSuffix - tckTestCasesCh := make(chan *model.TestCases) + tckTestCasesCh := make(chan *tck.TestCases) go extractTckTestCases(testCaseFile, tckTestCasesCh) - tckDecisionsCh := make(chan []*TckDecision) - go extractTckDecisions(dmnFile, tckDecisionsCh) + dmnDecisionsCh := make(chan []*dmn.Decision) + go extractDmnDecisions(dmnFile, dmnDecisionsCh) - tckTestCases, tckDecisions := <-tckTestCasesCh, <-tckDecisionsCh + tckTestCases, dmnDecisions := <-tckTestCasesCh, <-dmnDecisionsCh - tckDecisionsMap := mapTckDecisionsByName(tckDecisions) + dmnDecisionsMap := mapDmnDecisionsByName(dmnDecisions) - testCases := make([]TestCase, 0) + testCases := make([]testconfig.TestCase, 0) for _, tckTestCase := range tckTestCases.TestCases { - tests := make([]Test, 0) - for _, tckResult := range tckTestCase.ResultNodes { - tckDecision := tckDecisionsMap[tckResult.NameAttr] - - expectedResult := compileExpectedResult(tckResult.Expected) - tests = append( - tests, - Test{ - FeelExpression: &tckDecision.LiteralExpression, - ExpectedResult: &expectedResult, - }, - ) - } + tests := compileTest(tckTestCase, dmnDecisionsMap) - testCase := TestCase{ - Id: &tckTestCase.IdAttr, - Description: &tckTestCase.Description, + testCase := testconfig.TestCase{ + Id: tckTestCase.IdAttr, + Description: tckTestCase.Description, Tests: tests, } testCases = append(testCases, testCase) } - testConfigsCh <- TestConfig{ - Model: TestConfigModel{ - &testCaseDir, - &tckTestCases.ModelName, + testConfigsCh <- tcktestconfig.TestConfig{ + Model: tcktestconfig.Model{ + Dir: testCaseDir, + Name: tckTestCases.ModelName, }, TestCases: testCases, } } +func compileTest(tckTestCase *tck.TestCase, dmnDecisionsMap map[string]*dmn.Decision) []testconfig.Test { + tests := make([]testconfig.Test, 0) + for _, tckResult := range tckTestCase.ResultNodes { + dmnDecision := dmnDecisionsMap[tckResult.NameAttr] + + expectedResult := compileExpectedResult(tckResult.Expected) + tests = append( + tests, + testconfig.Test{ + FeelExpression: dmnDecision.LiteralExpression, + ExpectedResult: expectedResult, + }, + ) + } + return tests +} + // Strip namespace prefix from `valueType`, if not `nil`. // Otherwise, return `nil`. func stripNamespacePrefix(valueType *string) *string { @@ -303,26 +232,49 @@ func stripNamespacePrefix(valueType *string) *string { } } -func mapTckDecisionsByName(tckDecisions []*TckDecision) map[string]*TckDecision { - resultsMap := make(map[string]*TckDecision) - for _, tckDecision := range tckDecisions { - resultsMap[tckDecision.Name] = tckDecision +func mapDmnDecisionsByName(tckDecisions []*dmn.Decision) map[string]*dmn.Decision { + resultsMap := make(map[string]*dmn.Decision) + for _, dmnDecision := range tckDecisions { + resultsMap[dmnDecision.Name] = dmnDecision } return resultsMap } -func saveTestConfigs(testConfigs []TestConfig, outputFile *os.File) { - yamlData, err := yaml.Marshal(&testConfigs) - if err != nil { - printError("Error marshaling to YAML: %v\n", err) - os.Exit(1) - } +func saveTestConfigs(testConfigs []tcktestconfig.TestConfig, outputDir string) { - _, err = outputFile.Write(yamlData) - if err != nil { - printError("Error writing YAML file: %v\n", err) - os.Exit(1) + for _, testConfig := range testConfigs { + + testConfigFilename := strings.TrimSuffix( + testConfig.Model.Name, + filepath.Ext(testConfig.Model.Name), + ) + ".yaml" + + outputFilename := filepath.Join( + outputDir, + filepath.Dir(testConfig.Model.Dir), // No need to have dir with one file of same name + testConfigFilename, + ) + outputFile := ensureOutputFile(outputFilename) + + yamlData, err := yaml.Marshal([]tcktestconfig.TestConfig{testConfig}) + if err != nil { + printError("Error marshaling to YAML: %v\n", err) + os.Exit(1) + } + + defer func(outputFile *os.File) { + err := outputFile.Close() + if err != nil { + printError("Error closing output file: %v\n", err) + } + }(outputFile) + + _, err = outputFile.Write(yamlData) + if err != nil { + printError("Error writing YAML to file: %v\n", err) + os.Exit(1) + } } } @@ -330,41 +282,20 @@ func printError(format string, a ...any) { _, _ = fmt.Fprintf(os.Stderr, format, a...) } -func isOutputPiped() bool { - fileInfo, err := os.Stdout.Stat() - if err != nil { - printError("Error checking pipe: %v\n", err) - } - // Check if the file mode indicates a named pipe (FIFO) - return (fileInfo.Mode() & os.ModeNamedPipe) != 0 -} - func printExtractionStats( - outputFile *os.File, + outputDir string, countOfFeelExpressions int, countOfFiles int, duration time.Duration, ) { - - outputFileInfo := "" - if outputFile != os.Stdout { - outputFilenameAbs, _ := filepath.Abs(outputFile.Name()) - outputFileInfo = fmt.Sprintf( - " to file "+ - "\n\t%v", - outputFilenameAbs, - ) - } - fmt.Printf( "\n"+ - "%d test cases for feel expressions extracted"+ - "%v"+ + "%d test cases for feel expressions extracted to %s"+ "\n%d TCK DMN and Test Case files processed"+ "\nIt took %v"+ "\n", countOfFeelExpressions, - outputFileInfo, + outputDir, countOfFiles, duration, ) @@ -373,7 +304,7 @@ func printExtractionStats( func main() { startTs := time.Now() - dir, outputFilename, forceStats := parseFlags() + dir, outputDir, _ := parseFlags() searchDir, err := filepath.Abs(*dir) if err != nil { @@ -381,16 +312,7 @@ func main() { os.Exit(1) } - outputFile := resolveOutputFile(*outputFilename) - - defer func(outputFile *os.File) { - err := outputFile.Close() - if err != nil { - printError("Error closing output file: %v\n", err) - } - }(outputFile) - - modelFiles := findFiles(searchDir, dmnModelFileWildcard) + modelFiles := fs.FindFiles(searchDir, dmnModelFileWildcard, true) testConfigs := compileTestConfigs(modelFiles, searchDir) countOfFeelExpressions := 0 @@ -398,16 +320,14 @@ func main() { countOfFeelExpressions += len(testConfig.TestCases) } - saveTestConfigs(testConfigs, outputFile) + saveTestConfigs(testConfigs, *outputDir) duration := time.Since(startTs) - if !isOutputPiped() || *forceStats { - printExtractionStats( - outputFile, - countOfFeelExpressions, - len(modelFiles)*2, // *2 because both DMN file and TestCase files are processed - duration, - ) - } + printExtractionStats( + *outputDir, + countOfFeelExpressions, + len(modelFiles)*2, // *2 because both DMN file and TestCase files are processed + duration, + ) } diff --git a/cmd/testcase-extractor/model/dmn/dmn_model.go b/cmd/testcase-extractor/model/dmn/dmn_model.go new file mode 100644 index 0000000..68e3ca9 --- /dev/null +++ b/cmd/testcase-extractor/model/dmn/dmn_model.go @@ -0,0 +1,11 @@ +package dmn + +type Definitions struct { + Decisions []*Decision `xml:"decision"` +} + +type Decision struct { + Name string `xml:"name,attr"` + // TODO[JSot]: Add support for "contextEntry>literalExpression>text" + LiteralExpression string `xml:"literalExpression>text"` +} diff --git a/cmd/testcase-extractor/tck/model/model.go b/cmd/testcase-extractor/model/tck/tck_model.go similarity index 94% rename from cmd/testcase-extractor/tck/model/model.go rename to cmd/testcase-extractor/model/tck/tck_model.go index 1d36e86..a578bba 100644 --- a/cmd/testcase-extractor/tck/model/model.go +++ b/cmd/testcase-extractor/model/tck/tck_model.go @@ -1,4 +1,4 @@ -package model +package tck import ( "encoding/xml" @@ -99,13 +99,9 @@ func (simpleType *AnySimpleType) UnmarshalXML(d *xml.Decoder, start xml.StartEle return err } if simpleTypeNode.Nil { - simpleType.Content = nil + simpleType.Content = nil // Treat empty string as nil } else { - if simpleTypeNode.Value != "" { - simpleType.Content = &simpleTypeNode.Value - } else { - simpleType.Content = nil // Treat empty string as nil - } + simpleType.Content = &simpleTypeNode.Value } simpleType.Type = simpleTypeNode.Type return nil diff --git a/cmd/testcase-extractor/model/tcktestconfig/tcktestconfig_model.go b/cmd/testcase-extractor/model/tcktestconfig/tcktestconfig_model.go new file mode 100644 index 0000000..3c1e555 --- /dev/null +++ b/cmd/testcase-extractor/model/tcktestconfig/tcktestconfig_model.go @@ -0,0 +1,15 @@ +package tcktestconfig + +import ( + "github.com/pbinitiative/feel/cmd/testcase-extractor/model/testconfig" +) + +type TestConfig struct { + Model Model `yaml:"model"` + TestCases []testconfig.TestCase `yaml:"test-cases"` +} + +type Model struct { + Dir string `yaml:"dir"` + Name string `yaml:"name"` +} diff --git a/cmd/testcase-extractor/model/testconfig/testconfig_model.go b/cmd/testcase-extractor/model/testconfig/testconfig_model.go new file mode 100644 index 0000000..4e6109f --- /dev/null +++ b/cmd/testcase-extractor/model/testconfig/testconfig_model.go @@ -0,0 +1,74 @@ +package testconfig + +import ( + "fmt" + "strings" +) + +type TestCase struct { + Id string `yaml:"id"` + Description string `yaml:"description"` + Tests []Test `yaml:"tests"` +} + +type Test struct { + FeelExpression string `yaml:"feel-expression"` + ExpectedResult `yaml:"expected"` +} + +type ExpectedResult struct { + Components *[]Component `yaml:"components,omitempty"` + Value *ExpectedValue `yaml:"result,omitempty"` + Values *[]ExpectedResult `yaml:"results,omitempty"` +} + +func joinStrings(vals []string) string { + return strings.Join(vals, ", ") +} + +func (er ExpectedResult) String() string { + switch { + case er.Components != nil: + componentsStrings := make([]string, 0) + for _, component := range *er.Components { + componentsStrings = append(componentsStrings, component.String()) + } + + return fmt.Sprintf("components: {%s}", joinStrings(componentsStrings)) + case er.Value != nil: + if er.Value.Value == nil { + return fmt.Sprintf("value: nil") + } + + var typeString string + if er.Value.Type == nil { + typeString = "nil" + } else { + typeString = *er.Value.Type + } + + return fmt.Sprintf("%s(%s)", typeString, *er.Value.Value) + case er.Values != nil: + valuesStrings := make([]string, 0) + for _, value := range *er.Values { + valuesStrings = append(valuesStrings, value.String()) + } + return fmt.Sprintf("values: {%s}", joinStrings(valuesStrings)) + default: + panic("Unsupported 'ExpectedResult' type. Supported types are 'Components', 'Value' and 'Values'") + } +} + +type Component struct { + Name string `yaml:"name"` + ExpectedResult `yaml:"expected"` +} + +func (c Component) String() string { + return fmt.Sprintf("%s: %s", c.Name, c.ExpectedResult.String()) +} + +type ExpectedValue struct { + Value *string `yaml:"value"` + Type *string `yaml:"type,omitempty"` +} diff --git a/tests/feel-all-function.yaml b/tests/feel-all-function.yaml new file mode 100644 index 0000000..5090e5e --- /dev/null +++ b/tests/feel-all-function.yaml @@ -0,0 +1,142 @@ +- id: "001" + description: return false if any item is false + tests: + - feel-expression: all([true, false, true]) + expected: + result: + value: "false" + type: boolean +- id: "002" + description: return true if all items are true + tests: + - feel-expression: all([true, true, true]) + expected: + result: + value: "true" + type: boolean +#- id: "003" +# description: return null if any item is not true or false +# tests: +# - feel-expression: all([true, null, true]) +# expected: +# result: +# value: null +#- id: "004" +# description: return null if any item is not true or false +# tests: +# - feel-expression: all([true, 123, true]) +# expected: +# result: +# value: null +- id: "005" + description: return true for empty list + tests: + - feel-expression: all([]) + expected: + result: + value: "true" + type: boolean +- id: "006" + description: 'return true for singleton true ' + tests: + - feel-expression: all(true) + expected: + result: + value: "true" + type: boolean +- id: "007" + description: return false for singleton false + tests: + - feel-expression: all(false) + expected: + result: + value: "false" + type: boolean +#- id: "008" +# description: return null for singleton null +# tests: +# - feel-expression: all(null) +# expected: +# result: +# value: null +#- id: "009" +# description: return null for singleton non-boolean +# tests: +# - feel-expression: all(123) +# expected: +# result: +# value: null +- id: "010" + description: return false if any vararg item is false + tests: + - feel-expression: all(true, false, true) + expected: + result: + value: "false" + type: boolean +- id: "011" + description: return true if all vararg items are true + tests: + - feel-expression: all(true, true, true) + expected: + result: + value: "true" + type: boolean +#- id: "012" +# description: return null if any vararg item is not true or false +# tests: +# - feel-expression: all(true, null, true) +# expected: +# result: +# value: null +#- id: "013" +# description: return null if any vararg item is not true or false +# tests: +# - feel-expression: all(true, 123, true) +# expected: +# result: +# value: null +#- id: "014" +# description: return error when no params +# tests: +# - feel-expression: all() +# expected: +# result: +# value: null +#- id: "015" +# description: return false if any item is false with named param +# tests: +# - feel-expression: all(list:[true, false, true]) +# expected: +# result: +# value: "false" +# type: boolean +#- id: "016" +# description: return true if all items are true with named param +# tests: +# - feel-expression: all(list:[true, true, true]) +# expected: +# result: +# value: "true" +# type: boolean +#- id: "017" +# description: return null if any item is not true or false - with named param +# tests: +# - feel-expression: all(list:[true, null, true]) +# expected: +# result: +# value: null +#- id: "018" +# description: return null when named param is null +# tests: +# - feel-expression: all(list:null) +# expected: +# result: +# value: null +#- id: "019" +# description: will error when wrongly named param +# tests: +# - feel-expression: all(l:[true]) +# expected: +# result: +# value: null diff --git a/tests/feel-any-function.yaml b/tests/feel-any-function.yaml new file mode 100644 index 0000000..3c02273 --- /dev/null +++ b/tests/feel-any-function.yaml @@ -0,0 +1,128 @@ +- id: "001" + description: return true if any item is true + tests: + - feel-expression: any([true, false, true]) + expected: + result: + value: "true" + type: boolean +- id: "002" + description: return false if all items are false + tests: + - feel-expression: any([false, false, false]) + expected: + result: + value: "false" + type: boolean +#- id: "004" +# description: return null if any item not true and not all false +# tests: +# - feel-expression: any([123, false]) +# expected: +# result: +# value: null +- id: "005" + description: return false for empty list + tests: + - feel-expression: any([]) + expected: + result: + value: "false" + type: boolean +- id: "006" + description: 'return true for singleton true ' + tests: + - feel-expression: any(true) + expected: + result: + value: "true" + type: boolean +- id: "007" + description: return false for singleton false + tests: + - feel-expression: any(false) + expected: + result: + value: "false" + type: boolean +#- id: "008" +# description: return null for singleton null +# tests: +# - feel-expression: any(null) +# expected: +# result: +# value: null +#- id: "009" +# description: return null for singleton non-boolean +# tests: +# - feel-expression: any(123) +# expected: +# result: +# value: null +- id: "010" + description: return true if any vararg item is true + tests: + - feel-expression: any(true, false, true) + expected: + result: + value: "true" + type: boolean +- id: "011" + description: return false if all vararg items are false + tests: + - feel-expression: any(false, false) + expected: + result: + value: "false" + type: boolean +#- id: "012" +# description: return null if not all vararg items are true and none are false false +# tests: +# - feel-expression: any(null, false) +# expected: +# result: +# value: null +#- id: "014" +# description: return error when no params +# tests: +# - feel-expression: any() +# expected: +# result: +# value: null +#- id: "015" +# description: return true if any item is true with named param +# tests: +# - feel-expression: any(list:[true, false, true]) +# expected: +# result: +# value: "true" +# type: boolean +#- id: "016" +# description: return false if all items are false with named param +# tests: +# - feel-expression: any(list:[false, false]) +# expected: +# result: +# value: "false" +# type: boolean +#- id: "017" +# description: return null if none true and not all false - with named param +# tests: +# - feel-expression: any(list:[null, false]) +# expected: +# result: +# value: null +#- id: "018" +# description: return error when named param is null +# tests: +# - feel-expression: any(list:null) +# expected: +# result: +# value: null +#- id: "019" +# description: will error when wrongly named param +# tests: +# - feel-expression: any(l:[true]) +# expected: +# result: +# value: null diff --git a/tests/feel-at-literals.yaml b/tests/feel-at-literals.yaml new file mode 100644 index 0000000..8885118 --- /dev/null +++ b/tests/feel-at-literals.yaml @@ -0,0 +1,151 @@ +#- id: test_001 +# description: invalid value has null value +# tests: +# - feel-expression: '@"foo"' +# expected: +# result: +# value: null +#- id: date_001 +# description: will parse date to date type +# tests: +# - feel-expression: '@"2019-03-31" instance of date' +# expected: +# result: +# value: "true" +# type: boolean +- id: date_002 + description: will parse date value + tests: + - feel-expression: '@"2019-03-31"' + expected: + result: + value: "2019-03-31" + type: date +#- id: datetime_001 +# description: will parse to date time type +# tests: +# - feel-expression: '@"2018-12-08T10:30:11" instance of date and time' +# expected: +# result: +# value: "true" +# type: boolean +- id: datetime_002 + description: will parse date time value + tests: + - feel-expression: '@"2018-12-08T10:30:11"' + expected: + result: + value: 2018-12-08T10:30:11 + type: dateTime +#- id: datetime_003 +# description: will parse to date time with zone +# tests: +# - feel-expression: '@"2018-12-08T10:30:11@Australia/Melbourne" instance of date and time' +# expected: +# result: +# value: "true" +# type: boolean +#- id: datetime_004 +# description: will parse date time value with zone +# tests: +# - feel-expression: string(@"2018-12-08T10:30:11@Australia/Melbourne") +# expected: +# result: +# value: 2018-12-08T10:30:11@Australia/Melbourne +# type: string +#- id: datetime_005 +# description: will parse to date time value with offset +# tests: +# - feel-expression: '@"2018-12-08T10:30:11+11:00" instance of date and time' +# expected: +# result: +# value: "true" +# type: boolean +- id: datetime_006 + description: will parse date time value with offset + tests: + - feel-expression: '@"2018-12-08T10:30:11+11:00"' + expected: + result: + value: "2018-12-08T10:30:11+11:00" + type: dateTime +#- id: time_001 +# description: will parse to time type +# tests: +# - feel-expression: '@"10:30:11" instance of time' +# expected: +# result: +# value: "true" +# type: boolean +- id: time_002 + description: will parse time value + tests: + - feel-expression: '@"10:30:11"' + expected: + result: + value: "10:30:11" + type: time +#- id: time_003 +# description: will parse to time + offset +# tests: +# - feel-expression: '@"10:30:11+11:00" instance of time' +# expected: +# result: +# value: "true" +# type: boolean +- id: time_004 + description: will parse time value + offset + tests: + - feel-expression: '@"10:30:11+11:00"' + expected: + result: + value: 10:30:11+11:00 + type: time +#- id: time_005 +# description: will parse to time + zone +# tests: +# - feel-expression: '@"10:30:11@Australia/Melbourne" instance of time' +# expected: +# result: +# value: "true" +# type: boolean +#- id: time_006 +# description: will parse time value + zone +# tests: +# - feel-expression: string(@"10:30:11@Australia/Melbourne") +# expected: +# result: +# value: 10:30:11@Australia/Melbourne +# type: string +#- id: dt_duration_001 +# description: will parse to days and time duration type +# tests: +# - feel-expression: '@"P10D" instance of days and time duration' +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_002 +# description: will parse days and time duration value +# tests: +# - feel-expression: '@"P10D"' +# expected: +# result: +# value: P10D +# type: duration +#- id: ym_duration_001 +# description: will parse to years and months duration type +# tests: +# - feel-expression: '@"P10Y" instance of years and months duration' +# expected: +# result: +# value: "true" +# type: boolean +- id: ym_duration_002 + description: will parse years and months duration value + tests: + - feel-expression: '@"P10Y"' + expected: + result: + value: P10Y + type: duration diff --git a/tests/feel-between.yaml b/tests/feel-between.yaml new file mode 100644 index 0000000..8a71ab9 --- /dev/null +++ b/tests/feel-between.yaml @@ -0,0 +1,301 @@ +#- id: number_001 +# description: before +# tests: +# - feel-expression: 0 between 1 and 10 +# expected: +# result: +# value: "false" +# type: boolean +- id: number_002 + description: start + tests: + - feel-expression: 1 between 1 and 10 + expected: + result: + value: "true" + type: boolean +- id: number_003 + description: between + tests: + - feel-expression: 5 between 1 and 10 + expected: + result: + value: "true" + type: boolean +- id: number_004 + description: end + tests: + - feel-expression: 10 between 1 and 10 + expected: + result: + value: "true" + type: boolean +#- id: number_005 +# description: after +# tests: +# - feel-expression: 11 between 1 and 10 +# expected: +# result: +# value: "false" +# type: boolean +#- id: string_001 +# description: before +# tests: +# - feel-expression: '"a" between "b" and "d"' +# expected: +# result: +# value: "false" +# type: boolean +- id: string_002 + description: start + tests: + - feel-expression: '"b" between "b" and "d"' + expected: + result: + value: "true" + type: boolean +- id: string_003 + description: between + tests: + - feel-expression: '"c" between "b" and "d"' + expected: + result: + value: "true" + type: boolean +- id: string_004 + description: end + tests: + - feel-expression: '"d" between "b" and "d"' + expected: + result: + value: "true" + type: boolean +#- id: string_005 +# description: after +# tests: +# - feel-expression: '"e" between "b" and "d"' +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_001 +# description: before +# tests: +# - feel-expression: date("2018-12-01") between date("2018-12-02") and date("2018-12-04") +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_002 +# description: start +# tests: +# - feel-expression: date("2018-12-02") between date("2018-12-02") and date("2018-12-04") +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_003 +# description: between +# tests: +# - feel-expression: date("2018-12-03") between date("2018-12-02") and date("2018-12-04") +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_004 +# description: end +# tests: +# - feel-expression: date("2018-12-04") between date("2018-12-02") and date("2018-12-04") +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_005 +# description: after +# tests: +# - feel-expression: date("2018-12-05") between date("2018-12-02") and date("2018-12-04") +# expected: +# result: +# value: "false" +# type: boolean +- id: time_001 + description: before +# tests: +# - feel-expression: time("10:31:00") between time("10:32:00") and time("10:34:00") +# expected: +# result: +# value: "false" +# type: boolean +#- id: time_002 +# description: start +# tests: +# - feel-expression: time("10:32:00") between time("10:32:00") and time("10:34:00") +# expected: +# result: +# value: "true" +# type: boolean +#- id: time_003 +# description: between +# tests: +# - feel-expression: time("10:33:00") between time("10:32:00") and time("10:34:00") +# expected: +# result: +# value: "true" +# type: boolean +#- id: time_004 +# description: end +# tests: +# - feel-expression: time("10:34:00") between time("10:32:00") and time("10:34:00") +# expected: +# result: +# value: "true" +# type: boolean +#- id: time_005 +# description: after +# tests: +# - feel-expression: time("10:35:00") between time("10:32:00") and time("10:34:00") +# expected: +# result: +# value: "false" +# type: boolean +#- id: datetime_001 +# description: before +# tests: +# - feel-expression: date and time("2018-12-01T10:30:00") between date and time("2018-12-02T10:30:00") and date and time("2018-12-04T10:30:00") +# expected: +# result: +# value: "false" +# type: boolean +#- id: datetime_002 +# description: start +# tests: +# - feel-expression: date and time("2018-12-02T10:30:00") between date and time("2018-12-02T10:30:00") and date and time("2018-12-04T10:30:00") +# expected: +# result: +# value: "true" +# type: boolean +#- id: datetime_003 +# description: between +# tests: +# - feel-expression: date and time("2018-12-03T10:30:00") between date and time("2018-12-02T10:30:00") and date and time("2018-12-04T10:30:00") +# expected: +# result: +# value: "true" +# type: boolean +#- id: datetime_004 +# description: end +# tests: +# - feel-expression: date and time("2018-12-04T10:30:00") between date and time("2018-12-02T10:30:00") and date and time("2018-12-04T10:30:00") +# expected: +# result: +# value: "true" +# type: boolean +#- id: datetime_005 +# description: after +# tests: +# - feel-expression: date and time("2018-12-05T10:30:00") between date and time("2018-12-02T10:30:00") and date and time("2018-12-04T10:30:00") +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_001 +# description: before +# tests: +# - feel-expression: duration("P1Y") between duration("P2Y") and duration("P4Y") +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_002 +# description: start +# tests: +# - feel-expression: duration("P2Y") between duration("P2Y") and duration("P4Y") +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_003 +# description: between +# tests: +# - feel-expression: duration("P3Y") between duration("P2Y") and duration("P4Y") +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_004 +# description: end +# tests: +# - feel-expression: duration("P4Y") between duration("P2Y") and duration("P4Y") +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_005 +# description: after +# tests: +# - feel-expression: duration("P5Y") between duration("P2Y") and duration("P4Y") +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_001 +# description: before +# tests: +# - feel-expression: duration("P1D") between duration("P2D") and duration("P4D") +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_002 +# description: start +# tests: +# - feel-expression: duration("P2D") between duration("P2D") and duration("P4D") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_003 +# description: between +# tests: +# - feel-expression: duration("P3D") between duration("P2D") and duration("P4D") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_004 +# description: end +# tests: +# - feel-expression: duration("P4D") between duration("P2D") and duration("P4D") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_005 +# description: after +# tests: +# - feel-expression: duration("P5D") between duration("P2D") and duration("P4D") +# expected: +# result: +# value: "false" +# type: boolean +#- id: null_001 +# description: null test value +# tests: +# - feel-expression: null between 1 and 10 +# expected: +# result: +# value: null +#- id: null_002 +# description: null start value +# tests: +# - feel-expression: 2 between null and 10 +# expected: +# result: +# value: null +#- id: null_003 +# description: null end value +# tests: +# - feel-expression: 2 between 1 and null +# expected: +# result: +# value: null diff --git a/tests/feel-coercion.yaml b/tests/feel-coercion.yaml new file mode 100644 index 0000000..350325a --- /dev/null +++ b/tests/feel-coercion.yaml @@ -0,0 +1,296 @@ +#- id: decision_001 +# description: type mismatch - decision return value is null coerced +# tests: +# - feel-expression: 1+1 +# expected: +# result: +# value: null +#- id: decision_003 +# description: list type mismatch - decision return value is null coerced +# tests: +# - feel-expression: '[1,2,"foo"]' +# expected: +# result: +# value: null +- id: decision_004 + description: type permitted - conforming context + tests: + - feel-expression: '{name: "foo", surname: "bar", age: 10}' + expected: + components: + - name: name + expected: + result: + value: foo + type: string + - name: surname + expected: + result: + value: bar + type: string + - name: age + expected: + result: + value: "10" + type: decimal +#- id: decision_005 +# description: context type mismatch - decision return value is null coerced +# tests: +# - feel-expression: '{name: "foo"}' +# expected: +# result: +# value: null +#- id: decision_006_a +# description: decision type is list but return val is non-conforming val - coercion to null +# tests: +# - feel-expression: '"foo"' +# expected: +# result: +# value: null +#- id: decision_007 +# description: decision returns singleton list value but type is not a list - coercion list to val +# tests: +# - feel-expression: '["foo"]' +# expected: +# result: +# value: foo +# type: string +#- id: decision_007_a +# description: decision type is value but return val is non-conforming singleton list - coercion to null +# tests: +# - feel-expression: '[1]' +# expected: +# result: +# value: null +#- id: decision_008 +# description: decision type is list but return val null - null cannot be coerced so no singleton list coercion +# tests: +# - feel-expression: "null" +# expected: +# result: +# value: null +#- id: decision_bkm_001 +# description: pass conforming context type to bkm +# tests: +# - feel-expression: 'bkm_001({name: "foo", surname: "bar", age: 10})' +# expected: +# result: +# value: "true" +# type: boolean +#- id: decision_bkm_002 +# description: pass non-conforming type to bkm - bkm is never invoked +# tests: +# - feel-expression: 'bkm_001({name: "foo"})' +# expected: +# result: +# value: null +#- id: decision_bkm_003 +# description: BKM logic returns non-conforming value to bkm variable typeRef - bk result is null coerced +# tests: +# - feel-expression: 'bkm_002({name: "foo"})' +# expected: +# result: +# value: null +#- id: decision_bkm_004_a +# description: bkm type is list and bkm logic returns non-conforming (non-list) value - coercion to null +# tests: +# - feel-expression: bkm_004("foo") +# expected: +# result: +# value: null +#- id: decision_bkm_004_b +# description: bkm type is list and bkm logic returns null - null cannot be coerced to result remains null +# tests: +# - feel-expression: bkm_004(null) +# expected: +# result: +# value: null +#- id: decision_bkm_005 +# description: bkm type is non-list and bkm logic returns singleton list of conforming value - coercion list to val +# tests: +# - feel-expression: bkm_005(10) +# expected: +# result: +# value: "10" +# type: decimal +#- id: decision_bkm_005_a +# description: bkm type is non-list and bkm logic returns singleton list of non-conforming value - coercion to null +# tests: +# - feel-expression: bkm_005("foo") +# expected: +# result: +# value: null +- id: invoke_001 + description: |- + decision has invocation call to bkm passing + non-conforming context - bkm is never invoked + tests: + - feel-expression: "" + expected: + result: + value: null +- id: invoke_002 + description: "decision has invocation of bkm passing valid param, but bkm return value\n does not match explicit type on invocation defn - null coercion of result\n of invocation " + tests: + - feel-expression: "" + expected: + result: + value: null +- id: invoke_004 + description: invocation type is a list and invoked bkm returns single non-conforming value - coercion to null + tests: + - feel-expression: "" + expected: + result: + value: null +- id: invoke_005 + description: "Ref https://github.com/dmn-tck/tck/pull/238#issuecomment-497744315\n \n " + tests: + - feel-expression: "" + expected: + result: + value: null +- id: invoke_006 + description: invocation type is a non-list and invoked bkm returns singleton array of non-conforming value - coercion to null + tests: + - feel-expression: "" + expected: + result: + value: null +- id: invoke_007 + description: |- + invocation has binding name that is not a valid formal param name - + function is never invoked + tests: + - feel-expression: "" + expected: + result: + value: null +#- id: fd_001 +# description: function definition has typed param and is passed a conforming type - no coercion +# tests: +# - feel-expression: "" +# expected: +# result: +# value: "10" +# type: decimal +- id: fd_002 + description: function definition has typed param and is passed non-conforming type - coercion to null + tests: + - feel-expression: "" + expected: + result: + value: null +- id: literal_001 + description: literal expression has typeRef and result is conforming value - no coercion + tests: + - feel-expression: 5+5 + expected: + result: + value: "10" + type: decimal +#- id: literal_002 +# description: literal expression has typeRef and result is non-conforming value - coercion to null +# tests: +# - feel-expression: '"foo"' +# expected: +# result: +# value: null +#- id: literal_004 +# description: literal expression has list typeRef and result is non-conforming value - coercion to null +# tests: +# - feel-expression: '"foo"' +# expected: +# result: +# value: null +#- id: literal_005 +# description: literal expression has non-list typeRef and result is conforming singleton list - coercion to value +# tests: +# - feel-expression: '[10]' +# expected: +# result: +# value: "10" +# type: decimal +#- id: literal_006 +# description: literal expression has non-list typeRef and result is non-conforming singleton list - coercion to null +# tests: +# - feel-expression: '["foo"]' +# expected: +# result: +# value: null +#- id: decisionService_001 +# description: 'Direct invocation: Decision service returns context that does not confirm to type' +# tests: +# - feel-expression: "1000" +# expected: +# result: +# value: null +#- id: decisionService_002 +# description: 'Direct invocation: Decision service has string input but we pass incorrect type - input is coerced to null' +# tests: +# - feel-expression: decisionService_002_input_1 +# expected: +# result: +# value: null +#- id: decisionService_002_a +# description: 'Indirect invocation: Decision Service has string input but we pass incorrect type - input is coerced to null' +# tests: +# - feel-expression: decisionService_002(10) +# expected: +# result: +# value: null +#- id: decisionService_002_b +# description: 'Direct invocation: Decision service has string input but we pass in singleton list of correct type - input is coerced to string' +# tests: +# - feel-expression: decisionService_002_input_1 +# expected: +# result: +# value: foo +# type: string +#- id: decisionService_002_c +# description: 'Indirect invocation: Decision service has string input but we pass in singleton list of correct type - input is coerced to string' +# tests: +# - feel-expression: decisionService_002(["foo"]) +# expected: +# result: +# value: foo +# type: string +#- id: decision_context_01 +# description: Value of context() equivalentTo the decision typeRef +# tests: +# - feel-expression: 'context(entries: [{key:"a", value:1}, {key:"b", value:2}])' +# expected: +# components: +# - name: a +# expected: +# result: +# value: "1" +# type: decimal +# - name: b +# expected: +# result: +# value: "2" +# type: decimal +#- id: decision_context_02 +# description: Value of context() conformsTo the decision typeRef +# tests: +# - feel-expression: 'context(entries: [{key:"a", value:1}, {key:"b", value:2}])' +# expected: +# components: +# - name: a +# expected: +# result: +# value: "1" +# type: decimal +# - name: b +# expected: +# result: +# value: "2" +# type: decimal +#- id: decision_context_03 +# description: Value of context() does not conformsTo the decision typeRef +# tests: +# - feel-expression: 'context(entries: [{key:"a", value:1}, {key:"b", value:2}])' +# expected: +# result: +# value: null diff --git a/tests/feel-comments.yaml b/tests/feel-comments.yaml new file mode 100644 index 0000000..32f1a2e --- /dev/null +++ b/tests/feel-comments.yaml @@ -0,0 +1,24 @@ +- id: decision_001 + description: "" + tests: + - feel-expression: 1 + /* 1 + */ 1 + expected: + result: + value: "2" + type: decimal +- id: decision_002 + description: "" + tests: + - feel-expression: "1 + // eol comment\n 1\n " + expected: + result: + value: "2" + type: decimal +- id: decision_003 + description: "" + tests: + - feel-expression: "\n /*\n some intro waffle\n */\n 1 + 1 // and stuff\n " + expected: + result: + value: "2" + type: decimal diff --git a/tests/feel-conjunction.yaml b/tests/feel-conjunction.yaml new file mode 100644 index 0000000..1da505c --- /dev/null +++ b/tests/feel-conjunction.yaml @@ -0,0 +1,143 @@ +- id: "001" + description: "" + tests: + - feel-expression: true and true + expected: + result: + value: "true" + type: boolean +- id: "002" + description: "" + tests: + - feel-expression: true and false + expected: + result: + value: "false" + type: boolean +#- id: 003_a +# description: "" +# tests: +# - feel-expression: true and null +# expected: +# result: +# value: null +#- id: 003_b +# description: "" +# tests: +# - feel-expression: true and 123 +# expected: +# result: +# value: null +#- id: 003_c +# description: "" +# tests: +# - feel-expression: true and "true" +# expected: +# result: +# value: null +- id: "004" + description: "" + tests: + - feel-expression: false and true + expected: + result: + value: "false" + type: boolean +- id: "005" + description: "" + tests: + - feel-expression: false and false + expected: + result: + value: "false" + type: boolean +- id: 006_a + description: "" + tests: + - feel-expression: false and null + expected: + result: + value: "false" + type: boolean +- id: 006_b + description: "" + tests: + - feel-expression: false and 123 + expected: + result: + value: "false" + type: boolean +- id: 006_c + description: "" + tests: + - feel-expression: false and "true" + expected: + result: + value: "false" + type: boolean +#- id: 007_a +# description: "" +# tests: +# - feel-expression: null and true +# expected: +# result: +# value: null +#- id: 007_b +# description: "" +# tests: +# - feel-expression: 123 and true +# expected: +# result: +# value: null +#- id: 007_c +# description: "" +# tests: +# - feel-expression: '"true" and true' +# expected: +# result: +# value: null +- id: 008_a + description: "" + tests: + - feel-expression: null and false + expected: + result: + value: "false" + type: boolean +- id: 008_b + description: "" + tests: + - feel-expression: 123 and false + expected: + result: + value: "false" + type: boolean +- id: 008_c + description: "" + tests: + - feel-expression: '"true" and false' + expected: + result: + value: "false" + type: boolean +#- id: 009_a +# description: "" +# tests: +# - feel-expression: null and null +# expected: +# result: +# value: null +#- id: 009_b +# description: "" +# tests: +# - feel-expression: '"true" and "true"' +# expected: +# result: +# value: null +#- id: 009_c +# description: "" +# tests: +# - feel-expression: 0 and 0 +# expected: +# result: +# value: null diff --git a/tests/feel-constants-boolean.yaml b/tests/feel-constants-boolean.yaml new file mode 100644 index 0000000..14c8305 --- /dev/null +++ b/tests/feel-constants-boolean.yaml @@ -0,0 +1,13 @@ +- id: "001" + description: Tests FEEL boolean constants + tests: + - feel-expression: "true" + expected: + result: + value: "true" + type: boolean + - feel-expression: "false" + expected: + result: + value: "false" + type: boolean diff --git a/tests/feel-constants-decimal.yaml b/tests/feel-constants-decimal.yaml new file mode 100644 index 0000000..4d540fa --- /dev/null +++ b/tests/feel-constants-decimal.yaml @@ -0,0 +1,48 @@ +#- id: "001" +# description: Tests FEEL decimal number constant +# tests: +# - feel-expression: ".872" +# expected: +# result: +# value: "0.872" +# type: decimal +#- id: "002" +# description: Tests FEEL negative decimal number constant +# tests: +# - feel-expression: "-.872" +# expected: +# result: +# value: "-0.872" +# type: decimal +- id: "004" + description: Tests FEEL number constant + tests: + - feel-expression: "50" + expected: + result: + value: "50" + type: decimal +- id: "005" + description: Tests FEEL negative number constant + tests: + - feel-expression: "-50" + expected: + result: + value: "-50" + type: decimal +- id: "007" + description: Tests FEEL decimal number constant + tests: + - feel-expression: "125.4321987654" + expected: + result: + value: "125.4321987654" + type: decimal +- id: "008" + description: Tests FEEL negative decimal number constant + tests: + - feel-expression: "-125.4321987654" + expected: + result: + value: "-125.4321987654" + type: decimal diff --git a/tests/feel-constants-string.yaml b/tests/feel-constants-string.yaml new file mode 100644 index 0000000..49d7725 --- /dev/null +++ b/tests/feel-constants-string.yaml @@ -0,0 +1,32 @@ +- id: "001" + description: Tests FEEL string constants + tests: + - feel-expression: '"foo bar"' + expected: + result: + value: foo bar + type: string +- id: "002" + description: Tests FEEL unicode string constant + tests: + - feel-expression: '"šomeÚnicodeŠtriňg"' + expected: + result: + value: šomeÚnicodeŠtriňg + type: string +- id: "003" + description: Tests FEEL unicode string constant + tests: + - feel-expression: '"横綱"' + expected: + result: + value: 横綱 + type: string +- id: "004" + description: Tests FEEL long string constant + tests: + - feel-expression: '"thisIsSomeLongStringThatMustBeProcessedSoHopefullyThisTestPassWithItAndIMustWriteSomethingMoreSoItIsLongerAndLongerAndLongerAndLongerAndLongerTillItIsReallyLong"' + expected: + result: + value: thisIsSomeLongStringThatMustBeProcessedSoHopefullyThisTestPassWithItAndIMustWriteSomethingMoreSoItIsLongerAndLongerAndLongerAndLongerAndLongerTillItIsReallyLong + type: string diff --git a/tests/feel-constants.yaml~ b/tests/feel-constants.yaml~ new file mode 100644 index 0000000..a53a0c1 --- /dev/null +++ b/tests/feel-constants.yaml~ @@ -0,0 +1,28 @@ +- description: Tests FEEL string constants + tests: + - feel-expression: '"foo bar"' + expected: + result: + value: foo bar + type: string +- description: Tests FEEL unicode string constant + tests: + - feel-expression: '"šomeÚnicodeŠtriňg"' + expected: + result: + value: šomeÚnicodeŠtriňg + type: string +- description: Tests FEEL unicode string constant + tests: + - feel-expression: '"横綱"' + expected: + result: + value: 横綱 + type: string +- description: Tests FEEL long string constant + tests: + - feel-expression: '"thisIsSomeLongStringThatMustBeProcessedSoHopefullyThisTestPassWithItAndIMustWriteSomethingMoreSoItIsLongerAndLongerAndLongerAndLongerAndLongerTillItIsReallyLong"' + expected: + result: + value: thisIsSomeLongStringThatMustBeProcessedSoHopefullyThisTestPassWithItAndIMustWriteSomethingMoreSoItIsLongerAndLongerAndLongerAndLongerAndLongerTillItIsReallyLong + type: string diff --git a/tests/feel-contains-function.yaml b/tests/feel-contains-function.yaml new file mode 100644 index 0000000..4c61536 --- /dev/null +++ b/tests/feel-contains-function.yaml @@ -0,0 +1,77 @@ +#- id: 001_2a4d7448c6 +# description: "" +# tests: +# - feel-expression: contains(null,null) +# expected: +# result: +# value: null +#- id: 002_d2a1831b5c +# description: "" +# tests: +# - feel-expression: contains(null,"bar") +# expected: +# result: +# value: null +#- id: 003_df56e0a1ad +# description: "" +# tests: +# - feel-expression: contains("bar",null) +# expected: +# result: +# value: null +- id: 004_805503b274 + description: "" + tests: + - feel-expression: contains("foobar","bar") + expected: + result: + value: "true" + type: boolean +- id: 005_5c1269db16 + description: "" + tests: + - feel-expression: contains("foobar","o") + expected: + result: + value: "true" + type: boolean +- id: 006_babdaf4f36 + description: "" + tests: + - feel-expression: contains("abc","") + expected: + result: + value: "true" + type: boolean +- id: 007_d24a599180 + description: "" + tests: + - feel-expression: contains("","ab") + expected: + result: + value: "false" + type: boolean +- id: 008_cf1311586a + description: "" + tests: + - feel-expression: contains("","") + expected: + result: + value: "true" + type: boolean +- id: 009_c4b50ad623 + description: "" + tests: + - feel-expression: contains(string:"foobar",match:"bar") + expected: + result: + value: "true" + type: boolean +- id: 010_9ae03e0e59 + description: "" + tests: + - feel-expression: contains(string:"foobar",match:"b") + expected: + result: + value: "true" + type: boolean diff --git a/tests/feel-context-merge-function.yaml b/tests/feel-context-merge-function.yaml new file mode 100644 index 0000000..635b59d --- /dev/null +++ b/tests/feel-context-merge-function.yaml @@ -0,0 +1,135 @@ +- id: "001" + description: Will merge a context + tests: + - feel-expression: 'context merge([{"a": 1}])' + expected: + components: + - name: a + expected: + result: + value: "1" + type: decimal +- id: 001_a + description: Will merge empty context + tests: + - feel-expression: context merge([{}]) = {} + expected: + result: + value: "true" + type: boolean +- id: "002" + description: Will merge multiple contexts + tests: + - feel-expression: 'context merge([{"a": 1}, {"b": 2}])' + expected: + components: + - name: a + expected: + result: + value: "1" + type: decimal + - name: b + expected: + result: + value: "2" + type: decimal +- id: "003" + description: Will overwrite existing context entry + tests: + - feel-expression: 'context merge([{"a": 1}, {"a": 2}])' + expected: + components: + - name: a + expected: + result: + value: "2" + type: decimal +- id: "004" + description: Will overwrite (not merge) nested contexts + tests: + - feel-expression: 'context merge([{"a": {"aa": 1}}, {"a": {"bb": 2}}])' + expected: + components: + - name: a + expected: + components: + - name: bb + expected: + result: + value: "2" + type: decimal +#- id: "005" +# description: Null contexts param gives null +# tests: +# - feel-expression: context merge(null) +# expected: +# result: +# value: null +#- id: "006" +# description: Too few params gives null +# tests: +# - feel-expression: context merge() +# expected: +# result: +# value: null +#- id: "007" +# description: Too many params gives null +# tests: +# - feel-expression: context merge([],"foo") +# expected: +# result: +# value: null +#- id: "008" +# description: named params +# tests: +# - feel-expression: 'context merge(contexts: [{"a": 1}])' +# expected: +# components: +# - name: a +# expected: +# result: +# value: "1" +# type: decimal +#- id: "009" +# description: Incorrect named param gives null +# tests: +# - feel-expression: 'context merge(context: [{"a": 1}])' +# expected: +# result: +# value: null +#- id: "010" +# description: Incorrect 'contexts' type gives null +# tests: +# - feel-expression: context merge([1,2,3]) +# expected: +# result: +# value: null +#- id: "011" +# description: Non-context entry in 'contexts' gives null +# tests: +# - feel-expression: 'context merge([{"a": 1},2,{"b": 2}])' +# expected: +# result: +# value: null +#- id: "012" +# description: Will coerce single context to list +# tests: +# - feel-expression: 'context merge({"a": 1})' +# expected: +# components: +# - name: a +# expected: +# result: +# value: "1" +# type: decimal +#- id: "013" +# description: Will coerce single name param entry to list +# tests: +# - feel-expression: 'context merge(contexts: {"a": 1})' +# expected: +# components: +# - name: a +# expected: +# result: +# value: "1" +# type: decimal diff --git a/tests/feel-context-put-function.yaml b/tests/feel-context-put-function.yaml new file mode 100644 index 0000000..5937eab --- /dev/null +++ b/tests/feel-context-put-function.yaml @@ -0,0 +1,406 @@ +- id: "001" + description: Will add context entry + tests: + - feel-expression: context put({}, "a", 1) + expected: + components: + - name: a + expected: + result: + value: "1" + type: decimal +#- id: "002" +# description: Will add entry to end of context +# tests: +# - feel-expression: 'get entries(context put({"a": 1}, "b", 2))' +# expected: +# results: +# - components: +# - name: key +# expected: +# result: +# value: a +# type: string +# - name: value +# expected: +# result: +# value: "1" +# type: decimal +# - components: +# - name: key +# expected: +# result: +# value: b +# type: string +# - name: value +# expected: +# result: +# value: "2" +# type: decimal +- id: "003" + description: Will overwrite existing context entry + tests: + - feel-expression: 'context put({"a": 1}, "a", 2)' + expected: + components: + - name: a + expected: + result: + value: "2" + type: decimal +- id: 003_a + description: Will maintain key order when overwriting existing context entry + tests: + - feel-expression: context put({"a":1, "b":2, "c":3 }, "b", 3) + expected: + components: + - name: a + expected: + result: + value: "1" + type: decimal + - name: b + expected: + result: + value: "3" + type: decimal + - name: c + expected: + result: + value: "3" + type: decimal +- id: "004" + description: Will permit empty key param + tests: + - feel-expression: context put({}, "", 1) + expected: + components: + - name: "" + expected: + result: + value: "1" + type: decimal +#- id: "005" +# description: Null key param gives null +# tests: +# - feel-expression: context put({}, null, 1) +# expected: +# result: +# value: null +#- id: "006" +# description: Null context param gives null +# tests: +# - feel-expression: context put(null, "a", 1) +# expected: +# result: +# value: null +#- id: "007" +# description: Will permit null value param +# tests: +# - feel-expression: context put({}, "a", null) +# expected: +# components: +# - name: a +# expected: +# result: +# value: null +#- id: "008" +# description: Too few params gives null +# tests: +# - feel-expression: context put({}, "a") +# expected: +# result: +# value: null +#- id: "009" +# description: Too many params gives null +# tests: +# - feel-expression: context put({}, "a", 1, 1) +# expected: +# result: +# value: null +- id: "010" + description: named params + tests: + - feel-expression: 'context put(context: {}, key: "a", value: 1)' + expected: + components: + - name: a + expected: + result: + value: "1" + type: decimal +#- id: "011" +# description: Incorrect named param gives null +# tests: +# - feel-expression: 'context put(context: {}, ky: "a", value: 1)' +# expected: +# result: +# value: null +#- id: "012" +# description: Incorrect 'context' type gives null +# tests: +# - feel-expression: context put([], "a", 1) +# expected: +# result: +# value: null +#- id: "013" +# description: Will return null when key is not a string +# tests: +# - feel-expression: context put({}, 1, 1) +# expected: +# result: +# value: null +- id: "014" + description: Will operate on boxed context + tests: + - feel-expression: context put(context01, "a", 2) + expected: + components: + - name: a + expected: + result: + value: "2" + type: decimal +#- id: "015" +# description: Will create new copy of boxed context, not mutate it +# tests: +# - feel-expression: "" +# expected: +# components: +# - name: context01 +# expected: +# components: +# - name: a +# expected: +# result: +# value: "1" +# type: decimal +# - name: copied +# expected: +# components: +# - name: a +# expected: +# result: +# value: "2" +# type: decimal +#- id: "016" +# description: Will create new copy of literal context, not mutate it +# tests: +# - feel-expression: "" +# expected: +# components: +# - name: original +# expected: +# components: +# - name: a +# expected: +# result: +# value: "1" +# type: decimal +# - name: copied +# expected: +# components: +# - name: a +# expected: +# result: +# value: "2" +# type: decimal +- id: nested001 + description: will overwrite value in nested context + tests: + - feel-expression: 'context put({x:1, y: {a: 0} }, ["y", "a"], 2)' + expected: + components: + - name: x + expected: + result: + value: "1" + type: decimal + - name: "y" + expected: + components: + - name: a + expected: + result: + value: "2" + type: decimal +- id: nested001_a + description: will add value to nested context + tests: + - feel-expression: 'context put({x:1, y: {a: 0} }, ["y", "b"], 2)' + expected: + components: + - name: x + expected: + result: + value: "1" + type: decimal + - name: "y" + expected: + components: + - name: a + expected: + result: + value: "0" + type: decimal + - name: b + expected: + result: + value: "2" + type: decimal +#- id: nested002 +# description: null key gives null (1) +# tests: +# - feel-expression: 'context put({x:1, y: {a: 0} }, ["y", null], 2)' +# expected: +# result: +# value: null +#- id: nested003 +# description: null key gives null (2) +# tests: +# - feel-expression: 'context put({x:1, y: {a: 0} }, [null, "a"], 2)' +# expected: +# result: +# value: null +#- id: nested004 +# description: null key gives null (3) +# tests: +# - feel-expression: 'context put({x:1, y: {a: 0} }, [null], 2)' +# expected: +# result: +# value: null +#- id: nested005 +# description: empty keys array gives null +# tests: +# - feel-expression: 'context put({x:1, y: {a: 0} }, [], 2)' +# expected: +# result: +# value: null +- id: nested006 + description: will recurse into nested contexts + tests: + - feel-expression: 'context put({x:1, y: {a: {b: {c: 1}} }}, ["y", "a", "b", "c"], 2)' + expected: + components: + - name: x + expected: + result: + value: "1" + type: decimal + - name: "y" + expected: + components: + - name: a + expected: + components: + - name: b + expected: + components: + - name: c + expected: + result: + value: "2" + type: decimal +#- id: nested007 +# description: named params - with 'keys' +# tests: +# - feel-expression: 'context put(context: {x:1, y: {a: 0} }, keys: ["y", "a"], value: 2)' +# expected: +# components: +# - name: x +# expected: +# result: +# value: "1" +# type: decimal +# - name: "y" +# expected: +# components: +# - name: a +# expected: +# result: +# value: "2" +# type: decimal +#- id: nested008 +# description: named params - array value for 'key' gives null +# tests: +# - feel-expression: 'context put(context: {x:1, y: {a: 0} }, key: ["y", "a"], value: 2)' +# expected: +# result: +# value: null +#- id: nested009 +# description: named params - array value for 'key' gives null +# tests: +# - feel-expression: 'context put({x:1, y: {a: 0}}, ["y", "a", "b", "c"], 2)' +# expected: +# result: +# value: null +- id: nested010 + description: Will operate on boxed context + tests: + - feel-expression: context put(nestedContext01, ["a", "b"], 2) + expected: + components: + - name: a + expected: + components: + - name: b + expected: + result: + value: "2" + type: decimal +#- id: nested011 +# description: Will create new copy of nested boxed context, not mutate it +# tests: +# - feel-expression: "" +# expected: +# components: +# - name: nestedContext01 +# expected: +# components: +# - name: a +# expected: +# components: +# - name: b +# expected: +# result: +# value: "1" +# type: decimal +# - name: copied +# expected: +# components: +# - name: a +# expected: +# components: +# - name: b +# expected: +# result: +# value: "2" +# type: decimal +#- id: nested012 +# description: Will create new copy of nested literal context, not mutate it +# tests: +# - feel-expression: "" +# expected: +# components: +# - name: original +# expected: +# components: +# - name: a +# expected: +# components: +# - name: b +# expected: +# result: +# value: "1" +# type: decimal +# - name: copied +# expected: +# components: +# - name: a +# expected: +# components: +# - name: b +# expected: +# result: +# value: "2" +# type: decimal diff --git a/tests/feel-context.yaml b/tests/feel-context.yaml new file mode 100644 index 0000000..5ef2b81 --- /dev/null +++ b/tests/feel-context.yaml @@ -0,0 +1,148 @@ +- id: "001" + description: creation of simple context + tests: + - feel-expression: '{a: "foo", b: "bar"}' + expected: + components: + - name: a + expected: + result: + value: foo + type: string + - name: b + expected: + result: + value: bar + type: string +- id: "002" + description: nested context + tests: + - feel-expression: '{a: "foo", b: {c: "bar", d: {e: "baz"}}}' + expected: + components: + - name: a + expected: + result: + value: foo + type: string + - name: b + expected: + components: + - name: c + expected: + result: + value: bar + type: string + - name: d + expected: + components: + - name: e + expected: + result: + value: baz + type: string +#- id: "003" +# description: previous entries in scope for later entries +# tests: +# - feel-expression: '{a: 1 + 2, b: a + 3}' +# expected: +# components: +# - name: a +# expected: +# result: +# value: "3" +# type: decimal +# - name: b +# expected: +# result: +# value: "6" +# type: decimal +#- id: 003_a +# description: previous entries in scope for later (nested) entries +# tests: +# - feel-expression: '{a: 1 + 2, b: 3, c: {d: a + b}}' +# expected: +# components: +# - name: a +# expected: +# result: +# value: "3" +# type: decimal +# - name: b +# expected: +# result: +# value: "3" +# type: decimal +# - name: c +# expected: +# components: +# - name: d +# expected: +# result: +# value: "6" +# type: decimal +- id: "004" + description: spaces permitted in name + tests: + - feel-expression: '{foo bar: "foo"}' + expected: + components: + - name: foo bar + expected: + result: + value: foo + type: string +#- id: "005" +# description: extra chars permtted in name +# tests: +# - feel-expression: '{foo+bar: "foo"}' +# expected: +# components: +# - name: foo+bar +# expected: +# result: +# value: foo +# type: string +- id: "006" + description: string literal permitted as name + tests: + - feel-expression: '{"foo+bar((!!],foo": "foo"}' + expected: + components: + - name: foo+bar((!!],foo + expected: + result: + value: foo + type: string +- id: "007" + description: empty string literal permitted as name + tests: + - feel-expression: '{"": "foo"}' + expected: + components: + - name: "" + expected: + result: + value: foo + type: string +#- id: "008" +# description: duplicate context entry keys not allowed (DMN14-178), results in null +# tests: +# - feel-expression: '{foo: "bar", foo: "baz"}' +# expected: +# result: +# value: null +#- id: "009" +# description: non-existing member access results in null +# tests: +# - feel-expression: '{ a: 1 }.b' +# expected: +# result: +# value: null +#- id: "010" +# description: non-existing member access (on null) +# tests: +# - feel-expression: null.b +# expected: +# result: +# value: null diff --git a/tests/feel-date-and-time-function.yaml b/tests/feel-date-and-time-function.yaml new file mode 100644 index 0000000..eefaebe --- /dev/null +++ b/tests/feel-date-and-time-function.yaml @@ -0,0 +1,667 @@ +#- id: 001_05fd7d6215 +# description: "" +# tests: +# - feel-expression: date and time(null) +# expected: +# result: +# value: null +#- id: 002_8c66ed2d1a +# description: "" +# tests: +# - feel-expression: date and time(null,null) +# expected: +# result: +# value: null +#- id: 003_335cff371a +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-08-10T10:20:00"),null) +# expected: +# result: +# value: null +#- id: 004_28ef3e7882 +# description: "" +# tests: +# - feel-expression: date and time(date("2017-08-10"),null) +# expected: +# result: +# value: null +#- id: 005_15df95b27a +# description: "" +# tests: +# - feel-expression: date and time(null,time("23:59:01")) +# expected: +# result: +# value: null +#- id: 006_8c794da0bb +# description: "" +# tests: +# - feel-expression: date and time() +# expected: +# result: +# value: null +#- id: 007_59863d1b57 +# description: "" +# tests: +# - feel-expression: date and time("2012-12-24") +# expected: +# result: +# value: 2012-12-24T00:00:00 +# type: dateTime +- id: 008_83eb9a93ba + description: "" + tests: + - feel-expression: date and time("2017-12-31T00:00:00") + expected: + result: + value: 2017-12-31T00:00:00 + type: dateTime +- id: 009_1982fa549c + description: "" + tests: + - feel-expression: date and time("2017-12-31T11:22:33") + expected: + result: + value: 2017-12-31T11:22:33 + type: dateTime +#- id: 010_59f5b47012 +# description: "" +# tests: +# - feel-expression: date and time("-2017-12-31T11:22:33") +# expected: +# result: +# value: -2017-12-31T11:22:33 +# type: dateTime +#- id: 011_eec2d5bdcd +# description: "" +# tests: +# - feel-expression: string(date and time("99999-12-31T11:22:33")) +# expected: +# result: +# value: 99999-12-31T11:22:33 +# type: string +#- id: 012_225a105eef +# description: "" +# tests: +# - feel-expression: string(date and time("-99999-12-31T11:22:33")) +# expected: +# result: +# value: -99999-12-31T11:22:33 +# type: string +- id: 013_c4fd0a0e8d + description: "" + tests: + - feel-expression: date and time("2017-12-31T11:22:33.345") + expected: + result: + value: 2017-12-31T11:22:33.345 + type: dateTime +- id: 014_ded0e5fe2f + description: "" + tests: + - feel-expression: date and time("2017-12-31T11:22:33.123456789") + expected: + result: + value: 2017-12-31T11:22:33.123456789 + type: dateTime +#- id: 015_9e27148afd +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T11:22:33Z") +# expected: +# result: +# value: "2017-12-31T11:22:33Z" +# type: dateTime +#- id: 016_c08e4d417a +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T11:22:33.567Z") +# expected: +# result: +# value: "2017-12-31T11:22:33.567Z" +# type: dateTime +- id: 017_47816add0e + description: "" + tests: + - feel-expression: date and time("2017-12-31T11:22:33+01:00") + expected: + result: + value: "2017-12-31T11:22:33+01:00" + type: dateTime +- id: 018_0614e473e7 + description: "" + tests: + - feel-expression: date and time("2017-12-31T11:22:33-02:00") + expected: + result: + value: "2017-12-31T11:22:33-02:00" + type: dateTime +- id: 019_c312e3dfe3 + description: "" + tests: + - feel-expression: date and time("2017-12-31T11:22:33+01:35") + expected: + result: + value: "2017-12-31T11:22:33+01:35" + type: dateTime +- id: 020_29e0585b6f + description: "" + tests: + - feel-expression: date and time("2017-12-31T11:22:33-01:35") + expected: + result: + value: "2017-12-31T11:22:33-01:35" + type: dateTime +- id: 021_99f0215b60 + description: "" + tests: + - feel-expression: date and time("2017-12-31T11:22:33.456+01:35") + expected: + result: + value: "2017-12-31T11:22:33.456+01:35" + type: dateTime +#- id: 022_b8b20f0328 +# description: "" +# tests: +# - feel-expression: date and time("-2017-12-31T11:22:33.456+01:35") +# expected: +# result: +# value: -2017-12-31T11:22:33.456+01:35 +# type: dateTime +#- id: 023_2e41497673 +# description: "" +# tests: +# - feel-expression: string(date and time("2011-12-31T10:15:30@Europe/Paris")) +# expected: +# result: +# value: 2011-12-31T10:15:30@Europe/Paris +# type: string +#- id: 024_b4d1fb8735 +# description: "" +# tests: +# - feel-expression: string(date and time("2011-12-31T10:15:30@Etc/UTC")) +# expected: +# result: +# value: 2011-12-31T10:15:30@Etc/UTC +# type: string +#- id: 025_0cb7f83ec6 +# description: "" +# tests: +# - feel-expression: string(date and time("2011-12-31T10:15:30.987@Europe/Paris")) +# expected: +# result: +# value: 2011-12-31T10:15:30.987@Europe/Paris +# type: string +#- id: 026_5ba081cd5f +# description: "" +# tests: +# - feel-expression: string(date and time("2011-12-31T10:15:30.123456789@Europe/Paris")) +# expected: +# result: +# value: 2011-12-31T10:15:30.123456789@Europe/Paris +# type: string +#- id: 027_ae365197dd +# description: "" +# tests: +# - feel-expression: string(date and time("999999999-12-31T23:59:59.999999999@Europe/Paris")) +# expected: +# result: +# value: 999999999-12-31T23:59:59.999999999@Europe/Paris +# type: string +#- id: 028_1c3d56275f +# description: "" +# tests: +# - feel-expression: string(date and time("-999999999-12-31T23:59:59.999999999+02:00")) +# expected: +# result: +# value: -999999999-12-31T23:59:59.999999999+02:00 +# type: string +#- id: 029_e3a5e786a0 +# description: "" +# tests: +# - feel-expression: date and time(date("2017-01-01"),time("23:59:01")) +# expected: +# result: +# value: 2017-01-01T23:59:01 +# type: dateTime +#- id: 030_2f97bff606 +# description: "" +# tests: +# - feel-expression: date and time(date("2017-01-01"),time("23:59:01Z")) +# expected: +# result: +# value: "2017-01-01T23:59:01Z" +# type: dateTime +#- id: 031_61e70c285f +# description: "" +# tests: +# - feel-expression: date and time(date("2017-01-01"),time("23:59:01+02:00")) +# expected: +# result: +# value: "2017-01-01T23:59:01+02:00" +# type: dateTime +#- id: 032_1e95e8726e +# description: "" +# tests: +# - feel-expression: string(date and time(date("2017-01-01"),time("23:59:01@Europe/Paris"))) +# expected: +# result: +# value: 2017-01-01T23:59:01@Europe/Paris +# type: string +#- id: 033_2fac4d6807 +# description: "" +# tests: +# - feel-expression: string(date and time(date("2017-01-01"),time("23:59:01.123456789@Europe/Paris"))) +# expected: +# result: +# value: 2017-01-01T23:59:01.123456789@Europe/Paris +# type: string +#- id: 034_75580be3aa +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-08-10T10:20:00"),time("23:59:01")) +# expected: +# result: +# value: 2017-08-10T23:59:01 +# type: dateTime +#- id: 035_831b1ad0c5 +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-08-10T10:20:00"),time("23:59:01.987654321")) +# expected: +# result: +# value: 2017-08-10T23:59:01.987654321 +# type: dateTime +#- id: 036_189e1c3095 +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-09-05T10:20:00"),time("09:15:30+02:00")) +# expected: +# result: +# value: "2017-09-05T09:15:30+02:00" +# type: dateTime +#- id: 037_c7aec7ecf7 +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-09-05T10:20:00"),time("09:15:30Z")) +# expected: +# result: +# value: "2017-09-05T09:15:30Z" +# type: dateTime +#- id: 038_1493e6d873 +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-09-05T10:20:00"),time("09:15:30.987654321+02:00")) +# expected: +# result: +# value: "2017-09-05T09:15:30.987654321+02:00" +# type: dateTime +#- id: 039_593292b25c +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-09-05T10:20:00"),time("09:15:30.123456Z")) +# expected: +# result: +# value: "2017-09-05T09:15:30.123456Z" +# type: dateTime +#- id: 040_d9116e1daa +# description: "" +# tests: +# - feel-expression: string(date and time(date and time("2017-09-05T10:20:00"),time("09:15:30.987654321@Europe/Paris"))) +# expected: +# result: +# value: 2017-09-05T09:15:30.987654321@Europe/Paris +# type: string +#- id: 041_c6decfe6a3 +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-08-10T10:20:00+02:00"),time("23:59:01")) +# expected: +# result: +# value: 2017-08-10T23:59:01 +# type: dateTime +#- id: 042_0cbcc3d1dc +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-08-10T10:20:00+02:00"),time("23:59:01.987654321")) +# expected: +# result: +# value: 2017-08-10T23:59:01.987654321 +# type: dateTime +#- id: 043_2e4177d00c +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-09-05T10:20:00-01:00"),time("09:15:30+02:00")) +# expected: +# result: +# value: "2017-09-05T09:15:30+02:00" +# type: dateTime +#- id: 044_9404547f9d +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-09-05T10:20:00-01:00"),time("09:15:30Z")) +# expected: +# result: +# value: "2017-09-05T09:15:30Z" +# type: dateTime +#- id: 045_5d93a541eb +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-09-05T10:20:00+02:00"),time("09:15:30.987654321+02:00")) +# expected: +# result: +# value: "2017-09-05T09:15:30.987654321+02:00" +# type: dateTime +#- id: 046_89c1cd8daa +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-09-05T10:20:00+02:00"),time("09:15:30.123456Z")) +# expected: +# result: +# value: "2017-09-05T09:15:30.123456Z" +# type: dateTime +#- id: 047_60ea7838ce +# description: "" +# tests: +# - feel-expression: string(date and time(date and time("2017-09-05T10:20:00-01:00"),time("09:15:30.987654321@Europe/Paris"))) +# expected: +# result: +# value: 2017-09-05T09:15:30.987654321@Europe/Paris +# type: string +#- id: 048_e387922273 +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-08-10T10:20:00@Europe/Paris"),time("23:59:01")) +# expected: +# result: +# value: 2017-08-10T23:59:01 +# type: dateTime +#- id: 049_eb9cd1f777 +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-08-10T10:20:00@Europe/Paris"),time("23:59:01.987654321")) +# expected: +# result: +# value: 2017-08-10T23:59:01.987654321 +# type: dateTime +#- id: 050_2d960354af +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-09-05T10:20:00@Europe/Paris"),time("09:15:30+02:00")) +# expected: +# result: +# value: "2017-09-05T09:15:30+02:00" +# type: dateTime +#- id: 051_46bdaa00b0 +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-09-05T10:20:00@Europe/Paris"),time("09:15:30Z")) +# expected: +# result: +# value: "2017-09-05T09:15:30Z" +# type: dateTime +#- id: 052_911dbd0a24 +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-09-05T10:20:00@Europe/Paris"),time("09:15:30.987654321+02:00")) +# expected: +# result: +# value: "2017-09-05T09:15:30.987654321+02:00" +# type: dateTime +#- id: 053_283c083df9 +# description: "" +# tests: +# - feel-expression: date and time(date and time("2017-09-05T10:20:00@Europe/Paris"),time("09:15:30.123456Z")) +# expected: +# result: +# value: "2017-09-05T09:15:30.123456Z" +# type: dateTime +#- id: 054_2561a406fc +# description: "" +# tests: +# - feel-expression: string(date and time(date and time("2017-09-05T10:20:00@Europe/Paris"),time("09:15:30.987654321@Europe/Paris"))) +# expected: +# result: +# value: 2017-09-05T09:15:30.987654321@Europe/Paris +# type: string +#- id: 055_6ce9202e17 +# description: "" +# tests: +# - feel-expression: date and time(2017) +# expected: +# result: +# value: null +#- id: 056_e66397568e +# description: "" +# tests: +# - feel-expression: date and time([]) +# expected: +# result: +# value: null +#- id: 057_0452ca8719 +# description: "" +# tests: +# - feel-expression: date and time("") +# expected: +# result: +# value: null +#- id: 058_588040ceaa +# description: "" +# tests: +# - feel-expression: date and time("11:00:00") +# expected: +# result: +# value: null +#- id: 059_dfc62a3ebc +# description: "" +# tests: +# - feel-expression: date and time("2011-12-0310:15:30") +# expected: +# result: +# value: null +#- id: 060_890c302575 +# description: "" +# tests: +# - feel-expression: date and time("2011-12-03T10:15:30+01:00@Europe/Paris") +# expected: +# result: +# value: null +#- id: 061_38ea1fc94d +# description: "" +# tests: +# - feel-expression: date and time("9999999999-12-27T11:22:33") +# expected: +# result: +# value: null +#- id: 062_528aa370a3 +# description: "" +# tests: +# - feel-expression: date and time("2017-13-10T11:22:33") +# expected: +# result: +# value: null +#- id: 063_2c94303011 +# description: "" +# tests: +# - feel-expression: date and time("2017-00-10T11:22:33") +# expected: +# result: +# value: null +#- id: 064_926a372666 +# description: "" +# tests: +# - feel-expression: date and time("2017-13-32T11:22:33") +# expected: +# result: +# value: null +#- id: 065_a13de18ee4 +# description: "" +# tests: +# - feel-expression: date and time("2017-13-0T11:22:33") +# expected: +# result: +# value: null +#- id: 066_e9f3d6d2c2 +# description: "" +# tests: +# - feel-expression: date and time("998-12-31T11:22:33") +# expected: +# result: +# value: null +#- id: 067_35fef99b53 +# description: "" +# tests: +# - feel-expression: date and time("01211-12-31T11:22:33") +# expected: +# result: +# value: null +#- id: 068_abaa1c2774 +# description: "" +# tests: +# - feel-expression: date and time("+99999-12-01T11:22:33") +# expected: +# result: +# value: null +#- id: 069_ca84e9c806 +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T24:00:01") +# expected: +# result: +# value: null +#- id: 070_889c75a0cf +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T24:01:00") +# expected: +# result: +# value: null +#- id: 071_e90b813dfe +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T25:00:00") +# expected: +# result: +# value: null +#- id: 072_9f3e9b9c21 +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T00:60:00") +# expected: +# result: +# value: null +#- id: 073_717548bec6 +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T00:00:61") +# expected: +# result: +# value: null +#- id: 074_a15e7f8d29 +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T7:00:00") +# expected: +# result: +# value: null +#- id: 075_4c3b8e7097 +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T07:1:00") +# expected: +# result: +# value: null +#- id: 076_4d31fed18e +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T07:01:2") +# expected: +# result: +# value: null +#- id: 077_f83b3ac8bb +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T13:20:00@xyz/abc") +# expected: +# result: +# value: null +#- id: 078_e113dabcdd +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T13:20:00+19:00") +# expected: +# result: +# value: null +#- id: 079_2e6f80eb94 +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T13:20:00-19:00") +# expected: +# result: +# value: null +#- id: 080_69de952053 +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T13:20:00+05:0") +# expected: +# result: +# value: null +#- id: 081_e063215a7c +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T13:20:00+5:00") +# expected: +# result: +# value: null +#- id: 082_5b6ed4e801 +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T13:20:00+5") +# expected: +# result: +# value: null +#- id: 083_4f41731f2a +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T13:20:00+02:00@Europe/Paris") +# expected: +# result: +# value: null +#- id: 084_c633b01603 +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T7:20") +# expected: +# result: +# value: null +#- id: 085_a604a1bc80 +# description: "" +# tests: +# - feel-expression: date and time("2017-12-31T07:2") +# expected: +# result: +# value: null +- id: 086_12ca8ac1d3 + description: "" + tests: + - feel-expression: date and time(from:"2012-12-24T23:59:00") + expected: + result: + value: 2012-12-24T23:59:00 + type: dateTime +#- id: 087_e9fd32063a +# description: "" +# tests: +# - feel-expression: date and time(date:date("2017-01-01"),time:time("23:59:01")) +# expected: +# result: +# value: 2017-01-01T23:59:01 +# type: dateTime +#- id: 088_1db0287718 +# description: "" +# tests: +# - feel-expression: date and time(date:date and time("2017-01-01T00:00:00"),time:time("23:59:01")) +# expected: +# result: +# value: 2017-01-01T23:59:01 +# type: dateTime diff --git a/tests/feel-date-function.yaml b/tests/feel-date-function.yaml new file mode 100644 index 0000000..04f03c8 --- /dev/null +++ b/tests/feel-date-function.yaml @@ -0,0 +1,387 @@ +#- id: 001_e9ae035ab9 +# description: "" +# tests: +# - feel-expression: date(null) +# expected: +# result: +# value: null +#- id: 002_9b9e6085ce +# description: "" +# tests: +# - feel-expression: date(null,null) +# expected: +# result: +# value: null +#- id: 003_e4b7918d8f +# description: "" +# tests: +# - feel-expression: date(null,2,1) +# expected: +# result: +# value: null +#- id: 004_f24ed41117 +# description: "" +# tests: +# - feel-expression: date(2017,null,1) +# expected: +# result: +# value: null +#- id: 005_3540a22062 +# description: "" +# tests: +# - feel-expression: date(2017,1,null) +# expected: +# result: +# value: null +#- id: 006_616e24dbb7 +# description: "" +# tests: +# - feel-expression: date(null,null,1) +# expected: +# result: +# value: null +#- id: 007_cda82a5d01 +# description: "" +# tests: +# - feel-expression: date(null,02,null) +# expected: +# result: +# value: null +#- id: 008_492649d3d0 +# description: "" +# tests: +# - feel-expression: date(2017,null,null) +# expected: +# result: +# value: null +#- id: 009_9e00bbdad3 +# description: "" +# tests: +# - feel-expression: date(null,null,null) +# expected: +# result: +# value: null +#- id: 010_6d4d58d23a +# description: "" +# tests: +# - feel-expression: date() +# expected: +# result: +# value: null +#- id: 011_5f0b42b1f8 +# description: "" +# tests: +# - feel-expression: date("2017-12-31") +# expected: +# result: +# value: "2017-12-31" +# type: date +#- id: 012_d9e4b97438 +# description: "" +# tests: +# - feel-expression: date("2017-01-01") +# expected: +# result: +# value: "2017-01-01" +# type: date +#- id: 013_d7e901ee86 +# description: "" +# tests: +# - feel-expression: date("-2017-12-31") +# expected: +# result: +# value: -2017-12-31 +# type: date +#- id: 014_fad7e00633 +# description: "" +# tests: +# - feel-expression: date("-2017-01-01") +# expected: +# result: +# value: -2017-01-01 +# type: date +#- id: 015_1dd66594cf +# description: "" +# tests: +# - feel-expression: string(date("999999999-12-31")) +# expected: +# result: +# value: 999999999-12-31 +# type: string +#- id: 016_31f3fef4a0 +# description: "" +# tests: +# - feel-expression: string(date("-999999999-12-31")) +# expected: +# result: +# value: -999999999-12-31 +# type: string +#- id: 017_887dfef005 +# description: "" +# tests: +# - feel-expression: date(date and time("2017-08-14T14:25:00")) +# expected: +# result: +# value: "2017-08-14" +# type: date +#- id: 018_fc0ef0c8cb +# description: "" +# tests: +# - feel-expression: date(date and time(date and time("2017-08-14T14:25:00"),time("10:50:00"))) +# expected: +# result: +# value: "2017-08-14" +# type: date +#- id: 019_b2b82796ce +# description: "" +# tests: +# - feel-expression: date(date and time("2017-08-14T14:25:00.123456789")) +# expected: +# result: +# value: "2017-08-14" +# type: date +#- id: 020_7d56b7bf63 +# description: "" +# tests: +# - feel-expression: date(date and time("2017-09-03T09:45:30@Europe/Paris")) +# expected: +# result: +# value: "2017-09-03" +# type: date +#- id: 021_95fb3d9984 +# description: "" +# tests: +# - feel-expression: date(date and time("2017-09-06T09:45:30@Asia/Dhaka")) +# expected: +# result: +# value: "2017-09-06" +# type: date +#- id: 022_4063db2d59 +# description: "" +# tests: +# - feel-expression: date(date and time("2012-12-25T11:00:00Z")) +# expected: +# result: +# value: "2012-12-25" +# type: date +#- id: 023_4a1f604006 +# description: "" +# tests: +# - feel-expression: date(date and time("2017-08-03T10:15:30+01:00")) +# expected: +# result: +# value: "2017-08-03" +# type: date +#- id: 024_3cb98a2bb8 +# description: "" +# tests: +# - feel-expression: date(date("2017-10-11")) +# expected: +# result: +# value: "2017-10-11" +# type: date +#- id: 025_cf0ad1313c +# description: "" +# tests: +# - feel-expression: date(2017,12,31) +# expected: +# result: +# value: "2017-12-31" +# type: date +#- id: 026_cedd7e5e5f +# description: "" +# tests: +# - feel-expression: date(2017,01,01) +# expected: +# result: +# value: "2017-01-01" +# type: date +#- id: 027_987c5be372 +# description: "" +# tests: +# - feel-expression: date(-2017,12,31) +# expected: +# result: +# value: -2017-12-31 +# type: date +#- id: 028_35ca79a6cd +# description: "" +# tests: +# - feel-expression: date(-2017,01,01) +# expected: +# result: +# value: -2017-01-01 +# type: date +#- id: 029_88f5c7c90f +# description: "" +# tests: +# - feel-expression: string(date(999999999,12,31)) +# expected: +# result: +# value: 999999999-12-31 +# type: string +#- id: 030_9184a7bfc3 +# description: "" +# tests: +# - feel-expression: string(date(-999999999,12,31)) +# expected: +# result: +# value: -999999999-12-31 +# type: string +#- id: 031_4f5ec70669 +# description: "" +# tests: +# - feel-expression: date("2012-12-25T") +# expected: +# result: +# value: null +#- id: 032_fc66cc2fec +# description: "" +# tests: +# - feel-expression: date("") +# expected: +# result: +# value: null +#- id: 033_c3a5600c62 +# description: "" +# tests: +# - feel-expression: date("2012/12/25") +# expected: +# result: +# value: null +#- id: 034_7d2e18a10c +# description: "" +# tests: +# - feel-expression: date("0000-12-25T") +# expected: +# result: +# value: null +#- id: 035_e6c1bb43fd +# description: "" +# tests: +# - feel-expression: date("9999999999-12-25") +# expected: +# result: +# value: null +#- id: 036_b826a6b5f9 +# description: "" +# tests: +# - feel-expression: date("2017-13-10") +# expected: +# result: +# value: null +#- id: 037_cfd70896b6 +# description: "" +# tests: +# - feel-expression: date("2017-12-32") +# expected: +# result: +# value: null +#- id: 038_c26782f559 +# description: "" +# tests: +# - feel-expression: date("998-12-31") +# expected: +# result: +# value: null +#- id: 039_67a6eafa3f +# description: "" +# tests: +# - feel-expression: date("01211-12-31") +# expected: +# result: +# value: null +#- id: 040_dd2a2ed4a2 +# description: "" +# tests: +# - feel-expression: date("2012T-12-2511:00:00Z") +# expected: +# result: +# value: null +#- id: 041_9e7e388146 +# description: "" +# tests: +# - feel-expression: date("+2012-12-02") +# expected: +# result: +# value: null +#- id: 042_8f5dd97588 +# description: "" +# tests: +# - feel-expression: date(2017,13,31) +# expected: +# result: +# value: null +#- id: 043_8f82301fac +# description: "" +# tests: +# - feel-expression: date(2017,12,32) +# expected: +# result: +# value: null +#- id: 044_74893220b4 +# description: "" +# tests: +# - feel-expression: date(2017,-8,2) +# expected: +# result: +# value: null +#- id: 045_969723fed5 +# description: "" +# tests: +# - feel-expression: date(2017,8,-2) +# expected: +# result: +# value: null +#- id: 046_36bf30268a +# description: "" +# tests: +# - feel-expression: date(-1000999999,12,01) +# expected: +# result: +# value: null +#- id: 047_ba717eb672 +# description: "" +# tests: +# - feel-expression: date(1000999999,12,32) +# expected: +# result: +# value: null +#- id: 048_25595a6420 +# description: "" +# tests: +# - feel-expression: date(1) +# expected: +# result: +# value: null +#- id: 049_a1644ce710 +# description: "" +# tests: +# - feel-expression: date([]) +# expected: +# result: +# value: null +- id: 050_8f1e299951 + description: "" + tests: + - feel-expression: date(from:"2012-12-25") + expected: + result: + value: "2012-12-25" + type: date +#- id: 051_ad98079864 +# description: "" +# tests: +# - feel-expression: date(from:date and time("2017-08-30T10:25:00")) +# expected: +# result: +# value: "2017-08-30" +# type: date +#- id: 052_63457d78b7 +# description: "" +# tests: +# - feel-expression: date(year:2017,month:08,day:30) +# expected: +# result: +# value: "2017-08-30" +# type: date diff --git a/tests/feel-day-of-year-function.yaml b/tests/feel-day-of-year-function.yaml new file mode 100644 index 0000000..e7a0ce8 --- /dev/null +++ b/tests/feel-day-of-year-function.yaml @@ -0,0 +1,144 @@ +- id: date_001 + description: 'date: first day of year' + tests: + - feel-expression: day of year(@"1970-01-01") + expected: + result: + value: "1" + type: decimal +- id: date_002 + description: 'date: last day of year' + tests: + - feel-expression: day of year(@"2019-12-31") + expected: + result: + value: "365" + type: decimal +- id: date_003 + description: 'date: leap year has 366 days' + tests: + - feel-expression: day of year(@"2020-12-31") + expected: + result: + value: "366" + type: decimal +- id: date_004 + description: 'date: spec example' + tests: + - feel-expression: day of year(@"2019-09-17") + expected: + result: + value: "260" + type: decimal +#- id: date_005 +# description: 'date: unknown type at compile time with valid date as runtime input' +# tests: +# - feel-expression: day of year(date_input_001) +# expected: +# result: +# value: "1" +# type: decimal +- id: date_006 + description: 'date: will accept date as named param' + tests: + - feel-expression: 'day of year(date: @"2019-09-17")' + expected: + result: + value: "260" + type: decimal +- id: datetime_001 + description: 'datetime: first day of year' + tests: + - feel-expression: day of year(@"1970-01-01T10:10:10") + expected: + result: + value: "1" + type: decimal +- id: datetime_002 + description: 'datetime: last day of year' + tests: + - feel-expression: day of year(@"2019-12-31T10:10:10") + expected: + result: + value: "365" + type: decimal +- id: datetime_003 + description: 'datetime: leap year has 366 days' + tests: + - feel-expression: day of year(@"2020-12-31T10:10:10") + expected: + result: + value: "366" + type: decimal +#- id: datetime_004 +# description: 'datetime: unknown type at compile time with valid datetime as runtime input' +# tests: +# - feel-expression: day of year(date_input_001) +# expected: +# result: +# value: "1" +# type: decimal +- id: datetime_005 + description: 'datetime: will accept date time as named param' + tests: + - feel-expression: 'day of year(date: @"2019-09-17T10:10:10")' + expected: + result: + value: "260" + type: decimal +#- id: null_001 +# description: null param gives null result +# tests: +# - feel-expression: day of year(null) +# expected: +# result: +# value: null +#- id: null_002 +# description: no param gives null result +# tests: +# - feel-expression: day of year() +# expected: +# result: +# value: null +#- id: null_003 +# description: invalid param type gives null result +# tests: +# - feel-expression: day of year("foo") +# expected: +# result: +# value: null +#- id: null_004 +# description: null value named param gives null result +# tests: +# - feel-expression: 'day of year(date: null)' +# expected: +# result: +# value: null +#- id: null_005 +# description: invalid type as named param gives null result +# tests: +# - feel-expression: 'day of year(date: "foo")' +# expected: +# result: +# value: null +#- id: null_006 +# description: invalidly named param gives null result +# tests: +# - feel-expression: 'day of year(value: @"1970-01-01")' +# expected: +# result: +# value: null +#- id: null_007 +# description: unknown type at compile time with invalid type as runtime input +# tests: +# - feel-expression: day of year(date_input_001) +# expected: +# result: +# value: null +#- id: null_008 +# description: too many params gives null result +# tests: +# - feel-expression: day of year(@"1970-01-01", @"1970-01-01") +# expected: +# result: +# value: null diff --git a/tests/feel-disjunction.yaml b/tests/feel-disjunction.yaml new file mode 100644 index 0000000..393b2a3 --- /dev/null +++ b/tests/feel-disjunction.yaml @@ -0,0 +1,143 @@ +- id: "001" + description: "" + tests: + - feel-expression: true or true + expected: + result: + value: "true" + type: boolean +- id: "002" + description: "" + tests: + - feel-expression: true or false + expected: + result: + value: "true" + type: boolean +- id: 003_a + description: "" + tests: + - feel-expression: true or null + expected: + result: + value: "true" + type: boolean +- id: 003_b + description: "" + tests: + - feel-expression: true or 123 + expected: + result: + value: "true" + type: boolean +- id: 003_c + description: "" + tests: + - feel-expression: true or "true" + expected: + result: + value: "true" + type: boolean +- id: "004" + description: "" + tests: + - feel-expression: false or true + expected: + result: + value: "true" + type: boolean +- id: "005" + description: "" + tests: + - feel-expression: false or false + expected: + result: + value: "false" + type: boolean +#- id: 006_a +# description: "" +# tests: +# - feel-expression: false or null +# expected: +# result: +# value: null +#- id: 006_b +# description: "" +# tests: +# - feel-expression: false or 123 +# expected: +# result: +# value: null +#- id: 006_c +# description: "" +# tests: +# - feel-expression: false or "true" +# expected: +# result: +# value: null +- id: 007_a + description: "" + tests: + - feel-expression: null or true + expected: + result: + value: "true" + type: boolean +- id: 007_b + description: "" + tests: + - feel-expression: 123 or true + expected: + result: + value: "true" + type: boolean +- id: 007_c + description: "" + tests: + - feel-expression: '"true" or true' + expected: + result: + value: "true" + type: boolean +#- id: 008_a +# description: "" +# tests: +# - feel-expression: null or false +# expected: +# result: +# value: null +#- id: 008_b +# description: "" +# tests: +# - feel-expression: 123 or false +# expected: +# result: +# value: null +#- id: 008_c +# description: "" +# tests: +# - feel-expression: '"true" or false' +# expected: +# result: +# value: null +#- id: 009_a +# description: "" +# tests: +# - feel-expression: null or null +# expected: +# result: +# value: null +#- id: 009_b +# description: "" +# tests: +# - feel-expression: '"true" or "true"' +# expected: +# result: +# value: null +#- id: 009_c +# description: "" +# tests: +# - feel-expression: 0 or 0 +# expected: +# result: +# value: null diff --git a/tests/feel-duration-function.yaml b/tests/feel-duration-function.yaml new file mode 100644 index 0000000..d523619 --- /dev/null +++ b/tests/feel-duration-function.yaml @@ -0,0 +1,388 @@ +#- id: 001_f2c6cd6866 +# description: "" +# tests: +# - feel-expression: duration(null) +# expected: +# result: +# value: null +#- id: 002_ddca5756ca +# description: "" +# tests: +# - feel-expression: duration() +# expected: +# result: +# value: null +#- id: 003_951e1d1c31 +# description: "" +# tests: +# - feel-expression: duration("P1D") +# expected: +# result: +# value: P1D +# type: duration +- id: 004_6b31e7cde7 + description: "" + tests: + - feel-expression: duration("PT2H") + expected: + result: + value: PT2H + type: duration +- id: 005_202d863d07 + description: "" + tests: + - feel-expression: duration("PT3M") + expected: + result: + value: PT3M + type: duration +- id: 006_a885f926d9 + description: "" + tests: + - feel-expression: duration("PT4S") + expected: + result: + value: PT4S + type: duration +#- id: 007_2f0ad399f3 +# description: "" +# tests: +# - feel-expression: duration("PT0.999S") +# expected: +# result: +# value: PT0.999S +# type: duration +#- id: 008_747f56743d +# description: "" +# tests: +# - feel-expression: duration("P1DT2H3M4.123456789S") +# expected: +# result: +# value: P1DT2H3M4.123456789S +# type: duration +- id: 009_cef3c1ed26 + description: "" + tests: + - feel-expression: duration("PT0S") + expected: + result: + value: PT0S + type: duration +#- id: 010_5b452a4975 +# description: "" +# tests: +# - feel-expression: duration("PT0.000S") +# expected: +# result: +# value: PT0S +# type: duration +#- id: 011_2169615b94 +# description: "" +# tests: +# - feel-expression: duration("PT0.S") +# expected: +# result: +# value: PT0S +# type: duration +- id: 012_2affe6d169 + description: "" + tests: + - feel-expression: duration("PT0M") + expected: + result: + value: PT0S + type: duration +- id: 013_0e8e26513c + description: "" + tests: + - feel-expression: duration("PT0H") + expected: + result: + value: PT0S + type: duration +#- id: 014_598ba6fabd +# description: "" +# tests: +# - feel-expression: duration("P0D") +# expected: +# result: +# value: PT0S +# type: duration +- id: 015_ce2cb09830 + description: "" + tests: + - feel-expression: duration("-PT1H2M") + expected: + result: + value: -PT1H2M + type: duration +#- id: 016_af3e37fdbd +# description: "" +# tests: +# - feel-expression: duration("PT1000M") +# expected: +# result: +# value: PT16H40M +# type: duration +#- id: 017_4f4549fda4 +# description: "" +# tests: +# - feel-expression: duration("PT1000M0.999999999S") +# expected: +# result: +# value: PT16H40M0.999999999S +# type: duration +#- id: 018_f5ec776811 +# description: "" +# tests: +# - feel-expression: duration("PT555M") +# expected: +# result: +# value: PT9H15M +# type: duration +#- id: 019_2e6885755a +# description: "" +# tests: +# - feel-expression: duration("PT61M") +# expected: +# result: +# value: PT1H1M +# type: duration +#- id: 020_af58b3766e +# description: "" +# tests: +# - feel-expression: duration("PT24H") +# expected: +# result: +# value: P1D +# type: duration +#- id: 021_e48e70ad4e +# description: "" +# tests: +# - feel-expression: duration("PT240H") +# expected: +# result: +# value: P10D +# type: duration +#- id: 022_668f24bed7 +# description: "" +# tests: +# - feel-expression: duration("P2DT100M") +# expected: +# result: +# value: P2DT1H40M +# type: duration +#- id: 023_6fc32087db +# description: "" +# tests: +# - feel-expression: duration("PT3600S") +# expected: +# result: +# value: PT1H +# type: duration +#- id: 024_fd7000d72f +# description: "" +# tests: +# - feel-expression: duration("P2DT274M") +# expected: +# result: +# value: P2DT4H34M +# type: duration +- id: 025_f8ffbd8658 + description: "" + tests: + - feel-expression: duration("P1Y2M") + expected: + result: + value: P1Y2M + type: duration +- id: 026_e6c47f0cae + description: "" + tests: + - feel-expression: duration("P1Y") + expected: + result: + value: P1Y + type: duration +- id: 027_33b7fb8704 + description: "" + tests: + - feel-expression: duration("P0Y") + expected: + result: + value: P0M + type: duration +- id: 028_971b94f16d + description: "" + tests: + - feel-expression: duration("P0M") + expected: + result: + value: P0M + type: duration +- id: 029_1a12a226cc + description: "" + tests: + - feel-expression: duration("-P1Y") + expected: + result: + value: -P1Y + type: duration +#- id: 030_afac0f2062 +# description: "" +# tests: +# - feel-expression: duration("P26M") +# expected: +# result: +# value: P2Y2M +# type: duration +#- id: 031_1ddad718b9 +# description: "" +# tests: +# - feel-expression: duration("P1Y27M") +# expected: +# result: +# value: P3Y3M +# type: duration +#- id: 032_72c46a9ec9 +# description: "" +# tests: +# - feel-expression: duration("P100M") +# expected: +# result: +# value: P8Y4M +# type: duration +#- id: 033_5d1540abaf +# description: "" +# tests: +# - feel-expression: duration("-P100M") +# expected: +# result: +# value: -P8Y4M +# type: duration +#- id: 034_aa9cbb21a6 +# description: "" +# tests: +# - feel-expression: duration("P999999999M") +# expected: +# result: +# value: P83333333Y3M +# type: duration +#- id: 035_93eef01ae7 +# description: "" +# tests: +# - feel-expression: duration("-P999999999M") +# expected: +# result: +# value: -P83333333Y3M +# type: duration +- id: 036_5f2775875e + description: "" + tests: + - feel-expression: duration("P99999999Y") + expected: + result: + value: P99999999Y + type: duration +- id: 037_8c9ea9c0e6 + description: "" + tests: + - feel-expression: duration("-P99999999Y") + expected: + result: + value: -P99999999Y + type: duration +- id: 038_67dc4c254c + description: "" + tests: + - feel-expression: duration(from:"P1Y") + expected: + result: + value: P1Y + type: duration +#- id: 039_4aa0b67804 +# description: "" +# tests: +# - feel-expression: duration(from:"PT24H") +# expected: +# result: +# value: P1D +# type: duration +#- id: 040_7d8eae461f +# description: "" +# tests: +# - feel-expression: duration(from:"P26M") +# expected: +# result: +# value: P2Y2M +# type: duration +#- id: 041_264bc9d682 +# description: "" +# tests: +# - feel-expression: duration("") +# expected: +# result: +# value: null +#- id: 042_59a0000245 +# description: "" +# tests: +# - feel-expression: duration(2017) +# expected: +# result: +# value: null +#- id: 043_253815dc6c +# description: "" +# tests: +# - feel-expression: duration("2012T-12-2511:00:00Z") +# expected: +# result: +# value: null +#- id: 044_f3b338d877 +# description: "" +# tests: +# - feel-expression: duration([]) +# expected: +# result: +# value: null +#- id: 045_2ffcc37801 +# description: "" +# tests: +# - feel-expression: duration("P") +# expected: +# result: +# value: null +#- id: 046_eb637de5f6 +# description: "" +# tests: +# - feel-expression: duration("P0") +# expected: +# result: +# value: null +#- id: 047_3210c46a5a +# description: "" +# tests: +# - feel-expression: duration("1Y") +# expected: +# result: +# value: null +#- id: 048_ab6244f767 +# description: "" +# tests: +# - feel-expression: duration("1D") +# expected: +# result: +# value: null +#- id: 049_2225b503a0 +# description: "" +# tests: +# - feel-expression: duration("P1H") +# expected: +# result: +# value: null +#- id: 050_dd2ef33bbd +# description: "" +# tests: +# - feel-expression: duration("P1S") +# expected: +# result: +# value: null diff --git a/tests/feel-equality.yaml b/tests/feel-equality.yaml new file mode 100644 index 0000000..190fc79 --- /dev/null +++ b/tests/feel-equality.yaml @@ -0,0 +1,900 @@ +- id: null_001 + description: null equals null + tests: + - feel-expression: null = null + expected: + result: + value: "true" + type: boolean +- id: null_002 + description: null not equals null + tests: + - feel-expression: null != null + expected: + result: + value: "false" + type: boolean +- id: boolean_001 + description: boolean true equal + tests: + - feel-expression: true = true + expected: + result: + value: "true" + type: boolean +- id: boolean_002 + description: boolean true not equal + tests: + - feel-expression: true != true + expected: + result: + value: "false" + type: boolean +- id: boolean_003 + description: boolean true equal + tests: + - feel-expression: false = false + expected: + result: + value: "true" + type: boolean +- id: boolean_004 + description: boolean true not equal + tests: + - feel-expression: false != false + expected: + result: + value: "false" + type: boolean +- id: boolean_005 + description: boolean true not equal false + tests: + - feel-expression: true = false + expected: + result: + value: "false" + type: boolean +- id: boolean_006 + description: boolean true equals null + tests: + - feel-expression: true = null + expected: + result: + value: "false" + type: boolean +- id: boolean_007 + description: boolean false equals null + tests: + - feel-expression: false = null + expected: + result: + value: "false" + type: boolean +#- id: boolean_008 +# description: boolean false equals another type (0) +# tests: +# - feel-expression: false = 0 +# expected: +# result: +# value: null +#- id: boolean_009 +# description: boolean true equals another type (1) +# tests: +# - feel-expression: true = 1 +# expected: +# result: +# value: null +- id: number_001 + description: num equal + tests: + - feel-expression: 123 = 123 + expected: + result: + value: "true" + type: boolean +- id: number_002 + description: num with digits equal + tests: + - feel-expression: 123.01 = 123.01 + expected: + result: + value: "true" + type: boolean +- id: number_003 + description: zero equality + tests: + - feel-expression: 0 = 0.00 + expected: + result: + value: "true" + type: boolean +- id: number_004 + description: negative zero equality + tests: + - feel-expression: -0 = 0 + expected: + result: + value: "true" + type: boolean +- id: number_005 + description: negative inequality + tests: + - feel-expression: -1 = 1 + expected: + result: + value: "false" + type: boolean +- id: number_006 + description: number equals null + tests: + - feel-expression: 100 = null + expected: + result: + value: "false" + type: boolean +#- id: number_007 +# description: number equals another type +# tests: +# - feel-expression: 100 = "100" +# expected: +# result: +# value: null +#- id: number_008 +# description: number equals literal 'e' exponent number with default sign +# tests: +# - feel-expression: 12300 = 1.23e4 +# expected: +# result: +# value: "true" +# type: boolean +#- id: number_009 +# description: number equals literal 'e' exponent number with '+' sign +# tests: +# - feel-expression: 12300 = 1.23e+4 +# expected: +# result: +# value: "true" +# type: boolean +#- id: number_010 +# description: number equals literal 'e' exponent number with '-' sign +# tests: +# - feel-expression: 0.000123 = 1.23e-4 +# expected: +# result: +# value: "true" +# type: boolean +- id: string_001 + description: string equals + tests: + - feel-expression: '"foo" = "foo"' + expected: + result: + value: "true" + type: boolean +- id: string_002 + description: string case sensitive + tests: + - feel-expression: '"foo" = "Foo"' + expected: + result: + value: "false" + type: boolean +- id: string_003 + description: string not equals + tests: + - feel-expression: '"foo" != "Foo"' + expected: + result: + value: "true" + type: boolean +- id: string_004 + description: string equals null + tests: + - feel-expression: '"foo" = null' + expected: + result: + value: "false" + type: boolean +#- id: string_005 +# description: string equals another type +# tests: +# - feel-expression: '"foo" = 100' +# expected: +# result: +# value: null +#- id: list_001 +# description: list equal +# tests: +# - feel-expression: '[1,2,3] = [1,2,3]' +# expected: +# result: +# value: "true" +# type: boolean +- id: list_002 + description: lists of different lengths not equal + tests: + - feel-expression: '[1,1,1] = [1,1,1,1]' + expected: + result: + value: "false" + type: boolean +- id: list_003 + description: lists of same length with diff contents not equal + tests: + - feel-expression: '[1,1,1] = [1,1,2]' + expected: + result: + value: "false" + type: boolean +#- id: list_004 +# description: empty lists equal +# tests: +# - feel-expression: '[] = []' +# expected: +# result: +# value: "true" +# type: boolean +- id: list_005 + description: list with same content but different order not equal + tests: + - feel-expression: '[1,2,3] = [3,2,1]' + expected: + result: + value: "false" + type: boolean +#- id: list_006 +# description: non list boolean of index 1 equals boolean +# tests: +# - feel-expression: true[1] = true +# expected: +# result: +# value: "true" +# type: boolean +#- id: list_007 +# description: non list number of index 1 equals number +# tests: +# - feel-expression: 100[1] = 100 +# expected: +# result: +# value: "true" +# type: boolean +#- id: list_008 +# description: non list string of index 1 equals string +# tests: +# - feel-expression: '"foo"[1] = "foo"' +# expected: +# result: +# value: "true" +# type: boolean +#- id: list_009 +# description: non list date of index 1 equals date +# tests: +# - feel-expression: date("2018-12-08")[1] = date("2018-12-08") +# expected: +# result: +# value: "true" +# type: boolean +#- id: list_010 +# description: non list time of index 1 equals time +# tests: +# - feel-expression: time("10:30:12")[1] = time("10:30:12") +# expected: +# result: +# value: "true" +# type: boolean +#- id: list_011 +# description: non list date time of index 1 equals date time +# tests: +# - feel-expression: date and time("2018-12-08")[1] = date and time("2018-12-08") +# expected: +# result: +# value: "true" +# type: boolean +#- id: list_012 +# description: non list days duration of index 1 equals days duration +# tests: +# - feel-expression: duration("P1D")[1] = duration("P1D") +# expected: +# result: +# value: "true" +# type: boolean +#- id: list_013 +# description: non list years duration of index 1 equals years duration +# tests: +# - feel-expression: duration("P1Y")[1] = duration("P1Y") +# expected: +# result: +# value: "true" +# type: boolean +#- id: list_014 +# description: non list context of index 1 equals context +# tests: +# - feel-expression: '{a: "foo"}[1] = {a: "foo"}' +# expected: +# result: +# value: "true" +# type: boolean +- id: list_015 + description: list equals null + tests: + - feel-expression: '[] = null' + expected: + result: + value: "false" + type: boolean +#- id: list_016 +# description: list equals another type +# tests: +# - feel-expression: '[] = 0' +# expected: +# result: +# value: null +- id: context_001 + description: empty contexts equal + tests: + - feel-expression: '{} = {}' + expected: + result: + value: "true" + type: boolean +- id: context_002 + description: contexts with same properties in same order equal + tests: + - feel-expression: '{foo: "bar", bar: "baz"} = {foo: "bar", bar: "baz"}' + expected: + result: + value: "true" + type: boolean +- id: context_003 + description: contexts with same properties in different order equal + tests: + - feel-expression: '{foo: "bar", bar: "baz"} = {bar: "baz", foo: "bar"}' + expected: + result: + value: "true" + type: boolean +- id: context_004 + description: string literal name equal to non-string-literal name + tests: + - feel-expression: '{foo: "bar"} = {"foo": "bar"}' + expected: + result: + value: "true" + type: boolean +- id: context_005 + description: context with same name and different values not equal + tests: + - feel-expression: '{foo: "bar"} = {foo: "baz"}' + expected: + result: + value: "false" + type: boolean +- id: context_006 + description: context equals null + tests: + - feel-expression: '{} = null' + expected: + result: + value: "false" + type: boolean +#- id: context_007 +# description: context equals another type +# tests: +# - feel-expression: '{} = []' +# expected: +# result: +# value: null +#- id: date_001 +# description: same dates are equal +# tests: +# - feel-expression: date("2018-12-08") = date("2018-12-08") +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_002 +# description: different dates are not equal +# tests: +# - feel-expression: date("2018-12-07") = date("2018-12-08") +# expected: +# result: +# value: "false" +# type: boolean +- id: date_003 + description: date equals null + tests: + - feel-expression: date("2018-12-07") = null + expected: + result: + value: "false" + type: boolean +#- id: date_004 +# description: date equals another type +# tests: +# - feel-expression: date("2018-12-07") = 100 +# expected: +# result: +# value: null +- id: time_001 + description: same times are equal + tests: + - feel-expression: time("10:30:00") = time("10:30:00") + expected: + result: + value: "true" + type: boolean +- id: time_002 + description: 'different times are not equal: hours' + tests: + - feel-expression: time("11:30:00") = time("10:30:00") + expected: + result: + value: "false" + type: boolean +- id: time_002_a + description: 'different times are not equal: minutes' + tests: + - feel-expression: time("10:31:00") = time("10:30:00") + expected: + result: + value: "false" + type: boolean +- id: time_002_b + description: 'different times are not equal: seconds' + tests: + - feel-expression: time("10:30:01") = time("10:30:00") + expected: + result: + value: "false" + type: boolean +- id: time_003 + description: same times with zero milliseconds are equal + tests: + - feel-expression: time("10:30:00.0000") = time("10:30:00") + expected: + result: + value: "true" + type: boolean +- id: time_004 + description: same times with same milliseconds are equal + tests: + - feel-expression: time("10:30:00.0001") = time("10:30:00.0001") + expected: + result: + value: "true" + type: boolean +#- id: time_005 +# description: same times with different milliseconds are equal as value resolution is seconds +# tests: +# - feel-expression: time("10:30:00.0001") = time("10:30:00.0002") +# expected: +# result: +# value: "true" +# type: boolean +#- id: time_006 +# description: same times in same zone are equal +# tests: +# - feel-expression: time("10:30:00@Europe/Paris") = time("10:30:00@Europe/Paris") +# expected: +# result: +# value: "true" +# type: boolean +#- id: time_010 +# description: same times = one with Z zone, the other with UTC are equal +# tests: +# - feel-expression: time("10:30:00Z") = time("10:30:00+00:00") +# expected: +# result: +# value: "true" +# type: boolean +- id: time_011 + description: time equals null + tests: + - feel-expression: time("10:30:00") = null + expected: + result: + value: "false" + type: boolean +#- id: time_012 +# description: time equals another type +# tests: +# - feel-expression: time("10:30:00") = 100 +# expected: +# result: +# value: null +- id: datetime_001 + description: same datetimes are equal + tests: + - feel-expression: date and time("2018-12-08T10:30:00") = date and time("2018-12-08T10:30:00") + expected: + result: + value: "true" + type: boolean +#- id: datetime_002 +# description: datetimes with no time is equal to datetime with zero time +# tests: +# - feel-expression: date and time("2018-12-08") = date and time("2018-12-08T00:00:00") +# expected: +# result: +# value: "true" +# type: boolean +- id: datetime_003 + description: datetimes with same milliseconds are equal + tests: + - feel-expression: date and time("2018-12-08T00:00:00.0001") = date and time("2018-12-08T00:00:00.0001") + expected: + result: + value: "true" + type: boolean +#- id: datetime_003_a +# description: datetimes with different milliseconds are equal as resolution is to the second +# tests: +# - feel-expression: date and time("2018-12-08T00:00:00.0001") = date and time("2018-12-08T00:00:00.0000") +# expected: +# result: +# value: "true" +# type: boolean +- id: datetime_004 + description: different datetimes are not equal + tests: + - feel-expression: date and time("2018-12-08T00:00:00") = date and time("2018-12-07T00:00:00") + expected: + result: + value: "false" + type: boolean +#- id: datetime_005 +# description: same datetimes in same zone are equal +# tests: +# - feel-expression: "date and time(\"2018-12-08T00:00:00@Europe/Paris\") = date and\n time(\"2018-12-08T00:00:00@Europe/Paris\")\n " +# expected: +# result: +# value: "true" +# type: boolean +#- id: datetime_006 +# description: same datetimes in different zones are not equal +# tests: +# - feel-expression: "date and time(\"2018-12-08T00:00:00@Europe/Paris\") = date and time(\"2018-12-08T00:00:00@Asia/Dhaka\")\n " +# expected: +# result: +# value: "false" +# type: boolean +#- id: datetime_008 +# description: same datetimes, one with offset and the other with zone are equal +# tests: +# - feel-expression: date and time("2018-10-08T00:00:00+02:00") = date and time("2018-10-08T00:00:00@Europe/Paris") +# expected: +# result: +# value: "true" +# type: boolean +#- id: datetime_008_a +# description: same datetimes, one with offset and the other with zone are equal - DST +# tests: +# - feel-expression: date and time("2018-02-08T00:00:00+01:00") = date and time("2018-02-08T00:00:00@Europe/Paris") +# expected: +# result: +# value: "true" +# type: boolean +#- id: datetime_008_b +# description: same datetimes, with same offsets but different zones equal +# tests: +# - feel-expression: '@"2002-04-02T12:00:00@Australia/Melbourne" = @"2002-04-02T12:00:00@Australia/Sydney"' +# expected: +# result: +# value: "true" +# type: boolean +#- id: datetime_009 +# description: datetime with zero offset is equal to utc zone +# tests: +# - feel-expression: date and time("2018-12-08T00:00:00+00:00") = date and time("2018-12-08T00:00:00@Etc/UTC") +# expected: +# result: +# value: "true" +# type: boolean +- id: datetime_010 + description: datetime equals null + tests: + - feel-expression: date and time("2018-12-08T00:00:00") = null + expected: + result: + value: "false" + type: boolean +#- id: datetime_011 +# description: datetime equals another type +# tests: +# - feel-expression: date and time("2018-12-08T00:00:00") = 100 +# expected: +# result: +# value: null +- id: datetime_012 + description: 'datetime: different times in different zones can be equal' + tests: + - feel-expression: '@"2002-04-02T12:00:00-01:00" = @"2002-04-02T17:00:00+04:00"' + expected: + result: + value: "true" + type: boolean +- id: datetime_013 + description: 'datetime: different times in different zones can be equal (with negative offset)' + tests: + - feel-expression: '@"2002-04-02T23:00:00-04:00" = @"2002-04-03T02:00:00-01:00"' + expected: + result: + value: "true" + type: boolean +#- id: dt_duration_001 +# description: same durations are equal +# tests: +# - feel-expression: duration("P1D") = duration("P1D") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_002 +# description: equivalent durations are (erm) equal +# tests: +# - feel-expression: duration("P1D") = duration("PT24H") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_003 +# description: different durations are not equal +# tests: +# - feel-expression: duration("P1D") = duration("P2D") +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_004 +# description: negative non-zero durations of same amount are not equal +# tests: +# - feel-expression: duration("P1D") = duration("-P1D") +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_005 +# description: negative zero duration and zero duration are equal +# tests: +# - feel-expression: duration("P0D") = duration("-P0D") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_006 +# description: dt duration equals null +# tests: +# - feel-expression: duration("P0D") = null +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_007 +# description: dt duration equals another type +# tests: +# - feel-expression: duration("P0D") = 0 +# expected: +# result: +# value: null +#- id: ym_duration_001 +# description: same durations are equal +# tests: +# - feel-expression: duration("P1Y") = duration("P1Y") +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_002 +# description: equivalent durations are (erm) equal +# tests: +# - feel-expression: duration("P1Y") = duration("P12M") +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_003 +# description: different durations are not equal +# tests: +# - feel-expression: duration("P1Y") = duration("P2Y") +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_004 +# description: negative non-zero durations of same amount are not equal +# tests: +# - feel-expression: duration("P1Y") = duration("-P1Y") +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_005 +# description: negative zero duration and zero duration are equal +# tests: +# - feel-expression: duration("P0Y") = duration("-P0Y") +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_006 +# description: years/months duration not equal to days/hours duration of same amount +# tests: +# - feel-expression: duration("P1Y") = duration("P365D") +# expected: +# result: +# value: null +- id: ym_duration_007 + description: years/months duration equals null + tests: + - feel-expression: duration("P0Y") = null + expected: + result: + value: "false" + type: boolean +#- id: ym_duration_008 +# description: years/months duration equals another type +# tests: +# - feel-expression: duration("P0Y") = 0 +# expected: +# result: +# value: null +#- id: deep_001 +# description: deep array equality +# tests: +# - feel-expression: '[1,2,[3, 4]] = [1,2,[3, 4]]' +# expected: +# result: +# value: "true" +# type: boolean +#- id: deep_002 +# description: deep array equality +# tests: +# - feel-expression: '[1,2,{a: [3,4]}] = [1,2,{a: [3,4]}]' +# expected: +# result: +# value: "true" +# type: boolean +- id: deep_003 + description: deep array in-equality + tests: + - feel-expression: '[1,2,[3, 4]] = [1,2,[4, 3]]' + expected: + result: + value: "false" + type: boolean +- id: deep_004 + description: deep array in-equality + tests: + - feel-expression: '[1,2,{a: [3,4]}] = [1,2,{a: [3,4], b: "foo"}]' + expected: + result: + value: "false" + type: boolean +#- id: deep_005 +# description: deep context equality +# tests: +# - feel-expression: '{a: {b: "foo", c: [1,2]}} = {a: {b: "foo", c: [1,2]}}' +# expected: +# result: +# value: "true" +# type: boolean +- id: deep_006 + description: deep context equality + tests: + - feel-expression: '{a: {c: "bar", b: "foo"}} = {a: {b: "foo", c: "bar"}}' + expected: + result: + value: "true" + type: boolean +- id: deep_007 + description: deep context in-equality + tests: + - feel-expression: '{a: {b: "foo", c: [1,2]}} = {a: {b: "foo", c: [2,1]}}' + expected: + result: + value: "false" + type: boolean +#- id: range_001 +# description: ranges with same endpoint and inclusivity are equal +# tests: +# - feel-expression: '[1..10] = [1..10]' +# expected: +# result: +# value: "true" +# type: boolean +#- id: range_002 +# description: ranges with different upper endpoints are not equal +# tests: +# - feel-expression: '[1..2] = [1..3]' +# expected: +# result: +# value: "false" +# type: boolean +#- id: range_003 +# description: ranges with different lower endpoints are not equal +# tests: +# - feel-expression: '[2..10] = [1..10]' +# expected: +# result: +# value: "false" +# type: boolean +#- id: range_004 +# description: ranges with same endpoints, but same though syntactically different lower inclusivity are equal +# tests: +# - feel-expression: (1..10] = ]1..10] +# expected: +# result: +# value: "true" +# type: boolean +#- id: range_005 +# description: ranges with same endpoints, but same though syntactically different upper inclusivity are equal +# tests: +# - feel-expression: '[1..10) = [1..10[' +# expected: +# result: +# value: "true" +# type: boolean +#- id: range_006 +# description: 'equal ranges though syntactically different are not equal: LT ' +# tests: +# - feel-expression: (< 10) = (null..10) +# expected: +# result: +# value: "false" +# type: boolean +#- id: range_006_a +# description: unary syntax comparison range LT +# tests: +# - feel-expression: (< 10) = (< 10) +# expected: +# result: +# value: "true" +# type: boolean +#- id: range_007 +# description: 'equal ranges though syntactically different are not equal: LE ' +# tests: +# - feel-expression: (<= 10) = (null..10] +# expected: +# result: +# value: "false" +# type: boolean +#- id: range_008 +# description: 'equal ranges though syntactically different are not equal: GT ' +# tests: +# - feel-expression: (> 10) = (10..null) +# expected: +# result: +# value: "false" +# type: boolean +#- id: range_009 +# description: 'equal ranges though syntactically different are not equal: GE ' +# tests: +# - feel-expression: (>= 10) = [10..null) +# expected: +# result: +# value: "false" +# type: boolean +#- id: range_010 +# description: 'equal ranges though syntactically different are not equal: EQ ' +# tests: +# - feel-expression: (=10) = [10..10] +# expected: +# result: +# value: "false" +# type: boolean +#- id: range_011 +# description: unary syntax comparison range EQ +# tests: +# - feel-expression: (=10) = (=10) +# expected: +# result: +# value: "true" +# type: boolean +#- id: range_012 +# description: unary syntax comparison range NE +# tests: +# - feel-expression: (!=10) = (!=10) +# expected: +# result: +# value: "true" +# type: boolean diff --git a/tests/feel-external-java.yaml b/tests/feel-external-java.yaml new file mode 100644 index 0000000..c444080 --- /dev/null +++ b/tests/feel-external-java.yaml @@ -0,0 +1,140 @@ +#- id: boxed_001 +# description: boxed external function definition +# tests: +# - feel-expression: "" +# expected: +# result: +# value: "456" +# type: decimal +- id: incorrect_001 + description: no method on class + tests: + - feel-expression: "" + expected: + result: + value: null +- id: incorrect_002 + description: no class + tests: + - feel-expression: "" + expected: + result: + value: null +- id: incorrect_003 + description: no matching signature on class + tests: + - feel-expression: "" + expected: + result: + value: null +#- id: literal_001 +# description: external function definition - single param +# tests: +# - feel-expression: "" +# expected: +# result: +# value: "-0.88796890" +# type: decimal +#- id: literal_002 +# description: external function definition - two params - double +# tests: +# - feel-expression: "" +# expected: +# result: +# value: "456.78" +# type: decimal +#- id: literal_003 +# description: external function definition overrides built in function +# tests: +# - feel-expression: "" +# expected: +# result: +# value: "456" +# type: decimal +#- id: literal_004 +# description: external function definition - int +# tests: +# - feel-expression: "" +# expected: +# result: +# value: "456" +# type: decimal +#- id: literal_005 +# description: external function definition - short +# tests: +# - feel-expression: "" +# expected: +# result: +# value: "123" +# type: decimal +#- id: literal_006 +# description: external function definition - byte +# tests: +# - feel-expression: "" +# expected: +# result: +# value: "3" +# type: decimal +#- id: literal_007 +# description: external function definition - char +# tests: +# - feel-expression: "" +# expected: +# result: +# value: a +# type: string +- id: literal_007_a + description: external function definition - char + tests: + - feel-expression: "" + expected: + result: + value: null +#- id: literal_008 +# description: external function definition - long +# tests: +# - feel-expression: "" +# expected: +# result: +# value: "456" +# type: decimal +#- id: literal_009 +# description: external function definition - float +# tests: +# - feel-expression: "" +# expected: +# result: +# value: "456.78" +# type: decimal +#- id: literal_010 +# description: external function definition - string +# tests: +# - feel-expression: "" +# expected: +# result: +# value: "123" +# type: decimal +#- id: literal_011 +# description: external function definition - string to float (Java float -> BigDecimal is sometimes not quite exact) +# tests: +# - feel-expression: "" +# expected: +# result: +# value: "1234.56" +# type: decimal +#- id: literal_012 +# description: external function definition - string to double (Java double -> BigDecimal is sometimes not quite exact) +# tests: +# - feel-expression: "" +# expected: +# result: +# value: "1234.56" +# type: decimal +#- id: varargs_001 +# description: external function definition - varargs func +# tests: +# - feel-expression: "" +# expected: +# result: +# value: foo bar +# type: string diff --git a/tests/feel-for-loops.yaml b/tests/feel-for-loops.yaml new file mode 100644 index 0000000..828482d --- /dev/null +++ b/tests/feel-for-loops.yaml @@ -0,0 +1,320 @@ +- id: decision_001 + description: Loop over number list + tests: + - feel-expression: for i in [1,2,3] return i + 1 + expected: + results: + - result: + value: "2" + type: decimal + - result: + value: "3" + type: decimal + - result: + value: "4" + type: decimal +#- id: decision_002 +# description: two iteration context loop over number list +# tests: +# - feel-expression: for i in [1,2,3], j in [4,5] return i + j +# expected: +# results: +# - result: +# value: "5" +# type: decimal +# - result: +# value: "6" +# type: decimal +# - result: +# value: "6" +# type: decimal +# - result: +# value: "7" +# type: decimal +# - result: +# value: "7" +# type: decimal +# - result: +# value: "8" +# type: decimal +- id: decision_003 + description: loop over empty list + tests: + - feel-expression: for i in [] return i + expected: + results: [] +#- id: decision_007 +# description: numeric range iteration context - no delimiters +# tests: +# - feel-expression: for i in 2..4 return i +# expected: +# results: +# - result: +# value: "2" +# type: decimal +# - result: +# value: "3" +# type: decimal +# - result: +# value: "4" +# type: decimal +#- id: decision_008 +# description: numeric descending range iteration context - no delimiters +# tests: +# - feel-expression: for i in 4..2 return i +# expected: +# results: +# - result: +# value: "4" +# type: decimal +# - result: +# value: "3" +# type: decimal +# - result: +# value: "2" +# type: decimal +#- id: decision_009 +# description: numeric range iteration context - no delimiters - ascending from negative +# tests: +# - feel-expression: for i in -1..1 return i +# expected: +# results: +# - result: +# value: "-1" +# type: decimal +# - result: +# value: "0" +# type: decimal +# - result: +# value: "1" +# type: decimal +#- id: decision_010 +# description: numeric range iteration context - no delimiters - descending to negative +# tests: +# - feel-expression: for i in 1..-1 return i +# expected: +# results: +# - result: +# value: "1" +# type: decimal +# - result: +# value: "0" +# type: decimal +# - result: +# value: "-1" +# type: decimal +#- id: decision_011 +# description: numeric range iteration context - same endpoints +# tests: +# - feel-expression: for i in 1..1 return i +# expected: +# results: +# - result: +# value: "1" +# type: decimal +#- id: decision_012 +# description: expressions in range +# tests: +# - feel-expression: for i in 1+1..1+3 return i +# expected: +# results: +# - result: +# value: "2" +# type: decimal +# - result: +# value: "3" +# type: decimal +# - result: +# value: "4" +# type: decimal +#- id: decision_013 +# description: special variable 'partial' doing factorial list +# tests: +# - feel-expression: for i in 0..4 return if i = 0 then 1 else i * partial[-1] +# expected: +# results: +# - result: +# value: "1" +# type: decimal +# - result: +# value: "1" +# type: decimal +# - result: +# value: "2" +# type: decimal +# - result: +# value: "6" +# type: decimal +# - result: +# value: "24" +# type: decimal +#- id: decision_014 +# description: '''in'' may appear in list identifier' +# tests: +# - feel-expression: for i in days in weekend return if i = "sunday" then true else false +# expected: +# results: +# - result: +# value: "false" +# type: boolean +# - result: +# value: "true" +# type: boolean +#- id: decision_015 +# description: for loop with second iterator depending on first iterator +# tests: +# - feel-expression: for x in [ [1,2], [3,4] ], y in x return y +# expected: +# results: +# - result: +# value: "1" +# type: decimal +# - result: +# value: "2" +# type: decimal +# - result: +# value: "3" +# type: decimal +# - result: +# value: "4" +# type: decimal +#- id: decision_016 +# description: nested loops +# tests: +# - feel-expression: for x in [ [1,2], [3,4] ] return for y in x return y +# expected: +# results: +# - results: +# - result: +# value: "1" +# type: decimal +# - result: +# value: "2" +# type: decimal +# - results: +# - result: +# value: "3" +# type: decimal +# - result: +# value: "4" +# type: decimal +#- id: decision_017 +# description: date range increment upwards +# tests: +# - feel-expression: for i in @"1980-01-01"..@"1980-01-03" return i +# expected: +# results: +# - result: +# value: "1980-01-01" +# type: date +# - result: +# value: "1980-01-02" +# type: date +# - result: +# value: "1980-01-03" +# type: date +#- id: decision_018 +# description: date range increment downwards +# tests: +# - feel-expression: for i in @"1980-01-03"..@"1980-01-01" return i +# expected: +# results: +# - result: +# value: "1980-01-03" +# type: date +# - result: +# value: "1980-01-02" +# type: date +# - result: +# value: "1980-01-01" +# type: date +#- id: decision_019 +# description: string iteration context gives null +# tests: +# - feel-expression: for i in "a".."z" return i +# expected: +# result: +# value: null +#- id: decision_019_a +# description: string range iteration context gives null +# tests: +# - feel-expression: for i in ["a".."z"] return i +# expected: +# result: +# value: null +#- id: decision_020 +# description: datetime iteration context gives null +# tests: +# - feel-expression: for i in @"1980-01-03T00:00:00"..@"1980-01-01T00:00:00" return i +# expected: +# result: +# value: null +#- id: decision_020_a +# description: datetime range iteration context gives null +# tests: +# - feel-expression: for i in [@"1980-01-03T00:00:00"..@"1980-01-01T00:00:00"] return i +# expected: +# result: +# value: null +#- id: decision_021 +# description: time iteration context gives null +# tests: +# - feel-expression: for i in @"00:00:00"..@"00:00:00" return i +# expected: +# result: +# value: null +#- id: decision_021_a +# description: time range iteration context gives null +# tests: +# - feel-expression: for i in [@"00:00:00"..@"00:00:00"] return i +# expected: +# result: +# value: null +#- id: decision_022 +# description: duration iteration context gives null +# tests: +# - feel-expression: for i in @"P1D"..@"P2D" return i +# expected: +# result: +# value: null +#- id: decision_022_a +# description: duration range iteration context gives null +# tests: +# - feel-expression: for i in [@"P1D"..@"P2D"] return i +# expected: +# result: +# value: null +#- id: decision_023 +# description: a valid numeric range is permitted as iteration context +# tests: +# - feel-expression: for i in [1..2] return i +# expected: +# results: +# - result: +# value: "1" +# type: decimal +# - result: +# value: "2" +# type: decimal +#- id: decision_024 +# description: a valid date range is permitted as iteration context +# tests: +# - feel-expression: for i in [@"1980-01-01"..@"1980-01-03"] return i +# expected: +# results: +# - result: +# value: "1980-01-01" +# type: date +# - result: +# value: "1980-01-02" +# type: date +# - result: +# value: "1980-01-03" +# type: date +#- id: decision_025 +# description: invalid (descending) range gives null +# tests: +# - feel-expression: for i in [2..1] return i +# expected: +# result: +# value: null diff --git a/tests/feel-getvalue-function.yaml b/tests/feel-getvalue-function.yaml new file mode 100644 index 0000000..77b66df --- /dev/null +++ b/tests/feel-getvalue-function.yaml @@ -0,0 +1,101 @@ +#- id: decision_001 +# description: no param +# tests: +# - feel-expression: get value() +# expected: +# result: +# value: null +#- id: decision_002 +# description: only one param +# tests: +# - feel-expression: 'get value({a: "foo"})' +# expected: +# result: +# value: null +#- id: decision_003 +# description: too many params +# tests: +# - feel-expression: 'get value({a: "foo"}, "a", "bar")' +# expected: +# result: +# value: null +- id: decision_004 + description: get a value + tests: + - feel-expression: 'get value({a: "foo"}, "a")' + expected: + result: + value: foo + type: string +#- id: decision_005 +# description: not a map as first param +# tests: +# - feel-expression: get value("foo", "foo") +# expected: +# result: +# value: null +#- id: decision_006 +# description: not a string as second param +# tests: +# - feel-expression: 'get value({a: "foo"}, 123)' +# expected: +# result: +# value: null +#- id: decision_007 +# description: named params +# tests: +# - feel-expression: 'get value(key:"a", m:{a: "foo"})' +# expected: +# result: +# value: foo +# type: string +#- id: decision_008 +# description: badly named params +# tests: +# - feel-expression: 'get value(k:"a", m:{a: "foo"})' +# expected: +# result: +# value: null +#- id: decision_009 +# description: null map param +# tests: +# - feel-expression: get value(null, "a") +# expected: +# result: +# value: null +#- id: decision_010 +# description: null key param +# tests: +# - feel-expression: 'get value({a: "foo"}, null)' +# expected: +# result: +# value: null +#- id: decision_011 +# description: null context param +# tests: +# - feel-expression: get value(null, null) +# expected: +# result: +# value: null +#- id: decision_012 +# description: null item value stored in context +# tests: +# - feel-expression: 'get value({a: null}, "a")' +# expected: +# result: +# value: null +#- id: decision_013 +# description: non literal key of string type +# tests: +# - feel-expression: 'get value({a: "foo"}, input_001)' +# expected: +# result: +# value: foo +# type: string +#- id: decision_014 +# description: non literal key of incorrect type +# tests: +# - feel-expression: 'get value({a: "foo"}, input_001)' +# expected: +# result: +# value: null diff --git a/tests/feel-in.yaml b/tests/feel-in.yaml new file mode 100644 index 0000000..3a2762c --- /dev/null +++ b/tests/feel-in.yaml @@ -0,0 +1,2192 @@ +- id: number_001 + description: 'number: e1 in [e2,e3,…] (endpoints)' + tests: + - feel-expression: 1 in [2,3,1] + expected: + result: + value: "true" + type: boolean +- id: number_001_a + description: 'number: e1 in [e2,e3,…] (endpoints)' + tests: + - feel-expression: 1 in [2,3,4] + expected: + result: + value: "false" + type: boolean +#- id: number_002 +# description: 'number: e1 in [e2,e3,…] (ranges)' +# tests: +# - feel-expression: 1 in [[2..4], [1..3]] +# expected: +# result: +# value: "true" +# type: boolean +- id: number_002_a + description: 'number: e1 in [e2,e3,…] (ranges)' + tests: + - feel-expression: 5 in [[2..4], [1..3]] + expected: + result: + value: "false" + type: boolean +#- id: number_003 +# description: 'number: e1 in <=e2' +# tests: +# - feel-expression: 1 in <= 10 +# expected: +# result: +# value: "true" +# type: boolean +#- id: number_003_1 +# description: 'number: e1 in <=e2' +# tests: +# - feel-expression: 10 in <= 10 +# expected: +# result: +# value: "true" +# type: boolean +#- id: number_003_a +# description: 'number: e1 in <=e2' +# tests: +# - feel-expression: 11 in <= 10 +# expected: +# result: +# value: "false" +# type: boolean +#- id: number_004 +# description: 'number: e1 in =e2' +# tests: +# - feel-expression: 11 in >= 10 +# expected: +# result: +# value: "true" +# type: boolean +#- id: number_005_1 +# description: 'number: e1 in >=e2' +# tests: +# - feel-expression: 10 in >= 10 +# expected: +# result: +# value: "true" +# type: boolean +#- id: number_005_a +# description: 'number: e1 in >=e2' +# tests: +# - feel-expression: 9 in >= 10 +# expected: +# result: +# value: "false" +# type: boolean +#- id: number_006 +# description: 'number: e1 in >e2' +# tests: +# - feel-expression: 11 in > 10 +# expected: +# result: +# value: "true" +# type: boolean +#- id: number_006_a +# description: 'number: e1 in >e2' +# tests: +# - feel-expression: 10 in > 10 +# expected: +# result: +# value: "false" +# type: boolean +- id: number_007_a + description: 'number: e1 in (e2..e3)' + tests: + - feel-expression: 1 in (2..4) + expected: + result: + value: "false" + type: boolean +- id: number_007_b + description: 'number: e1 in (e2..e3)' + tests: + - feel-expression: 2 in (2..4) + expected: + result: + value: "false" + type: boolean +- id: number_007_c + description: 'number: e1 in (e2..e3)' + tests: + - feel-expression: 3 in (2..4) + expected: + result: + value: "true" + type: boolean +- id: number_007_d + description: 'number: e1 in (e2..e3)' + tests: + - feel-expression: 4 in (2..4) + expected: + result: + value: "false" + type: boolean +- id: number_007_e + description: 'number: e1 in (e2..e3)' + tests: + - feel-expression: 5 in (2..4) + expected: + result: + value: "false" + type: boolean +- id: number_008_a + description: 'number: e1 in (e2..e3]' + tests: + - feel-expression: 1 in (2..4] + expected: + result: + value: "false" + type: boolean +- id: number_008_b + description: 'number: e1 in (e2..e3]' + tests: + - feel-expression: 2 in (2..4] + expected: + result: + value: "false" + type: boolean +- id: number_008_c + description: 'number: e1 in (e2..e3]' + tests: + - feel-expression: 3 in (2..4] + expected: + result: + value: "true" + type: boolean +- id: number_008_d + description: 'number: e1 in (e2..e3]' + tests: + - feel-expression: 4 in (2..4] + expected: + result: + value: "true" + type: boolean +- id: number_008_e + description: 'number: e1 in (e2..e3]' + tests: + - feel-expression: 5 in (2..4] + expected: + result: + value: "false" + type: boolean +- id: number_009_a + description: 'number: e1 in [e2..e3)' + tests: + - feel-expression: 1 in [2..4) + expected: + result: + value: "false" + type: boolean +- id: number_009_b + description: 'number: e1 in [e2..e3)' + tests: + - feel-expression: 2 in [2..4) + expected: + result: + value: "true" + type: boolean +- id: number_009_c + description: 'number: e1 in [e2..e3)' + tests: + - feel-expression: 3 in [2..4) + expected: + result: + value: "true" + type: boolean +- id: number_009_d + description: 'number: e1 in [e2..e3)' + tests: + - feel-expression: 4 in [2..4) + expected: + result: + value: "false" + type: boolean +- id: number_009_e + description: 'number: e1 in [e2..e3)' + tests: + - feel-expression: 5 in [2..4) + expected: + result: + value: "false" + type: boolean +- id: number_010_a + description: 'number: e1 in [e2..e3]' + tests: + - feel-expression: 1 in [2..4] + expected: + result: + value: "false" + type: boolean +- id: number_010_b + description: 'number: e1 in [e2..e3]' + tests: + - feel-expression: 2 in [2..4] + expected: + result: + value: "true" + type: boolean +- id: number_010_c + description: 'number: e1 in [e2..e3]' + tests: + - feel-expression: 3 in [2..4] + expected: + result: + value: "true" + type: boolean +- id: number_010_d + description: 'number: e1 in [e2..e3]' + tests: + - feel-expression: 4 in [2..4] + expected: + result: + value: "true" + type: boolean +- id: number_010_e + description: 'number: e1 in [e2..e3]' + tests: + - feel-expression: 5 in [2..4] + expected: + result: + value: "false" + type: boolean +#- id: number_011 +# description: 'number: e1 in e2' +# tests: +# - feel-expression: 1 in 1 +# expected: +# result: +# value: "true" +# type: boolean +#- id: number_014 +# description: 'number: e1 in unary tests' +# tests: +# - feel-expression: 10 in (1, < 5, >=10) +# expected: +# result: +# value: "true" +# type: boolean +#- id: number_014_a +# description: 'number: e1 in unary tests' +# tests: +# - feel-expression: 10 in (1, 5, 9) +# expected: +# result: +# value: "false" +# type: boolean +- id: string_001 + description: 'string: e1 in [e2,e3,…] (endpoints)' + tests: + - feel-expression: '"a" in ["b","c","a"]' + expected: + result: + value: "true" + type: boolean +- id: string_001_a + description: 'string: e1 in [e2,e3,…] (endpoints)' + tests: + - feel-expression: '"a" in ["b","c","d"]' + expected: + result: + value: "false" + type: boolean +#- id: string_002 +# description: 'string: e1 in [e2,e3,…] (ranges)' +# tests: +# - feel-expression: '"b" in [["f".."h"], ["a".."c"]]' +# expected: +# result: +# value: "true" +# type: boolean +- id: string_002_a + description: 'string: e1 in [e2,e3,…] (ranges)' + tests: + - feel-expression: '"i" in [["f".."h"], ["a".."c"]]' + expected: + result: + value: "false" + type: boolean +#- id: string_003 +# description: 'string: e1 in <=e2' +# tests: +# - feel-expression: '"a" in <= "b"' +# expected: +# result: +# value: "true" +# type: boolean +#- id: string_003_1 +# description: 'string: e1 in <=e2' +# tests: +# - feel-expression: '"b" in <= "b"' +# expected: +# result: +# value: "true" +# type: boolean +#- id: string_003_a +# description: 'string: e1 in <=e2' +# tests: +# - feel-expression: '"c" in <= "b"' +# expected: +# result: +# value: "false" +# type: boolean +#- id: string_004 +# description: 'string: e1 in =e2' +# tests: +# - feel-expression: '"b" in >= "a"' +# expected: +# result: +# value: "true" +# type: boolean +#- id: string_005_1 +# description: 'string: e1 in >=e2' +# tests: +# - feel-expression: '"b" in >= "b"' +# expected: +# result: +# value: "true" +# type: boolean +#- id: string_005_a +# description: 'string: e1 in >=e2' +# tests: +# - feel-expression: '"a" in >= "b"' +# expected: +# result: +# value: "false" +# type: boolean +#- id: string_006 +# description: 'string: e1 in >e2' +# tests: +# - feel-expression: '"b" in > "a"' +# expected: +# result: +# value: "true" +# type: boolean +#- id: string_006_a +# description: 'string: e1 in >e2' +# tests: +# - feel-expression: '"b" in > "b"' +# expected: +# result: +# value: "false" +# type: boolean +- id: string_007_a + description: 'string: e1 in (e2..e3)' + tests: + - feel-expression: '"a" in ("b".."d")' + expected: + result: + value: "false" + type: boolean +- id: string_007_b + description: 'string: e1 in (e2..e3)' + tests: + - feel-expression: '"b" in ("b".."d")' + expected: + result: + value: "false" + type: boolean +- id: string_007_c + description: 'string: e1 in (e2..e3)' + tests: + - feel-expression: '"c" in ("b".."d")' + expected: + result: + value: "true" + type: boolean +- id: string_007_d + description: 'string: e1 in (e2..e3)' + tests: + - feel-expression: '"d" in ("b".."d")' + expected: + result: + value: "false" + type: boolean +- id: string_007_e + description: 'string: e1 in (e2..e3)' + tests: + - feel-expression: '"e" in ("b".."d")' + expected: + result: + value: "false" + type: boolean +- id: string_008_a + description: 'string: e1 in (e2..e3]' + tests: + - feel-expression: '"a" in ("b".."d"]' + expected: + result: + value: "false" + type: boolean +- id: string_008_b + description: 'string: e1 in (e2..e3]' + tests: + - feel-expression: '"b" in ("b".."d"]' + expected: + result: + value: "false" + type: boolean +- id: string_008_c + description: 'string: e1 in (e2..e3]' + tests: + - feel-expression: '"c" in ("b".."d"]' + expected: + result: + value: "true" + type: boolean +- id: string_008_d + description: 'string: e1 in (e2..e3]' + tests: + - feel-expression: '"d" in ("b".."d"]' + expected: + result: + value: "true" + type: boolean +- id: string_008_e + description: 'string: e1 in (e2..e3]' + tests: + - feel-expression: '"e" in ("b".."d"]' + expected: + result: + value: "false" + type: boolean +- id: string_009_a + description: 'string: e1 in [e2..e3)' + tests: + - feel-expression: '"a" in ["b".."d")' + expected: + result: + value: "false" + type: boolean +- id: string_009_b + description: 'string: e1 in [e2..e3)' + tests: + - feel-expression: '"b" in ["b".."d")' + expected: + result: + value: "true" + type: boolean +- id: string_009_c + description: 'string: e1 in [e2..e3)' + tests: + - feel-expression: '"c" in ["b".."d")' + expected: + result: + value: "true" + type: boolean +- id: string_009_d + description: 'string: e1 in [e2..e3)' + tests: + - feel-expression: '"d" in ["b".."d")' + expected: + result: + value: "false" + type: boolean +- id: string_009_e + description: 'string: e1 in [e2..e3)' + tests: + - feel-expression: '"e" in ["b".."d")' + expected: + result: + value: "false" + type: boolean +- id: string_010_a + description: 'string: e1 in [e2..e3]' + tests: + - feel-expression: '"a" in ["b".."d"]' + expected: + result: + value: "false" + type: boolean +- id: string_010_b + description: 'string: e1 in [e2..e3]' + tests: + - feel-expression: '"b" in ["b".."d"]' + expected: + result: + value: "true" + type: boolean +- id: string_010_c + description: 'string: e1 in [e2..e3]' + tests: + - feel-expression: '"c" in ["b".."d"]' + expected: + result: + value: "true" + type: boolean +- id: string_010_d + description: 'string: e1 in [e2..e3]' + tests: + - feel-expression: '"d" in ["b".."d"]' + expected: + result: + value: "true" + type: boolean +- id: string_010_e + description: 'string: e1 in [e2..e3]' + tests: + - feel-expression: '"e" in ["b".."d"]' + expected: + result: + value: "false" + type: boolean +#- id: string_011 +# description: 'string: e1 in e2' +# tests: +# - feel-expression: '"a" in "a"' +# expected: +# result: +# value: "true" +# type: boolean +#- id: string_014 +# description: 'string: e1 in unary tests' +# tests: +# - feel-expression: '"d" in ("c", < "c", >="d")' +# expected: +# result: +# value: "true" +# type: boolean +#- id: string_014_a +# description: 'string: e1 in unary tests' +# tests: +# - feel-expression: '"d" in ("c", >="e")' +# expected: +# result: +# value: "false" +# type: boolean +- id: boolean_001 + description: 'boolean: e1 in [e2,e3,…] (endpoints)' + tests: + - feel-expression: true in [true, false] + expected: + result: + value: "true" + type: boolean +- id: boolean_001_a + description: 'boolean: e1 in [e2,e3,…] (endpoints)' + tests: + - feel-expression: true in [false, 2, 3] + expected: + result: + value: "false" + type: boolean +#- id: boolean_011 +# description: 'boolean: e1 in e2' +# tests: +# - feel-expression: true in true +# expected: +# result: +# value: "true" +# type: boolean +#- id: boolean_014 +# description: 'boolean: e1 in unary tests' +# tests: +# - feel-expression: true in (false, true) +# expected: +# result: +# value: "true" +# type: boolean +#- id: boolean_014_a +# description: 'boolean: e1 in unary tests' +# tests: +# - feel-expression: true in (false, false) +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_001 +# description: 'date: e1 in [e2,e3,…] (endpoints)' +# tests: +# - feel-expression: date("2018-12-08") in [date("2018-12-08"),date("2018-12-09"),date("2018-12-10")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_001_a +# description: 'date: e1 in [e2,e3,…] (endpoints)' +# tests: +# - feel-expression: date("2018-12-11") in [date("2018-12-08"),date("2018-12-09"),date("2018-12-10")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_002 +# description: 'date: e1 in [e2,e3,…] (ranges)' +# tests: +# - feel-expression: date("2018-12-11") in [[date("2018-12-05") .. date("2018-12-07")], [date("2018-12-10") .. date("2018-12-12")]] +# expected: +# result: +# value: "true" +# type: boolean +- id: date_002_a + description: 'date: e1 in [e2,e3,…] (ranges)' + tests: + - feel-expression: date("2018-12-04") in [[date("2018-12-05") .. date("2018-12-07")], [date("2018-12-10") .. date("2018-12-12")]] + expected: + result: + value: "false" + type: boolean +#- id: date_003 +# description: 'date: e1 in <=e2' +# tests: +# - feel-expression: date("2018-12-04") in <= date("2018-12-05") +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_003_1 +# description: 'date: e1 in <=e2' +# tests: +# - feel-expression: date("2018-12-04") in <= date("2018-12-04") +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_003_a +# description: 'date: e1 in <=e2' +# tests: +# - feel-expression: date("2018-12-05") in <= date("2018-12-04") +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_004 +# description: 'date: e1 in =e2' +# tests: +# - feel-expression: date("2018-12-11") in >= date("2018-12-10") +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_005_1 +# description: 'date: e1 in >=e2' +# tests: +# - feel-expression: date("2018-12-10") in >= date("2018-12-10") +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_005_a +# description: 'string: e1 in >=e2' +# tests: +# - feel-expression: date("2018-12-09") in >= date("2018-12-10") +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_006 +# description: 'date: e1 in >e2' +# tests: +# - feel-expression: date("2018-12-11") in > date("2018-12-10") +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_006_a +# description: 'string: e1 in >e2' +# tests: +# - feel-expression: date("2018-12-10") in > date("2018-12-10") +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_007_a +# description: 'date: e1 in (e2..e3)' +# tests: +# - feel-expression: date("2018-12-01") in (date("2018-12-02")..date("2018-12-04")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_007_b +# description: 'date: e1 in (e2..e3)' +# tests: +# - feel-expression: date("2018-12-02") in (date("2018-12-02")..date("2018-12-04")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_007_c +# description: 'date: e1 in (e2..e3)' +# tests: +# - feel-expression: date("2018-12-03") in (date("2018-12-02")..date("2018-12-04")) +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_007_d +# description: 'date: e1 in (e2..e3)' +# tests: +# - feel-expression: date("2018-12-04") in (date("2018-12-02")..date("2018-12-04")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_007_e +# description: 'date: e1 in (e2..e3)' +# tests: +# - feel-expression: date("2018-12-05") in (date("2018-12-02")..date("2018-12-04")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_008_a +# description: 'date: e1 in (e2..e3]' +# tests: +# - feel-expression: date("2018-12-01") in (date("2018-12-02")..date("2018-12-04")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_008_b +# description: 'date: e1 in (e2..e3]' +# tests: +# - feel-expression: date("2018-12-02") in (date("2018-12-02")..date("2018-12-04")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_008_c +# description: 'date: e1 in (e2..e3]' +# tests: +# - feel-expression: date("2018-12-03") in (date("2018-12-02")..date("2018-12-04")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_008_d +# description: 'date: e1 in (e2..e3]' +# tests: +# - feel-expression: date("2018-12-04") in (date("2018-12-02")..date("2018-12-04")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_008_e +# description: 'date: e1 in (e2..e3]' +# tests: +# - feel-expression: date("2018-12-05") in (date("2018-12-02")..date("2018-12-04")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_009_a +# description: 'date: e1 in [e2..e3)' +# tests: +# - feel-expression: date("2018-12-01") in [date("2018-12-02")..date("2018-12-04")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_009_b +# description: 'date: e1 in [e2..e3)' +# tests: +# - feel-expression: date("2018-12-02") in [date("2018-12-02")..date("2018-12-04")) +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_009_c +# description: 'date: e1 in [e2..e3)' +# tests: +# - feel-expression: date("2018-12-03") in [date("2018-12-02")..date("2018-12-04")) +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_009_d +# description: 'date: e1 in [e2..e3)' +# tests: +# - feel-expression: date("2018-12-04") in [date("2018-12-02")..date("2018-12-04")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_009_e +# description: 'date: e1 in [e2..e3)' +# tests: +# - feel-expression: date("2018-12-05") in [date("2018-12-02")..date("2018-12-04")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_010_a +# description: 'date: e1 in [e2..e3]' +# tests: +# - feel-expression: date("2018-12-01") in [date("2018-12-02")..date("2018-12-04")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_010_b +# description: 'date: e1 in [e2..e3]' +# tests: +# - feel-expression: date("2018-12-02") in [date("2018-12-02")..date("2018-12-04")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_010_c +# description: 'date: e1 in [e2..e3]' +# tests: +# - feel-expression: date("2018-12-03") in [date("2018-12-02")..date("2018-12-04")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_010_d +# description: 'date: e1 in [e2..e3]' +# tests: +# - feel-expression: date("2018-12-04") in [date("2018-12-02")..date("2018-12-04")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_010_e +# description: 'date: e1 in [e2..e3]' +# tests: +# - feel-expression: date("2018-12-05") in [date("2018-12-02")..date("2018-12-04")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: date_011 +# description: 'date: e1 in e2' +# tests: +# - feel-expression: date("2018-12-05") in date("2018-12-05") +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_014 +# description: 'date: e1 in unary tests' +# tests: +# - feel-expression: date("2018-12-05") in (date("2018-12-04"), >=date("2018-12-05")) +# expected: +# result: +# value: "true" +# type: boolean +#- id: date_014_a +# description: 'date: e1 in unary tests' +# tests: +# - feel-expression: date("2018-12-05") in (date("2018-12-04"), >=date("2018-12-06")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: time_001 +# description: 'time: e1 in [e2,e3,…] (endpoints)' +# tests: +# - feel-expression: time("10:30:08") in [time("10:30:08"),time("10:30:09"),time("10:30:10")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: time_001_a +# description: 'time: e1 in [e2,e3,…] (endpoints)' +# tests: +# - feel-expression: time("10:30:11") in [time("10:30:08"),time("10:30:09"),time("10:30:10")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: time_002 +# description: 'time: e1 in [e2,e3,…] (ranges)' +# tests: +# - feel-expression: time("10:30:11") in [[time("10:30:05") .. time("10:30:07")], [time("10:30:10") .. time("10:30:12")]] +# expected: +# result: +# value: "true" +# type: boolean +- id: time_002_a + description: 'time: e1 in [e2,e3,…] (ranges)' + tests: + - feel-expression: time("10:30:04") in [[time("10:30:05") .. time("10:30:07")], [time("10:30:10") .. time("10:30:12")]] + expected: + result: + value: "false" + type: boolean +#- id: time_003 +# description: 'time: e1 in <=e2' +# tests: +# - feel-expression: time("10:30:04") in <= time("10:30:05") +# expected: +# result: +# value: "true" +# type: boolean +#- id: time_003_1 +# description: 'time: e1 in <=e2' +# tests: +# - feel-expression: time("10:30:04") in <= time("10:30:04") +# expected: +# result: +# value: "true" +# type: boolean +#- id: time_003_a +# description: 'time: e1 in <=e2' +# tests: +# - feel-expression: time("10:30:05") in <= time("10:30:04") +# expected: +# result: +# value: "false" +# type: boolean +#- id: time_004 +# description: 'time: e1 in =e2' +# tests: +# - feel-expression: time("10:30:11") in >= time("10:30:10") +# expected: +# result: +# value: "true" +# type: boolean +#- id: time_005_1 +# description: 'time: e1 in >=e2' +# tests: +# - feel-expression: time("10:30:10") in >= time("10:30:10") +# expected: +# result: +# value: "true" +# type: boolean +#- id: time_005_a +# description: 'time: e1 in >=e2' +# tests: +# - feel-expression: time("10:30:09") in >= time("10:30:10") +# expected: +# result: +# value: "false" +# type: boolean +#- id: time_006 +# description: 'time: e1 in >e2' +# tests: +# - feel-expression: time("10:30:11") in > time("10:30:10") +# expected: +# result: +# value: "true" +# type: boolean +#- id: time_006_a +# description: 'time: e1 in >e2' +# tests: +# - feel-expression: time("10:30:10") in > time("10:30:10") +# expected: +# result: +# value: "false" +# type: boolean +- id: time_007_a + description: 'time: e1 in (e2..e3)' + tests: + - feel-expression: time("10:30:01") in (time("10:30:02")..time("10:30:04")) + expected: + result: + value: "false" + type: boolean +- id: time_007_b + description: 'time: e1 in (e2..e3)' + tests: + - feel-expression: time("10:30:02") in (time("10:30:02")..time("10:30:04")) + expected: + result: + value: "false" + type: boolean +- id: time_007_c + description: 'time: e1 in (e2..e3)' + tests: + - feel-expression: time("10:30:03") in (time("10:30:02")..time("10:30:04")) + expected: + result: + value: "true" + type: boolean +- id: time_007_d + description: 'time: e1 in (e2..e3)' + tests: + - feel-expression: time("10:30:04") in (time("10:30:02")..time("10:30:04")) + expected: + result: + value: "false" + type: boolean +- id: time_007_e + description: 'time: e1 in (e2..e3)' + tests: + - feel-expression: time("10:30:05") in (time("10:30:02")..time("10:30:04")) + expected: + result: + value: "false" + type: boolean +- id: time_008_a + description: 'time: e1 in (e2..e3]' + tests: + - feel-expression: time("10:30:01") in (time("10:30:02")..time("10:30:04")] + expected: + result: + value: "false" + type: boolean +- id: time_008_b + description: 'time: e1 in (e2..e3]' + tests: + - feel-expression: time("10:30:02") in (time("10:30:02")..time("10:30:04")] + expected: + result: + value: "false" + type: boolean +- id: time_008_c + description: 'time: e1 in (e2..e3]' + tests: + - feel-expression: time("10:30:03") in (time("10:30:02")..time("10:30:04")] + expected: + result: + value: "true" + type: boolean +- id: time_008_d + description: 'time: e1 in (e2..e3]' + tests: + - feel-expression: time("10:30:04") in (time("10:30:02")..time("10:30:04")] + expected: + result: + value: "true" + type: boolean +- id: time_008_e + description: 'time: e1 in (e2..e3]' + tests: + - feel-expression: time("10:30:05") in (time("10:30:02")..time("10:30:04")] + expected: + result: + value: "false" + type: boolean +- id: time_009_a + description: 'time: e1 in [e2..e3)' + tests: + - feel-expression: time("10:30:01") in [time("10:30:02")..time("10:30:04")) + expected: + result: + value: "false" + type: boolean +- id: time_009_b + description: 'time: e1 in [e2..e3)' + tests: + - feel-expression: time("10:30:02") in [time("10:30:02")..time("10:30:04")) + expected: + result: + value: "true" + type: boolean +- id: time_009_c + description: 'time: e1 in [e2..e3)' + tests: + - feel-expression: time("10:30:03") in [time("10:30:02")..time("10:30:04")) + expected: + result: + value: "true" + type: boolean +- id: time_009_d + description: 'time: e1 in [e2..e3)' + tests: + - feel-expression: time("10:30:04") in [time("10:30:02")..time("10:30:04")) + expected: + result: + value: "false" + type: boolean +- id: time_009_e + description: 'time: e1 in [e2..e3)' + tests: + - feel-expression: time("10:30:05") in [time("10:30:02")..time("10:30:04")) + expected: + result: + value: "false" + type: boolean +- id: time_010_a + description: 'time: e1 in [e2..e3]' + tests: + - feel-expression: time("10:30:01") in [time("10:30:02")..time("10:30:04")] + expected: + result: + value: "false" + type: boolean +- id: time_010_b + description: 'time: e1 in [e2..e3]' + tests: + - feel-expression: time("10:30:02") in [time("10:30:02")..time("10:30:04")] + expected: + result: + value: "true" + type: boolean +- id: time_010_c + description: 'time: e1 in [e2..e3]' + tests: + - feel-expression: time("10:30:03") in [time("10:30:02")..time("10:30:04")] + expected: + result: + value: "true" + type: boolean +- id: time_010_d + description: 'time: e1 in [e2..e3]' + tests: + - feel-expression: time("10:30:04") in [time("10:30:02")..time("10:30:04")] + expected: + result: + value: "true" + type: boolean +- id: time_010_e + description: 'time: e1 in [e2..e3]' + tests: + - feel-expression: time("10:30:05") in [time("10:30:02")..time("10:30:04")] + expected: + result: + value: "false" + type: boolean +#- id: time_011 +# description: 'time: e1 in e2' +# tests: +# - feel-expression: time("10:30:05") in time("10:30:05") +# expected: +# result: +# value: "true" +# type: boolean +#- id: time_014 +# description: 'time: e1 in unary tests' +# tests: +# - feel-expression: time("10:30:05") in (time("10:30:04"), >=time("10:30:05")) +# expected: +# result: +# value: "true" +# type: boolean +#- id: time_014_a +# description: 'time: e1 in unary tests' +# tests: +# - feel-expression: time("10:30:05") in (time("10:30:04"), >=time("10:30:06")) +# expected: +# result: +# value: "false" +# type: boolean +- id: dateTime_001 + description: 'dateTime: e1 in [e2,e3,…] (endpoints)' + tests: + - feel-expression: date and time("2018-12-08T10:30:08") in [date and time("2018-12-08T10:30:08"),date and time("2018-12-08T10:30:09"),date and time("2018-12-08T10:30:10")] + expected: + result: + value: "true" + type: boolean +- id: dateTime_001_a + description: 'dateTime: e1 in [e2,e3,…] (endpoints)' + tests: + - feel-expression: date and time("2018-12-08T10:30:11") in [date and time("2018-12-08T10:30:08"),date and time("2018-12-08T10:30:09"),date and time("2018-12-08T10:30:10")] + expected: + result: + value: "false" + type: boolean +#- id: dateTime_002 +# description: 'dateTime: e1 in [e2,e3,…] (ranges)' +# tests: +# - feel-expression: date and time("2018-12-08T10:30:11") in [[date and time("2018-12-08T10:30:05") .. date and time("2018-12-08T10:30:07")], [date and time("2018-12-08T10:30:10") .. date and time("2018-12-08T10:30:12")]] +# expected: +# result: +# value: "true" +# type: boolean +- id: dateTime_002_a + description: 'dateTime: e1 in [e2,e3,…] (ranges)' + tests: + - feel-expression: date and time("2018-12-08T10:30:04") in [[date and time("2018-12-08T10:30:05") .. date and time("2018-12-08T10:30:07")], [date and time("2018-12-08T10:30:10") .. date and time("2018-12-08T10:30:12")]] + expected: + result: + value: "false" + type: boolean +#- id: dateTime_003 +# description: 'dateTime: e1 in <=e2' +# tests: +# - feel-expression: date and time("2018-12-08T10:30:04") in <= date and time("2018-12-08T10:30:05") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dateTime_003_1 +# description: 'dateTime: e1 in <=e2' +# tests: +# - feel-expression: date and time("2018-12-08T10:30:04") in <= date and time("2018-12-08T10:30:04") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dateTime_003_a +# description: 'dateTime: e1 in <=e2' +# tests: +# - feel-expression: date and time("2018-12-08T10:30:05") in <= date and time("2018-12-08T10:30:04") +# expected: +# result: +# value: "false" +# type: boolean +#- id: dateTime_004 +# description: 'dateTime: e1 in =e2' +# tests: +# - feel-expression: date and time("2018-12-08T10:30:11") in >= date and time("2018-12-08T10:30:10") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dateTime_005_1 +# description: 'dateTime: e1 in >=e2' +# tests: +# - feel-expression: date and time("2018-12-08T10:30:10") in >= date and time("2018-12-08T10:30:10") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dateTime_005_a +# description: 'dateTime: e1 in >=e2' +# tests: +# - feel-expression: date and time("2018-12-08T10:30:09") in >= date and time("2018-12-08T10:30:10") +# expected: +# result: +# value: "false" +# type: boolean +#- id: dateTime_006 +# description: 'dateTime: e1 in >e2' +# tests: +# - feel-expression: date and time("2018-12-08T10:30:11") in > date and time("2018-12-08T10:30:10") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dateTime_006_a +# description: 'dateTime: e1 in >e2' +# tests: +# - feel-expression: date and time("2018-12-08T10:30:10") in > date and time("2018-12-08T10:30:10") +# expected: +# result: +# value: "false" +# type: boolean +- id: dateTime_007_a + description: 'dateTime: e1 in (e2..e3)' + tests: + - feel-expression: date and time("2018-12-08T10:30:01") in (date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")) + expected: + result: + value: "false" + type: boolean +- id: dateTime_007_b + description: 'dateTime: e1 in (e2..e3)' + tests: + - feel-expression: date and time("2018-12-08T10:30:02") in (date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")) + expected: + result: + value: "false" + type: boolean +- id: dateTime_007_c + description: 'dateTime: e1 in (e2..e3)' + tests: + - feel-expression: date and time("2018-12-08T10:30:03") in (date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")) + expected: + result: + value: "true" + type: boolean +- id: dateTime_007_d + description: 'dateTime: e1 in (e2..e3)' + tests: + - feel-expression: date and time("2018-12-08T10:30:04") in (date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")) + expected: + result: + value: "false" + type: boolean +- id: dateTime_007_e + description: 'dateTime: e1 in (e2..e3)' + tests: + - feel-expression: date and time("2018-12-08T10:30:05") in (date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")) + expected: + result: + value: "false" + type: boolean +- id: dateTime_008_a + description: 'dateTime: e1 in (e2..e3]' + tests: + - feel-expression: date and time("2018-12-08T10:30:01") in (date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")] + expected: + result: + value: "false" + type: boolean +- id: dateTime_008_b + description: 'dateTime: e1 in (e2..e3]' + tests: + - feel-expression: date and time("2018-12-08T10:30:02") in (date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")] + expected: + result: + value: "false" + type: boolean +- id: dateTime_008_c + description: 'dateTime: e1 in (e2..e3]' + tests: + - feel-expression: date and time("2018-12-08T10:30:03") in (date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")] + expected: + result: + value: "true" + type: boolean +- id: dateTime_008_d + description: 'dateTime: e1 in (e2..e3]' + tests: + - feel-expression: date and time("2018-12-08T10:30:04") in (date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")] + expected: + result: + value: "true" + type: boolean +- id: dateTime_008_e + description: 'dateTime: e1 in (e2..e3]' + tests: + - feel-expression: date and time("2018-12-08T10:30:05") in (date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")] + expected: + result: + value: "false" + type: boolean +- id: dateTime_009_a + description: 'dateTime: e1 in [e2..e3)' + tests: + - feel-expression: date and time("2018-12-08T10:30:01") in [date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")) + expected: + result: + value: "false" + type: boolean +- id: dateTime_009_b + description: 'dateTime: e1 in [e2..e3)' + tests: + - feel-expression: date and time("2018-12-08T10:30:02") in [date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")) + expected: + result: + value: "true" + type: boolean +- id: dateTime_009_c + description: 'dateTime: e1 in [e2..e3)' + tests: + - feel-expression: date and time("2018-12-08T10:30:03") in [date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")) + expected: + result: + value: "true" + type: boolean +- id: dateTime_009_d + description: 'dateTime: e1 in [e2..e3)' + tests: + - feel-expression: date and time("2018-12-08T10:30:04") in [date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")) + expected: + result: + value: "false" + type: boolean +- id: dateTime_009_e + description: 'dateTime: e1 in [e2..e3)' + tests: + - feel-expression: date and time("2018-12-08T10:30:05") in [date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")) + expected: + result: + value: "false" + type: boolean +- id: dateTime_010_a + description: 'dateTime: e1 in [e2..e3]' + tests: + - feel-expression: date and time("2018-12-08T10:30:01") in [date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")] + expected: + result: + value: "false" + type: boolean +- id: dateTime_010_b + description: 'dateTime: e1 in [e2..e3]' + tests: + - feel-expression: date and time("2018-12-08T10:30:02") in [date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")] + expected: + result: + value: "true" + type: boolean +- id: dateTime_010_c + description: 'dateTime: e1 in [e2..e3]' + tests: + - feel-expression: date and time("2018-12-08T10:30:03") in [date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")] + expected: + result: + value: "true" + type: boolean +- id: dateTime_010_d + description: 'dateTime: e1 in [e2..e3]' + tests: + - feel-expression: date and time("2018-12-08T10:30:04") in [date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")] + expected: + result: + value: "true" + type: boolean +- id: dateTime_010_e + description: 'dateTime: e1 in [e2..e3]' + tests: + - feel-expression: date and time("2018-12-08T10:30:05") in [date and time("2018-12-08T10:30:02")..date and time("2018-12-08T10:30:04")] + expected: + result: + value: "false" + type: boolean +#- id: dateTime_011 +# description: 'dateTime: e1 in e2' +# tests: +# - feel-expression: date and time("2018-12-08T10:30:05") in date and time("2018-12-08T10:30:05") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dateTime_014 +# description: 'dateTime: e1 in unary tests' +# tests: +# - feel-expression: date and time("2018-12-08T10:30:05") in (date and time("2018-12-08T10:30:04"), >=date and time("2018-12-08T10:30:05")) +# expected: +# result: +# value: "true" +# type: boolean +#- id: dateTime_014_a +# description: 'dateTime: e1 in unary tests' +# tests: +# - feel-expression: date and time("2018-12-08T10:30:05") in (date and time("2018-12-08T10:30:04"), >=date and time("2018-12-08T10:30:06")) +# expected: +# result: +# value: "false" +# type: boolean +- id: list_001 + description: 'list: e1 in [e2,e3,…] (endpoints)' + tests: + - feel-expression: '[1,2,3] in [[1,2,3,4], [1,2,3]]' + expected: + result: + value: "true" + type: boolean +- id: list_001_a + description: 'list: e1 in [e2,e3,…] (endpoints)' + tests: + - feel-expression: '[1,2,3,5] in [[1,2,3,4], [1,2,3]]' + expected: + result: + value: "false" + type: boolean +- id: list_011_a + description: 'list: e1 in e2' + tests: + - feel-expression: '[1,2,3] in [[1,2,3], [1,2,3,4]]' + expected: + result: + value: "true" + type: boolean +- id: list_011_b + description: 'list: e1 in e2' + tests: + - feel-expression: '[1,2,2] in [[1,2,3], [1,2,3,4]]' + expected: + result: + value: "false" + type: boolean +#- id: list_014_a +# description: 'list: e1 in unary tests' +# tests: +# - feel-expression: '[1,2,3] in ([[1,2,3,4]], [[1,2,3,5]])' +# expected: +# result: +# value: "false" +# type: boolean +- id: context_001 + description: 'context: e1 in [e2,e3,…] (endpoints)' + tests: + - feel-expression: '{a: "foo"} in [{b: "bar"}, {a: "foo"}]' + expected: + result: + value: "true" + type: boolean +- id: context_001_a + description: 'context: e1 in [e2,e3,…] (endpoints)' + tests: + - feel-expression: '{c: "baz"} in [{b: "bar"}, {a: "foo"}]' + expected: + result: + value: "false" + type: boolean +#- id: context_011 +# description: 'context: e1 in e2' +# tests: +# - feel-expression: '{a: "foo"} in {a: "foo"}' +# expected: +# result: +# value: "true" +# type: boolean +#- id: context_014 +# description: 'context: e1 in unary tests' +# tests: +# - feel-expression: '{a: "foo"} in ({a: "bar"}, {a: "foo"})' +# expected: +# result: +# value: "true" +# type: boolean +#- id: context_014_a +# description: 'context: e1 in unary tests' +# tests: +# - feel-expression: '{a: "foo"} in ({a: "bar"}, {a: "baz"})' +# expected: +# result: +# value: "false" +# type: boolean +- id: ym_duration_001 + description: 'ym_duration: e1 in [e2,e3,…] (endpoints)' + tests: + - feel-expression: duration("P8Y") in [duration("P8Y"),duration("P9Y"),duration("P10Y")] + expected: + result: + value: "true" + type: boolean +- id: ym_duration_001_a + description: 'ym_duration: e1 in [e2,e3,…] (endpoints)' + tests: + - feel-expression: duration("P11Y") in [duration("P8Y"),duration("P9Y"),duration("P10Y")] + expected: + result: + value: "false" + type: boolean +#- id: ym_duration_002 +# description: 'ym_duration: e1 in [e2,e3,…] (ranges)' +# tests: +# - feel-expression: duration("P11Y") in [[duration("P5Y") .. duration("P7Y")], [duration("P10Y") .. duration("P12Y")]] +# expected: +# result: +# value: "true" +# type: boolean +- id: ym_duration_002_a + description: 'ym_duration: e1 in [e2,e3,…] (ranges)' + tests: + - feel-expression: duration("P4Y") in [[duration("P5Y") .. duration("P7Y")], [duration("P10Y") .. duration("P12Y")]] + expected: + result: + value: "false" + type: boolean +#- id: ym_duration_003 +# description: 'ym_duration: e1 in <=e2' +# tests: +# - feel-expression: duration("P4Y") in <= duration("P5Y") +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_003_1 +# description: 'ym_duration: e1 in <=e2' +# tests: +# - feel-expression: duration("P4Y") in <= duration("P4Y") +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_003_a +# description: 'ym_duration: e1 in <=e2' +# tests: +# - feel-expression: duration("P5Y") in <= duration("P4Y") +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_004 +# description: 'ym_duration: e1 in =e2' +# tests: +# - feel-expression: duration("P11Y") in >= duration("P10Y") +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_005_1 +# description: 'ym_duration: e1 in >=e2' +# tests: +# - feel-expression: duration("P10Y") in >= duration("P10Y") +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_005_a +# description: 'ym_duration: e1 in >=e2' +# tests: +# - feel-expression: duration("P9Y") in >= duration("P10Y") +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_006 +# description: 'ym_duration: e1 in >e2' +# tests: +# - feel-expression: duration("P11Y") in > duration("P10Y") +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_006_a +# description: 'ym_duration: e1 in >e2' +# tests: +# - feel-expression: duration("P10Y") in > duration("P10Y") +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_007_a +# description: 'ym_duration: e1 in (e2..e3)' +# tests: +# - feel-expression: duration("P1Y") in (duration("P2Y")..duration("P4Y")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_007_b +# description: 'ym_duration: e1 in (e2..e3)' +# tests: +# - feel-expression: duration("P2Y") in (duration("P2Y")..duration("P4Y")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_007_c +# description: 'ym_duration: e1 in (e2..e3)' +# tests: +# - feel-expression: duration("P3Y") in (duration("P2Y")..duration("P4Y")) +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_007_d +# description: 'ym_duration: e1 in (e2..e3)' +# tests: +# - feel-expression: duration("P4Y") in (duration("P2Y")..duration("P4Y")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_007_e +# description: 'ym_duration: e1 in (e2..e3)' +# tests: +# - feel-expression: duration("P5Y") in (duration("P2Y")..duration("P4Y")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_008_a +# description: 'ym_duration: e1 in (e2..e3]' +# tests: +# - feel-expression: duration("P1Y") in (duration("P2Y")..duration("P4Y")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_008_b +# description: 'ym_duration: e1 in (e2..e3]' +# tests: +# - feel-expression: duration("P2Y") in (duration("P2Y")..duration("P4Y")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_008_c +# description: 'ym_duration: e1 in (e2..e3]' +# tests: +# - feel-expression: duration("P3Y") in (duration("P2Y")..duration("P4Y")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_008_d +# description: 'ym_duration: e1 in (e2..e3]' +# tests: +# - feel-expression: duration("P4Y") in (duration("P2Y")..duration("P4Y")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_008_e +# description: 'ym_duration: e1 in (e2..e3]' +# tests: +# - feel-expression: duration("P5Y") in (duration("P2Y")..duration("P4Y")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_009_a +# description: 'ym_duration: e1 in [e2..e3)' +# tests: +# - feel-expression: duration("P1Y") in [duration("P2Y")..duration("P4Y")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_009_b +# description: 'ym_duration: e1 in [e2..e3)' +# tests: +# - feel-expression: duration("P2Y") in [duration("P2Y")..duration("P4Y")) +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_009_c +# description: 'ym_duration: e1 in [e2..e3)' +# tests: +# - feel-expression: duration("P3Y") in [duration("P2Y")..duration("P4Y")) +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_009_d +# description: 'ym_duration: e1 in [e2..e3)' +# tests: +# - feel-expression: duration("P4Y") in [duration("P2Y")..duration("P4Y")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_009_e +# description: 'ym_duration: e1 in [e2..e3)' +# tests: +# - feel-expression: duration("P5Y") in [duration("P2Y")..duration("P4Y")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_010_a +# description: 'ym_duration: e1 in [e2..e3]' +# tests: +# - feel-expression: duration("P1Y") in [duration("P2Y")..duration("P4Y")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_010_b +# description: 'ym_duration: e1 in [e2..e3]' +# tests: +# - feel-expression: duration("P2Y") in [duration("P2Y")..duration("P4Y")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_010_c +# description: 'ym_duration: e1 in [e2..e3]' +# tests: +# - feel-expression: duration("P3Y") in [duration("P2Y")..duration("P4Y")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_010_d +# description: 'ym_duration: e1 in [e2..e3]' +# tests: +# - feel-expression: duration("P4Y") in [duration("P2Y")..duration("P4Y")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_010_e +# description: 'ym_duration: e1 in [e2..e3]' +# tests: +# - feel-expression: duration("P5Y") in [duration("P2Y")..duration("P4Y")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: ym_duration_011 +# description: 'ym_duration: e1 in e2' +# tests: +# - feel-expression: duration("P5Y") in duration("P5Y") +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_014 +# description: 'ym_duration: e1 in unary tests' +# tests: +# - feel-expression: duration("P5Y") in (duration("P4Y"), >=duration("P5Y")) +# expected: +# result: +# value: "true" +# type: boolean +#- id: ym_duration_014_a +# description: 'ym_duration: e1 in unary tests' +# tests: +# - feel-expression: duration("P5Y") in (duration("P4Y"), >=duration("P6Y")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_001 +# description: 'dt_duration: e1 in [e2,e3,…] (endpoints)' +# tests: +# - feel-expression: duration("P8D") in [duration("P8D"),duration("P9D"),duration("P10D")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_001_a +# description: 'dt_duration: e1 in [e2,e3,…] (endpoints)' +# tests: +# - feel-expression: duration("P11D") in [duration("P8D"),duration("P9D"),duration("P10D")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_002 +# description: 'dt_duration: e1 in [e2,e3,…] (ranges)' +# tests: +# - feel-expression: duration("P11D") in [[duration("P5D") .. duration("P7D")], [duration("P10D") .. duration("P12D")]] +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_002_a +# description: 'dt_duration: e1 in [e2,e3,…] (ranges)' +# tests: +# - feel-expression: duration("P4D") in [[duration("P5D") .. duration("P7D")], [duration("P10D") .. duration("P12D")]] +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_003 +# description: 'dt_duration: e1 in <=e2' +# tests: +# - feel-expression: duration("P4D") in <= duration("P5D") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_003_1 +# description: 'dt_duration: e1 in <=e2' +# tests: +# - feel-expression: duration("P4D") in <= duration("P4D") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_003_a +# description: 'dt_duration: e1 in <=e2' +# tests: +# - feel-expression: duration("P5D") in <= duration("P4D") +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_004 +# description: 'dt_duration: e1 in =e2' +# tests: +# - feel-expression: duration("P11D") in >= duration("P10D") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_005_1 +# description: 'dt_duration: e1 in >=e2' +# tests: +# - feel-expression: duration("P10D") in >= duration("P10D") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_005_a +# description: 'dt_duration: e1 in >=e2' +# tests: +# - feel-expression: duration("P9D") in >= duration("P10D") +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_006 +# description: 'dt_duration: e1 in >e2' +# tests: +# - feel-expression: duration("P11D") in > duration("P10D") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_006_a +# description: 'dt_duration: e1 in >e2' +# tests: +# - feel-expression: duration("P10D") in > duration("P10D") +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_007_a +# description: 'dt_duration: e1 in (e2..e3)' +# tests: +# - feel-expression: duration("P1D") in (duration("P2D")..duration("P4D")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_007_b +# description: 'dt_duration: e1 in (e2..e3)' +# tests: +# - feel-expression: duration("P2D") in (duration("P2D")..duration("P4D")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_007_c +# description: 'dt_duration: e1 in (e2..e3)' +# tests: +# - feel-expression: duration("P3D") in (duration("P2D")..duration("P4D")) +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_007_d +# description: 'dt_duration: e1 in (e2..e3)' +# tests: +# - feel-expression: duration("P4D") in (duration("P2D")..duration("P4D")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_007_e +# description: 'dt_duration: e1 in (e2..e3)' +# tests: +# - feel-expression: duration("P5D") in (duration("P2D")..duration("P4D")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_008_a +# description: 'dt_duration: e1 in (e2..e3]' +# tests: +# - feel-expression: duration("P1D") in (duration("P2D")..duration("P4D")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_008_b +# description: 'dt_duration: e1 in (e2..e3]' +# tests: +# - feel-expression: duration("P2D") in (duration("P2D")..duration("P4D")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_008_c +# description: 'dt_duration: e1 in (e2..e3]' +# tests: +# - feel-expression: duration("P3D") in (duration("P2D")..duration("P4D")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_008_d +# description: 'dt_duration: e1 in (e2..e3]' +# tests: +# - feel-expression: duration("P4D") in (duration("P2D")..duration("P4D")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_008_e +# description: 'dt_duration: e1 in (e2..e3]' +# tests: +# - feel-expression: duration("P5D") in (duration("P2D")..duration("P4D")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_009_a +# description: 'dt_duration: e1 in [e2..e3)' +# tests: +# - feel-expression: duration("P1D") in [duration("P2D")..duration("P4D")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_009_b +# description: 'dt_duration: e1 in [e2..e3)' +# tests: +# - feel-expression: duration("P2D") in [duration("P2D")..duration("P4D")) +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_009_c +# description: 'dt_duration: e1 in [e2..e3)' +# tests: +# - feel-expression: duration("P3D") in [duration("P2D")..duration("P4D")) +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_009_d +# description: 'dt_duration: e1 in [e2..e3)' +# tests: +# - feel-expression: duration("P4D") in [duration("P2D")..duration("P4D")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_009_e +# description: 'dt_duration: e1 in [e2..e3)' +# tests: +# - feel-expression: duration("P5D") in [duration("P2D")..duration("P4D")) +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_010_a +# description: 'dt_duration: e1 in [e2..e3]' +# tests: +# - feel-expression: duration("P1D") in [duration("P2D")..duration("P4D")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_010_b +# description: 'dt_duration: e1 in [e2..e3]' +# tests: +# - feel-expression: duration("P2D") in [duration("P2D")..duration("P4D")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_010_c +# description: 'dt_duration: e1 in [e2..e3]' +# tests: +# - feel-expression: duration("P3D") in [duration("P2D")..duration("P4D")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_010_d +# description: 'dt_duration: e1 in [e2..e3]' +# tests: +# - feel-expression: duration("P4D") in [duration("P2D")..duration("P4D")] +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_010_e +# description: 'dt_duration: e1 in [e2..e3]' +# tests: +# - feel-expression: duration("P5D") in [duration("P2D")..duration("P4D")] +# expected: +# result: +# value: "false" +# type: boolean +#- id: dt_duration_011 +# description: 'dt_duration: e1 in e2' +# tests: +# - feel-expression: duration("P5D") in duration("P5D") +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_014 +# description: 'dt_duration: e1 in unary tests' +# tests: +# - feel-expression: duration("P5D") in (duration("P4D"), >=duration("P5D")) +# expected: +# result: +# value: "true" +# type: boolean +#- id: dt_duration_014_a +# description: 'dt_duration: e1 in unary tests' +# tests: +# - feel-expression: duration("P5D") in (duration("P4D"), >=duration("P6D")) +# expected: +# result: +# value: "false" +# type: boolean diff --git a/tests/feel-list.yaml b/tests/feel-list.yaml new file mode 100644 index 0000000..5faa0e2 --- /dev/null +++ b/tests/feel-list.yaml @@ -0,0 +1,346 @@ +- id: "001" + description: creation of list + tests: + - feel-expression: '[1,2,3]' + expected: + results: + - result: + value: "1" + type: decimal + - result: + value: "2" + type: decimal + - result: + value: "3" + type: decimal +#- id: 001_a +# description: creation of empty list +# tests: +# - feel-expression: '[]' +# expected: +# results: [] +#- id: "002" +# description: access of index 0 +# tests: +# - feel-expression: '[1,2,3][0]' +# expected: +# result: +# value: null +#- id: "003" +# description: access of index > size +# tests: +# - feel-expression: '[1,2,3][4]' +# expected: +# result: +# value: null +- id: "004" + description: access of first element + tests: + - feel-expression: '[1,2,3][1]' + expected: + result: + value: "1" + type: decimal +- id: "005" + description: access of last element + tests: + - feel-expression: '[1,2,3][3]' + expected: + result: + value: "3" + type: decimal +#- id: "006" +# description: access of negative element +# tests: +# - feel-expression: '[1,2,3][-1]' +# expected: +# result: +# value: "3" +# type: decimal +#- id: "007" +# description: access of negative element +# tests: +# - feel-expression: '[1,2,3][-3]' +# expected: +# result: +# value: "1" +# type: decimal +#- id: "008" +# description: access of negative element > -size +# tests: +# - feel-expression: '[1,2,3][-4]' +# expected: +# result: +# value: null +#- id: "009" +# description: true boolean index element gives entire list +# tests: +# - feel-expression: '[1,2,3][true]' +# expected: +# results: +# - result: +# value: "1" +# type: decimal +# - result: +# value: "2" +# type: decimal +# - result: +# value: "3" +# type: decimal +#- id: "010" +# description: false boolean index element gives empty list +# tests: +# - feel-expression: '[1,2,3][false]' +# expected: +# results: [] +#- id: "011" +# description: filter expression using item +# tests: +# - feel-expression: '[1,2,3][item >= 2]' +# expected: +# results: +# - result: +# value: "2" +# type: decimal +# - result: +# value: "3" +# type: decimal +#- id: "012" +# description: true filter expression on non list - boolean +# tests: +# - feel-expression: true[true] +# expected: +# results: +# - result: +# value: "true" +# type: boolean +#- id: "013" +# description: false filter expression on non list - boolean +# tests: +# - feel-expression: true[false] +# expected: +# results: [] +#- id: "014" +# description: true filter expression on non list - number +# tests: +# - feel-expression: 100[true] +# expected: +# results: +# - result: +# value: "100" +# type: decimal +#- id: "015" +# description: false filter expression on non list - number +# tests: +# - feel-expression: 100[false] +# expected: +# results: [] +#- id: "016" +# description: true filter expression on non list - string +# tests: +# - feel-expression: '"foo"[true]' +# expected: +# results: +# - result: +# value: foo +# type: string +#- id: "017" +# description: false filter expression on non list - string +# tests: +# - feel-expression: '"foo"[false]' +# expected: +# results: [] +#- id: "018" +# description: index of 1 on non list - boolean +# tests: +# - feel-expression: true[1] +# expected: +# result: +# value: "true" +# type: boolean +#- id: "019" +# description: index of 1 on non list - number +# tests: +# - feel-expression: 100[1] +# expected: +# result: +# value: "100" +# type: decimal +#- id: "020" +# description: index of 1 on non list - string +# tests: +# - feel-expression: '"foo"[1]' +# expected: +# result: +# value: foo +# type: string +#- id: "021" +# description: index of 0 on non list - boolean +# tests: +# - feel-expression: true[0] +# expected: +# result: +# value: null +#- id: "022" +# description: index of 0 on non list - number +# tests: +# - feel-expression: 100[0] +# expected: +# result: +# value: null +#- id: "023" +# description: index of 0 on non list - string +# tests: +# - feel-expression: '"foo"[0]' +# expected: +# result: +# value: null +#- id: "024" +# description: filter on context using item +# tests: +# - feel-expression: '[{a: 1}, {a: 2}, {a: 3}][item.a >= 2]' +# expected: +# results: +# - components: +# - name: a +# expected: +# result: +# value: "2" +# type: decimal +# - components: +# - name: a +# expected: +# result: +# value: "3" +# type: decimal +#- id: "025" +# description: filter on context using property name +# tests: +# - feel-expression: '[{a: 1}, {a: 2}, {a: 3}][a >= 2]' +# expected: +# results: +# - components: +# - name: a +# expected: +# result: +# value: "2" +# type: decimal +# - components: +# - name: a +# expected: +# result: +# value: "3" +# type: decimal +#- id: "026" +# description: filter on context using property 'item' name +# tests: +# - feel-expression: '[{item: 1}, {item: 2}, {item: 3}][item >= 2]' +# expected: +# results: +# - components: +# - name: item +# expected: +# result: +# value: "2" +# type: decimal +# - components: +# - name: item +# expected: +# result: +# value: "3" +# type: decimal +#- id: "027" +# description: filter on scalars (10.3.2.5 - example 1) +# tests: +# - feel-expression: '[ 1, 2, 3, 4 ][ item > 2 ]' +# expected: +# results: +# - result: +# value: "3" +# type: decimal +# - result: +# value: "4" +# type: decimal +#- id: "028" +# description: filter on property name (10.3.2.5 - example 2) +# tests: +# - feel-expression: '[ { x: 1, y: 2 }, { x: 2, y: 3 } ][ x = 1 ]' +# expected: +# results: +# - components: +# - name: x +# expected: +# result: +# value: "1" +# type: decimal +# - name: "y" +# expected: +# result: +# value: "2" +# type: decimal +#- id: "029" +# description: filter on property name + null value (10.3.2.5 - example 3) +# tests: +# - feel-expression: '[ { x: 1, y: 2 }, { x: null, y: 3 } ][ x < 2 ]' +# expected: +# results: +# - components: +# - name: x +# expected: +# result: +# value: "1" +# type: decimal +# - name: "y" +# expected: +# result: +# value: "2" +# type: decimal +#- id: "030" +# description: path expression (10.3.2.5 - example 4) +# tests: +# - feel-expression: '[ { x: 1, y: 2 }, { x: 2, y: 3 } ].y' +# expected: +# results: +# - result: +# value: "2" +# type: decimal +# - result: +# value: "3" +# type: decimal +#- id: "031" +# description: filter / non-member matching (empty) +# tests: +# - feel-expression: '[ { x: 1 } ][ y > 1 ]' +# expected: +# results: [] +#- id: "032" +# description: filter / non-member matching (single result) +# tests: +# - feel-expression: '[ { x: 1 }, { y: 2 } ][ y > 1 ]' +# expected: +# results: +# - components: +# - name: "y" +# expected: +# result: +# value: "2" +# type: decimal +#- id: "033" +# description: path expression / no match +# tests: +# - feel-expression: '[ { x: 1 } ].y' +# expected: +# results: +# - result: +# value: null +#- id: "034" +# description: path expression / partial match +# tests: +# - feel-expression: '[ { x: 1 }, { y: 2 } ].y' +# expected: +# results: +# - result: +# value: null +# - result: +# value: "2" +# type: decimal diff --git a/tests/feel-lower-case-function.yaml b/tests/feel-lower-case-function.yaml new file mode 100644 index 0000000..b9abe25 --- /dev/null +++ b/tests/feel-lower-case-function.yaml @@ -0,0 +1,72 @@ +- id: 001_f6ff05bcfa + description: "" + tests: + - feel-expression: lower case("A") + expected: + result: + value: a + type: string +- id: 002_0ecb21e1d8 + description: "" + tests: + - feel-expression: lower case("ABC") + expected: + result: + value: abc + type: string +- id: 003_af9f3a8dab + description: "" + tests: + - feel-expression: lower case("abc") + expected: + result: + value: abc + type: string +- id: 004_2dbf99e8c0 + description: "" + tests: + - feel-expression: lower case("aBc4") + expected: + result: + value: abc4 + type: string +- id: 005_ad33325968 + description: "" + tests: + - feel-expression: lower case("") + expected: + result: + value: "" + type: string +- id: 006_d8257b3b92 + description: "" + tests: + - feel-expression: lower case("?@{") + expected: + result: + value: ?@{ + type: string +- id: 007_a2ce59499a + description: "" + tests: + - feel-expression: lower case(string:"AbDcF") + expected: + result: + value: abdcf + type: string +- id: 008_9913ad454f + description: "" + tests: + - feel-expression: lower case(string:"xyZ ") + expected: + result: + value: 'xyz ' + type: string +- id: 009_78e6b2969b + description: "" + tests: + - feel-expression: lower case(string:"123ABC") + expected: + result: + value: 123abc + type: string diff --git a/tests/feel-math.yaml b/tests/feel-math.yaml new file mode 100644 index 0000000..56e55eb --- /dev/null +++ b/tests/feel-math.yaml @@ -0,0 +1,255 @@ +- id: "001" + description: Tests FEEL addition of number literals + tests: + - feel-expression: 10+5 + expected: + result: + value: "15" + type: decimal +- id: "002" + description: Tests FEEL addition of negative number literals + tests: + - feel-expression: -10+-5 + expected: + result: + value: "-15" + type: decimal +- id: "003" + description: Tests FEEL addition of negative number literals with brakets + tests: + - feel-expression: (-10)+(-5) + expected: + result: + value: "-15" + type: decimal +#- id: "004" +# description: Tests FEEL subtraction of number literals +# tests: +# - feel-expression: 10-5 +# expected: +# result: +# value: "5" +# type: decimal +- id: "005" + description: Tests FEEL subtraction of negative number literals + tests: + - feel-expression: -10--5 + expected: + result: + value: "-5" + type: decimal +- id: "006" + description: Tests FEEL subtraction of negative number literals with brakets + tests: + - feel-expression: (-10)-(-5) + expected: + result: + value: "-5" + type: decimal +- id: "007" + description: Tests FEEL addition and subtraction of number literals with brakets + tests: + - feel-expression: (10+20)-(-5+3) + expected: + result: + value: "32" + type: decimal +- id: "008" + description: Tests FEEL multiplication of number literals + tests: + - feel-expression: 10*5 + expected: + result: + value: "50" + type: decimal +- id: "009" + description: Tests FEEL multiplication of negative number literals + tests: + - feel-expression: -10*-5 + expected: + result: + value: "50" + type: decimal +- id: "010" + description: Tests FEEL multiplication of negative number literals with brakets + tests: + - feel-expression: (-10)*(-5) + expected: + result: + value: "50" + type: decimal +- id: "011" + description: Tests FEEL addition and multiplication of number literals with brakets + tests: + - feel-expression: (10+5)*(-5*3) + expected: + result: + value: "-225" + type: decimal +- id: "012" + description: Tests FEEL division of number literals + tests: + - feel-expression: 10/5 + expected: + result: + value: "2" + type: decimal +- id: "013" + description: Tests FEEL division of negative number literals + tests: + - feel-expression: -10/-5 + expected: + result: + value: "2" + type: decimal +- id: "014" + description: Tests FEEL division of negative number literals with brakets + tests: + - feel-expression: (-10)/(-5) + expected: + result: + value: "2" + type: decimal +- id: "015" + description: Tests FEEL addition and division of number literals with brakets + tests: + - feel-expression: (10+20)/(-5*3) + expected: + result: + value: "-2" + type: decimal +#- id: "016" +# description: Tests FEEL division by zero +# tests: +# - feel-expression: (10+20)/0 +# expected: +# result: +# value: null +#- id: "017" +# description: Tests FEEL potency of number literal +# tests: +# - feel-expression: 10**5 +# expected: +# result: +# value: "100000" +# type: decimal +#- id: "018" +# description: Tests FEEL negative potency of number literal +# tests: +# - feel-expression: 10**-5 +# expected: +# result: +# value: "0.00001" +# type: decimal +#- id: "019" +# description: Tests FEEL potency of number literal with brakets +# tests: +# - feel-expression: (5+2)**5 +# expected: +# result: +# value: "16807" +# type: decimal +#- id: "020" +# description: Tests FEEL addition and potency of number literals +# tests: +# - feel-expression: 5+2**5 +# expected: +# result: +# value: "37" +# type: decimal +#- id: "021" +# description: Tests FEEL addition and potency of number literals +# tests: +# - feel-expression: 5+2**5+3 +# expected: +# result: +# value: "40" +# type: decimal +#- id: "022" +# description: Tests FEEL addition and potency of number literals with brakets +# tests: +# - feel-expression: 5+2**(5+3) +# expected: +# result: +# value: "261" +# type: decimal +#- id: "023" +# description: Tests FEEL addition with null +# tests: +# - feel-expression: 10+null +# expected: +# result: +# value: null +#- id: "024" +# description: Tests FEEL addition with null +# tests: +# - feel-expression: null + 10 +# expected: +# result: +# value: null +#- id: "025" +# description: Tests FEEL subtraction with null +# tests: +# - feel-expression: 10 - null +# expected: +# result: +# value: null +#- id: "026" +# description: Tests FEEL subtraction with null +# tests: +# - feel-expression: null - 10 +# expected: +# result: +# value: null +#- id: "027" +# description: Tests FEEL multiplication with null +# tests: +# - feel-expression: 10 * null +# expected: +# result: +# value: null +#- id: "028" +# description: Tests FEEL multiplication with null +# tests: +# - feel-expression: null * 10 +# expected: +# result: +# value: null +#- id: "029" +# description: Tests FEEL division with null +# tests: +# - feel-expression: 10 / null +# expected: +# result: +# value: null +#- id: "030" +# description: Tests FEEL division with null +# tests: +# - feel-expression: null / 10 +# expected: +# result: +# value: null +- id: "031" + description: Tests FEEL arithmetics with spaces between number literals + tests: + - feel-expression: 10 + 20 / -5 - 3 + expected: + result: + value: "3" + type: decimal +#- id: "032" +# description: Tests FEEL arithmetics with spaces between number literals and brakets +# tests: +# - feel-expression: 10 + 20 / (-5 - 3) +# expected: +# result: +# value: "7.5" +# type: decimal +#- id: "033" +# description: Tests FEEL arithmetics with decimal number literals +# tests: +# - feel-expression: 1.2*10**3 +# expected: +# result: +# value: "1200" +# type: decimal diff --git a/tests/feel-median-function.yaml b/tests/feel-median-function.yaml new file mode 100644 index 0000000..5f9d553 --- /dev/null +++ b/tests/feel-median-function.yaml @@ -0,0 +1,105 @@ +- id: "001" + description: will return median for even list size + tests: + - feel-expression: median([8, 2, 5, 3, 4]) + expected: + result: + value: "4" + type: decimal +#- id: "002" +# description: will return median for odd list size +# tests: +# - feel-expression: median([8, 2, 5, 7]) +# expected: +# result: +# value: "6" +# type: decimal +#- id: "003" +# description: will error when no params +# tests: +# - feel-expression: median() +# expected: +# result: +# value: null +#- id: 003_a +# description: will error when null param +# tests: +# - feel-expression: median(null) +# expected: +# result: +# value: null +#- id: "004" +# description: will error when list item not a number +# tests: +# - feel-expression: median() +# expected: +# result: +# value: null +#- id: "005" +# description: will error when list item not a number +# tests: +# - feel-expression: median([1,2,"foo",4]) +# expected: +# result: +# value: null +#- id: "006" +# description: will median to decimals +# tests: +# - feel-expression: median([6, 1, 2, 3]) +# expected: +# result: +# value: "2.5" +# type: decimal +#- id: "007" +# description: will return null for empty list +# tests: +# - feel-expression: median([]) +# expected: +# result: +# value: null +- id: "008" + description: will coerce singleton list + tests: + - feel-expression: median(4) + expected: + result: + value: "4" + type: decimal +- id: "009" + description: will return median for even varargs list size + tests: + - feel-expression: median(8, 2, 5, 3, 4) + expected: + result: + value: "4" + type: decimal +#- id: "010" +# description: will return median for odd varargs list size +# tests: +# - feel-expression: median(8, 2, 5, 7) +# expected: +# result: +# value: "6" +# type: decimal +#- id: "011" +# description: will return median - named param +# tests: +# - feel-expression: median(list:[8, 2, 5, 7]) +# expected: +# result: +# value: "6" +# type: decimal +#- id: "012" +# description: will error when null named param +# tests: +# - feel-expression: median(list:null) +# expected: +# result: +# value: null +#- id: "013" +# description: will error when wrongly named param +# tests: +# - feel-expression: median(l:[2, 4, 7, 5]) +# expected: +# result: +# value: null diff --git a/tests/feel-negation.yaml b/tests/feel-negation.yaml new file mode 100644 index 0000000..e0d9117 --- /dev/null +++ b/tests/feel-negation.yaml @@ -0,0 +1,44 @@ +- id: "001" + description: "" + tests: + - feel-expression: not(true) + expected: + result: + value: "false" + type: boolean +- id: "002" + description: "" + tests: + - feel-expression: not(false) + expected: + result: + value: "true" + type: boolean +#- id: 003_a +# description: "" +# tests: +# - feel-expression: not(null) +# expected: +# result: +# value: null +#- id: 003_b +# description: "" +# tests: +# - feel-expression: not(0) +# expected: +# result: +# value: null +#- id: 003_c +# description: "" +# tests: +# - feel-expression: not(1) +# expected: +# result: +# value: null +#- id: 003_d +# description: "" +# tests: +# - feel-expression: not("true") +# expected: +# result: +# value: null diff --git a/tests/feel-product-function.yaml b/tests/feel-product-function.yaml new file mode 100644 index 0000000..919ebec --- /dev/null +++ b/tests/feel-product-function.yaml @@ -0,0 +1,97 @@ +- id: "001" + description: will return product for list + tests: + - feel-expression: product([6, 3, 9, 6, 6]) + expected: + result: + value: "5832" + type: decimal +#- id: "002" +# description: will return null when empty list +# tests: +# - feel-expression: product([]) +# expected: +# result: +# value: null +#- id: "003" +# description: will return null when no params +# tests: +# - feel-expression: product() +# expected: +# result: +# value: null +#- id: 003_a +# description: will error when null param +# tests: +# - feel-expression: product(null) +# expected: +# result: +# value: null +#- id: "004" +# description: will error when list item not a number +# tests: +# - feel-expression: product([1,2,null,4]) +# expected: +# result: +# value: null +#- id: "005" +# description: will error when list item not a number +# tests: +# - feel-expression: product([1,2,"foo",4]) +# expected: +# result: +# value: null +- id: "006" + description: will multiple decimals + tests: + - feel-expression: product([2.5, 1, 2.5, 3]) + expected: + result: + value: "18.75" + type: decimal +- id: "007" + description: will multiply varargs number list + tests: + - feel-expression: product(2,3,4) + expected: + result: + value: "24" + type: decimal +- id: "008" + description: product of single item is itself + tests: + - feel-expression: product(6) + expected: + result: + value: "6" + type: decimal +- id: 008_a + description: product of single item list is value of first item + tests: + - feel-expression: product([6]) + expected: + result: + value: "6" + type: decimal +#- id: "011" +# description: will return product for named params +# tests: +# - feel-expression: product(list:[6, 3, 9, 6, 6]) +# expected: +# result: +# value: "5832" +# type: decimal +#- id: "012" +# description: will error when null named param +# tests: +# - feel-expression: product(list:null) +# expected: +# result: +# value: null +#- id: "013" +# description: will error when wrongly named param +# tests: +# - feel-expression: product(l:[2, 4, 7, 5]) +# expected: +# result: +# value: null diff --git a/tests/feel-properties.yaml b/tests/feel-properties.yaml new file mode 100644 index 0000000..047b2b9 --- /dev/null +++ b/tests/feel-properties.yaml @@ -0,0 +1,522 @@ +- id: context_001 + description: "" + tests: + - feel-expression: '{a: "foo"}.a' + expected: + result: + value: foo + type: string +- id: date_001 + description: date - year + tests: + - feel-expression: date("2018-12-10").year + expected: + result: + value: "2018" + type: decimal +#- id: date_002 +# description: date - month +# tests: +# - feel-expression: date("2018-12-10").month +# expected: +# result: +# value: "12" +# type: decimal +- id: date_003 + description: date - day + tests: + - feel-expression: date("2018-12-10").day + expected: + result: + value: "10" + type: decimal +#- id: date_004 +# description: date - weekday +# tests: +# - feel-expression: date("2018-12-10").weekday +# expected: +# result: +# value: "1" +# type: decimal +- id: dateTime_001 + description: dateTime - year + tests: + - feel-expression: date and time("2018-12-10T10:30:01").year + expected: + result: + value: "2018" + type: decimal +#- id: dateTime_002 +# description: dateTime - month +# tests: +# - feel-expression: date and time("2018-12-10T10:30:01").month +# expected: +# result: +# value: "12" +# type: decimal +- id: dateTime_003 + description: dateTime - day + tests: + - feel-expression: date and time("2018-12-10T10:30:01").day + expected: + result: + value: "10" + type: decimal +#- id: dateTime_004 +# description: dateTime - weekday +# tests: +# - feel-expression: date and time("2018-12-10T10:30:01").weekday +# expected: +# result: +# value: "1" +# type: decimal +- id: dateTime_005 + description: dateTime - hour + tests: + - feel-expression: date and time("2018-12-10T10:30:01").hour + expected: + result: + value: "10" + type: decimal +#- id: dateTime_005_a +# description: dateTime - hour when no time specified +# tests: +# - feel-expression: date and time("2018-12-10").hour +# expected: +# result: +# value: "0" +# type: decimal +- id: dateTime_006 + description: dateTime - minute + tests: + - feel-expression: date and time("2018-12-10T10:30:01").minute + expected: + result: + value: "30" + type: decimal +#- id: dateTime_006_a +# description: dateTime - minute when no time specified +# tests: +# - feel-expression: date and time("2018-12-10").minute +# expected: +# result: +# value: "0" +# type: decimal +- id: dateTime_007 + description: dateTime - second + tests: + - feel-expression: date and time("2018-12-10T10:30:01").second + expected: + result: + value: "1" + type: decimal +#- id: dateTime_007_a +# description: dateTime - second when no time specified +# tests: +# - feel-expression: date and time("2018-12-10").second +# expected: +# result: +# value: "0" +# type: decimal +#- id: dateTime_008 +# description: dateTime - time offset when set +# tests: +# - feel-expression: date and time("2018-12-10T10:30:00+05:00").time offset +# expected: +# result: +# value: PT5H +# type: duration +#- id: dateTime_008_a +# description: dateTime - time offset when not set +# tests: +# - feel-expression: date and time("2018-12-10T10:30:00").time offset +# expected: +# result: +# value: null +#- id: dateTime_009 +# description: dateTime - timezone when set +# tests: +# - feel-expression: date and time("2018-12-10T10:30:00@Etc/UTC").timezone +# expected: +# result: +# value: Etc/UTC +# type: string +#- id: dateTime_009_a +# description: dateTime - timezone when not set +# tests: +# - feel-expression: date and time("2018-12-10T10:30:00").timezone +# expected: +# result: +# value: null +- id: time_001 + description: time - hour + tests: + - feel-expression: time("10:30:01").hour + expected: + result: + value: "10" + type: decimal +- id: time_002 + description: time - minute + tests: + - feel-expression: time("10:30:01").minute + expected: + result: + value: "30" + type: decimal +- id: time_003 + description: time - second + tests: + - feel-expression: time("10:30:01").second + expected: + result: + value: "1" + type: decimal +#- id: time_004 +# description: time - time offset when set +# tests: +# - feel-expression: time("10:30:00+05:00").time offset +# expected: +# result: +# value: PT5H +# type: duration +#- id: time_004_a +# description: time - time offset when not set +# tests: +# - feel-expression: time("10:30:00").time offset +# expected: +# result: +# value: null +#- id: time_005_a +# description: time - timezone when not set +# tests: +# - feel-expression: time("10:30:00").timezone +# expected: +# result: +# value: null +- id: ym_duration_001 + description: ym duration - years + tests: + - feel-expression: duration("P1Y2M").years + expected: + result: + value: "1" + type: decimal +- id: ym_duration_001_a + description: ym duration - years not set + tests: + - feel-expression: duration("P2M").years + expected: + result: + value: "0" + type: decimal +- id: ym_duration_002 + description: ym duration - month + tests: + - feel-expression: duration("P2M").months + expected: + result: + value: "2" + type: decimal +- id: ym_duration_002_a + description: ym duration - months not set + tests: + - feel-expression: duration("P1Y").months + expected: + result: + value: "0" + type: decimal +#- id: ym_duration_003 +# description: ym duration - days is null +# tests: +# - feel-expression: duration("P1Y").days +# expected: +# result: +# value: null +#- id: ym_duration_004 +# description: ym duration - hours is null +# tests: +# - feel-expression: duration("P1Y").hours +# expected: +# result: +# value: null +#- id: ym_duration_005 +# description: ym duration - minutes is null +# tests: +# - feel-expression: duration("P1Y").minutes +# expected: +# result: +# value: null +#- id: ym_duration_006 +# description: ym duration - seconds is null +# tests: +# - feel-expression: duration("P1Y").seconds +# expected: +# result: +# value: null +#- id: dt_duration_001 +# description: dt duration - years is null +# tests: +# - feel-expression: duration("P1D").years +# expected: +# result: +# value: null +#- id: dt_duration_002 +# description: dt duration - months is null +# tests: +# - feel-expression: duration("P1D").months +# expected: +# result: +# value: null +#- id: dt_duration_003 +# description: dt duration - days +# tests: +# - feel-expression: duration("P1D").days +# expected: +# result: +# value: "1" +# type: decimal +- id: dt_duration_003_a + description: dt duration - days is not set + tests: + - feel-expression: duration("PT2H").days + expected: + result: + value: "0" + type: decimal +- id: dt_duration_004 + description: dt duration - hours + tests: + - feel-expression: duration("PT2H").hours + expected: + result: + value: "2" + type: decimal +#- id: dt_duration_004_a +# description: dt duration - hours is not set +# tests: +# - feel-expression: duration("P1D").hours +# expected: +# result: +# value: "0" +# type: decimal +- id: dt_duration_005 + description: dt duration - minutes + tests: + - feel-expression: duration("PT2M").minutes + expected: + result: + value: "2" + type: decimal +#- id: dt_duration_005_a +# description: dt duration - minutes is not set +# tests: +# - feel-expression: duration("P1D").minutes +# expected: +# result: +# value: "0" +# type: decimal +- id: dt_duration_006 + description: dt duration - seconds + tests: + - feel-expression: duration("PT2S").seconds + expected: + result: + value: "2" + type: decimal +#- id: dt_duration_006_a +# description: dt duration - seconds is not set +# tests: +# - feel-expression: duration("P1D").seconds +# expected: +# result: +# value: "0" +# type: decimal +#- id: range_001 +# description: range - start +# tests: +# - feel-expression: '[1..10].start' +# expected: +# result: +# value: "1" +# type: decimal +#- id: range_002 +# description: range - end +# tests: +# - feel-expression: '[1..10].end' +# expected: +# result: +# value: "10" +# type: decimal +#- id: range_003 +# description: range - start included +# tests: +# - feel-expression: '[1..10].start included' +# expected: +# result: +# value: "true" +# type: boolean +#- id: range_004 +# description: range - start included '(' syntax +# tests: +# - feel-expression: (1..10].start included +# expected: +# result: +# value: "false" +# type: boolean +#- id: range_005 +# description: range - start included ']' syntax +# tests: +# - feel-expression: ']1..10].start included' +# expected: +# result: +# value: "false" +# type: boolean +#- id: range_006 +# description: range - end included +# tests: +# - feel-expression: '[1..10].end included' +# expected: +# result: +# value: "true" +# type: boolean +#- id: range_007 +# description: 'range - end included '')'' syntax ' +# tests: +# - feel-expression: '[1..10).end included' +# expected: +# result: +# value: "false" +# type: boolean +#- id: range_008 +# description: range - end included '[' syntax +# tests: +# - feel-expression: '[1..10[.end included' +# expected: +# result: +# value: "false" +# type: boolean +#- id: range_009 +# description: 'range - start: LT unary syntax' +# tests: +# - feel-expression: (< 10).start +# expected: +# result: +# value: null +#- id: range_010 +# description: 'range - start: LE unary syntax' +# tests: +# - feel-expression: (<= 10).start +# expected: +# result: +# value: null +#- id: range_011 +# description: 'range - start: GT unary syntax' +# tests: +# - feel-expression: (> 10).start +# expected: +# result: +# value: "10" +# type: decimal +#- id: range_012 +# description: 'range - start: GE unary syntax' +# tests: +# - feel-expression: (>= 10).start +# expected: +# result: +# value: "10" +# type: decimal +#- id: range_013 +# description: 'range - end: LT unary syntax' +# tests: +# - feel-expression: (< 10).end +# expected: +# result: +# value: "10" +# type: decimal +#- id: range_014 +# description: 'range - end: LE unary syntax' +# tests: +# - feel-expression: (<= 10).end +# expected: +# result: +# value: "10" +# type: decimal +#- id: range_015 +# description: 'range - end: GT unary syntax' +# tests: +# - feel-expression: (> 10).end +# expected: +# result: +# value: null +#- id: range_016 +# description: 'range - end: GE unary syntax' +# tests: +# - feel-expression: (>= 10).end +# expected: +# result: +# value: null +#- id: range_017 +# description: 'range - start included: LT unary syntax' +# tests: +# - feel-expression: (< 10).start included +# expected: +# result: +# value: "false" +# type: boolean +#- id: range_018 +# description: 'range - start included: LE unary syntax' +# tests: +# - feel-expression: (<= 10).start included +# expected: +# result: +# value: "false" +# type: boolean +#- id: range_019 +# description: 'range - start included: GT unary syntax' +# tests: +# - feel-expression: (> 10).start included +# expected: +# result: +# value: "false" +# type: boolean +#- id: range_020 +# description: 'range - start included: GE unary syntax' +# tests: +# - feel-expression: (>= 10).start included +# expected: +# result: +# value: "true" +# type: boolean +#- id: range_021 +# description: 'range - end included: LT unary syntax' +# tests: +# - feel-expression: (< 10).end included +# expected: +# result: +# value: "false" +# type: boolean +#- id: range_022 +# description: 'range - end included: LE unary syntax' +# tests: +# - feel-expression: (<= 10).end included +# expected: +# result: +# value: "true" +# type: boolean +#- id: range_023 +# description: 'range - end included: GT unary syntax' +# tests: +# - feel-expression: (> 10).end included +# expected: +# result: +# value: "false" +# type: boolean +#- id: range_024 +# description: 'range - end included: GE unary syntax' +# tests: +# - feel-expression: (>= 10).end included +# expected: +# result: +# value: "false" +# type: boolean diff --git a/tests/feel-string-function.yaml b/tests/feel-string-function.yaml new file mode 100644 index 0000000..fd67006 --- /dev/null +++ b/tests/feel-string-function.yaml @@ -0,0 +1,292 @@ +#- id: decision_001 +# description: no param +# tests: +# - feel-expression: string() +# expected: +# result: +# value: null +#- id: decision_002 +# description: too many params +# tests: +# - feel-expression: string("foo", "bar") +# expected: +# result: +# value: null +- id: decision_003 + description: named param + tests: + - feel-expression: string(from:"foo") + expected: + result: + value: foo + type: string +#- id: decision_004 +# description: badly named param +# tests: +# - feel-expression: string("foo", "bar") +# expected: +# result: +# value: null +#- id: null_001 +# description: null param gives null, not "null" +# tests: +# - feel-expression: string(null) +# expected: +# result: +# value: null +- id: string_001 + description: string param + tests: + - feel-expression: string("foo") + expected: + result: + value: foo + type: string +- id: number_001 + description: string param + tests: + - feel-expression: string(123.45) + expected: + result: + value: "123.45" + type: string +#- id: boolean_001 +# description: boolean true +# tests: +# - feel-expression: string(true) +# expected: +# result: +# value: "true" +# type: string +#- id: boolean_002 +# description: boolean false +# tests: +# - feel-expression: string(false) +# expected: +# result: +# value: "false" +# type: string +- id: date_001 + description: date + tests: + - feel-expression: string(date("2018-12-10")) + expected: + result: + value: "2018-12-10" + type: string +#- id: dateTime_001 +# description: dateTime - date only +# tests: +# - feel-expression: string(date and time("2018-12-10")) +# expected: +# result: +# value: 2018-12-10T00:00:00 +# type: string +#- id: dateTime_002 +# description: dateTime - with time +# tests: +# - feel-expression: string(date and time("2018-12-10T10:30:00.0001")) +# expected: +# result: +# value: 2018-12-10T10:30:00.0001 +# type: string +#- id: dateTime_003 +# description: dateTime - with time and offset +# tests: +# - feel-expression: string(date and time("2018-12-10T10:30:00.0001+05:00:01")) +# expected: +# result: +# value: 2018-12-10T10:30:00.0001+05:00:01 +# type: string +#- id: dateTime_004 +# description: dateTime - with time and zone +# tests: +# - feel-expression: string(date and time("2018-12-10T10:30:00@Etc/UTC")) +# expected: +# result: +# value: 2018-12-10T10:30:00@Etc/UTC +# type: string +#- id: time_001 +# description: time +# tests: +# - feel-expression: string(time("10:30:00.0001")) +# expected: +# result: +# value: "10:30:00.0001" +# type: string +#- id: time_002 +# description: time - with offset +# tests: +# - feel-expression: string(time("10:30:00.0001+05:00:01")) +# expected: +# result: +# value: 10:30:00.0001+05:00:01 +# type: string +#- id: time_003 +# description: time - with zone +# tests: +# - feel-expression: string(time("10:30:00@Etc/UTC")) +# expected: +# result: +# value: 10:30:00@Etc/UTC +# type: string +#- id: dt_duration_001 +# description: dt duration 1D +# tests: +# - feel-expression: string(duration("P1D")) +# expected: +# result: +# value: P1D +# type: string +#- id: dt_duration_002 +# description: dt duration -1D +# tests: +# - feel-expression: string(duration("-P1D")) +# expected: +# result: +# value: -P1D +# type: string +#- id: dt_duration_003 +# description: dt duration P0D +# tests: +# - feel-expression: string(duration("P0D")) +# expected: +# result: +# value: PT0S +# type: string +#- id: dt_duration_004 +# description: dt duration P1DT2H3M4.1234S +# tests: +# - feel-expression: string(duration("P1DT2H3M4.1234S")) +# expected: +# result: +# value: P1DT2H3M4.1234S +# type: string +#- id: dt_duration_005 +# description: dt duration P49H +# tests: +# - feel-expression: string(duration("PT49H")) +# expected: +# result: +# value: P2DT1H +# type: string +- id: ym_duration_001 + description: ym duration P1Y + tests: + - feel-expression: string(duration("P1Y")) + expected: + result: + value: P1Y + type: string +- id: ym_duration_002 + description: ym duration -P1Y + tests: + - feel-expression: string(duration("-P1Y")) + expected: + result: + value: -P1Y + type: string +#- id: ym_duration_003 +# description: ym duration P0Y +# tests: +# - feel-expression: string(duration("P0Y")) +# expected: +# result: +# value: P0M +# type: string +- id: ym_duration_004 + description: ym duration P1Y2M + tests: + - feel-expression: string(duration("P1Y2M")) + expected: + result: + value: P1Y2M + type: string +#- id: ym_duration_005 +# description: ym duration P25M +# tests: +# - feel-expression: string(duration("P25M")) +# expected: +# result: +# value: P2Y1M +# type: string +#- id: list_001 +# description: list +# tests: +# - feel-expression: string([1,2,3,"foo"]) +# expected: +# result: +# value: '[1, 2, 3, "foo"]' +# type: string +#- id: list_002 +# description: nested list +# tests: +# - feel-expression: string([1,2,3,[4,5,"foo"]]) +# expected: +# result: +# value: '[1, 2, 3, [4, 5, "foo"]]' +# type: string +#- id: list_003 +# description: list string get escaped +# tests: +# - feel-expression: string(["\"foo\""]) +# expected: +# result: +# value: '["\"foo\""]' +# type: string +#- id: context_001 +# description: context +# tests: +# - feel-expression: 'string({a: "foo"})' +# expected: +# result: +# value: '{a: "foo"}' +# type: string +#- id: context_002 +# description: nested context +# tests: +# - feel-expression: 'string({a: "foo", b: {bar: "baz"}})' +# expected: +# result: +# value: '{a: "foo", b: {bar: "baz"}}' +# type: string +#- id: context_003 +# description: context entry contains "{" so it gets quotes +# tests: +# - feel-expression: 'string({"{": "foo"})' +# expected: +# result: +# value: '{"{": "foo"}' +# type: string +#- id: context_004 +# description: context entry contains ":" so it gets quotes +# tests: +# - feel-expression: 'string({":": "foo"})' +# expected: +# result: +# value: '{":": "foo"}' +# type: string +#- id: context_005 +# description: context entry contains "," so it gets quotes +# tests: +# - feel-expression: 'string({",": "foo"})' +# expected: +# result: +# value: '{",": "foo"}' +# type: string +#- id: context_006 +# description: context entry contains "}" so it gets quotes +# tests: +# - feel-expression: 'string({"}": "foo"})' +# expected: +# result: +# value: '{"}": "foo"}' +# type: string +#- id: context_007 +# description: context entry contains '"' so it gets escaped and quotes +# tests: +# - feel-expression: 'string({"\"": "foo"})' +# expected: +# result: +# value: '{"\"": "foo"}' +# type: string diff --git a/tests/feel-string-join-function.yaml b/tests/feel-string-join-function.yaml new file mode 100644 index 0000000..cf5d3bb --- /dev/null +++ b/tests/feel-string-join-function.yaml @@ -0,0 +1,168 @@ +- id: "001" + description: Will join + tests: + - feel-expression: string join(["a","b","c"]) + expected: + result: + value: abc + type: string +- id: "002" + description: Will join (with delimiter) + tests: + - feel-expression: string join(["a","b","c"], " and ") + expected: + result: + value: a and b and c + type: string +- id: "003" + description: Will join with empty delimiter + tests: + - feel-expression: string join(["a","b","c"], "") + expected: + result: + value: abc + type: string +#- id: "004" +# description: Will join with null delimiter +# tests: +# - feel-expression: string join(["a","b","c"], null) +# expected: +# result: +# value: abc +# type: string +- id: 005_a + description: Will join single element list + tests: + - feel-expression: string join(["a"]) + expected: + result: + value: a + type: string +- id: 005_b + description: Will join single element list (with delimiter) + tests: + - feel-expression: string join(["a"], "X") + expected: + result: + value: a + type: string +- id: 006_a + description: Will ignore null elements in list + tests: + - feel-expression: string join(["a",null,"c"]) + expected: + result: + value: ac + type: string +- id: 006_b + description: Will ignore null elements in list (with delimiter) + tests: + - feel-expression: string join(["a",null,"c"], "X") + expected: + result: + value: aXc + type: string +- id: 007_a + description: Will join empty list as "" + tests: + - feel-expression: string join([]) + expected: + result: + value: "" + type: string +- id: 007_b + description: Will join empty list as "" (with delimiter) + tests: + - feel-expression: string join([], "X") + expected: + result: + value: "" + type: string +#- id: "008" +# description: No params gives null +# tests: +# - feel-expression: string join() +# expected: +# result: +# value: null +#- id: "009" +# description: Too many params gives null +# tests: +# - feel-expression: string join(["a","c"], "X", "foo") +# expected: +# result: +# value: null +- id: 010_a + description: Join with named param + tests: + - feel-expression: 'string join(list: ["a","c"])' + expected: + result: + value: ac + type: string +- id: 010_b + description: 'Join with named params (with delimiter) ' + tests: + - feel-expression: 'string join(delimiter: "X", list: ["a","c"])' + expected: + result: + value: aXc + type: string +#- id: 011_a +# description: Incorrect named delimiter param gives null +# tests: +# - feel-expression: 'string join(list: ["a","c"], delimitr: "X")' +# expected: +# result: +# value: null +#- id: 011_b +# description: Incorrect named list param gives null +# tests: +# - feel-expression: 'string join(lst: ["a","c"], delimiter: "X")' +# expected: +# result: +# value: null +#- id: 012_a +# description: null list gives null +# tests: +# - feel-expression: string join(null) +# expected: +# result: +# value: null +#- id: 012_b +# description: null list gives null (with delimiter) +# tests: +# - feel-expression: string join(null, "X") +# expected: +# result: +# value: null +#- id: "013" +# description: Incorrect list type gives null +# tests: +# - feel-expression: string join([1,2,3], "X") +# expected: +# result: +# value: null +#- id: "014" +# description: Non-list non-string list param gives null +# tests: +# - feel-expression: string join(123, "X") +# expected: +# result: +# value: null +#- id: "015" +# description: Non-list string list param is coerced to list +# tests: +# - feel-expression: string join("a", "X") +# expected: +# result: +# value: a +# type: string +#- id: "016" +# description: Non-list string named list param is coerced to list +# tests: +# - feel-expression: 'string join(list: "a", delimiter: "X")' +# expected: +# result: +# value: a +# type: string diff --git a/tests/feel-string-length-function.yaml b/tests/feel-string-length-function.yaml new file mode 100644 index 0000000..8e4eca0 --- /dev/null +++ b/tests/feel-string-length-function.yaml @@ -0,0 +1,48 @@ +- id: 001_1afe6930d1 + description: "" + tests: + - feel-expression: string length("") + expected: + result: + value: "0" + type: decimal +- id: 002_249c23050d + description: "" + tests: + - feel-expression: string length("a") + expected: + result: + value: "1" + type: decimal +- id: 003_e1df507dee + description: "" + tests: + - feel-expression: string length("abc") + expected: + result: + value: "3" + type: decimal +- id: 004_f4c02fac3d + description: "" + tests: + - feel-expression: string length(string:"xyz123") + expected: + result: + value: "6" + type: decimal +- id: 005_ca834dabac + description: "" + tests: + - feel-expression: string length(string:"aaaaa dddd") + expected: + result: + value: "10" + type: decimal +- id: 006_6c4930a0eb + description: "" + tests: + - feel-expression: string length(string:"aaaaa dddd ") + expected: + result: + value: "11" + type: decimal diff --git a/tests/feel-substring-function.yaml b/tests/feel-substring-function.yaml new file mode 100644 index 0000000..2f78642 --- /dev/null +++ b/tests/feel-substring-function.yaml @@ -0,0 +1,88 @@ +- id: 001_53051b5628 + description: "" + tests: + - feel-expression: substring("f",1) + expected: + result: + value: f + type: string +- id: 002_03d12b93f0 + description: "" + tests: + - feel-expression: substring("f",1,1) + expected: + result: + value: f + type: string +- id: 003_6d06b1d2ec + description: "" + tests: + - feel-expression: substring("foobar",6) + expected: + result: + value: r + type: string +- id: 004_938a24e7af + description: "" + tests: + - feel-expression: substring("foobar",1,6) + expected: + result: + value: foobar + type: string +- id: 005_21fcca286c + description: "" + tests: + - feel-expression: substring("foobar",3) + expected: + result: + value: obar + type: string +- id: 006_253e533bc6 + description: "" + tests: + - feel-expression: substring("foobar",3,3) + expected: + result: + value: oba + type: string +#- id: 007_3e021f33a8 +# description: "" +# tests: +# - feel-expression: substring("foobar",-2,1) +# expected: +# result: +# value: a +# type: string +#- id: 008_ddeffdc93e +# description: "" +# tests: +# - feel-expression: substring("foob r",-2,1) +# expected: +# result: +# value: ' ' +# type: string +#- id: 009_b52405c384 +# description: "" +# tests: +# - feel-expression: substring("foobar",-6,6) +# expected: +# result: +# value: foobar +# type: string +- id: 010_fbf9a89fde + description: "" + tests: + - feel-expression: substring("foobar",3,3.8) + expected: + result: + value: oba + type: string +- id: 011_a559ce6410 + description: "" + tests: + - feel-expression: substring(string:"foobar",start position :3) + expected: + result: + value: obar + type: string diff --git a/tests/feel-ternary-logic-not.yaml b/tests/feel-ternary-logic-not.yaml new file mode 100644 index 0000000..5c6a040 --- /dev/null +++ b/tests/feel-ternary-logic-not.yaml @@ -0,0 +1,23 @@ +- id: "001" + description: Tests ternary logic for true + tests: + - feel-expression: not(A) + expected: + result: + value: "false" + type: boolean +#- id: "002" +# description: Tests ternary logic for false +# tests: +# - feel-expression: not(A) +# expected: +# result: +# value: "true" +# type: boolean +#- id: "003" +# description: Tests ternary logic for null +# tests: +# - feel-expression: not(A) +# expected: +# result: +# value: null diff --git a/tests/feel-time-function.yaml b/tests/feel-time-function.yaml new file mode 100644 index 0000000..0ca38c3 --- /dev/null +++ b/tests/feel-time-function.yaml @@ -0,0 +1,623 @@ +#- id: 001_bdf26fdc72 +# description: "" +# tests: +# - feel-expression: time(null) +# expected: +# result: +# value: null +#- id: 002_9d2e399b96 +# description: "" +# tests: +# - feel-expression: time(null,11,45,duration("P0D")) +# expected: +# result: +# value: null +#- id: 003_d1f0ea5bb9 +# description: "" +# tests: +# - feel-expression: time(12,null,45,duration("P0D")) +# expected: +# result: +# value: null +#- id: 004_57aea91d1c +# description: "" +# tests: +# - feel-expression: time(12,0,null,duration("P0D")) +# expected: +# result: +# value: null +#- id: 005_32ea20b34f +# description: "" +# tests: +# - feel-expression: time(null,null,45,duration("P0D")) +# expected: +# result: +# value: null +#- id: 006_e266498180 +# description: "" +# tests: +# - feel-expression: time(null,11,null,duration("P0D")) +# expected: +# result: +# value: null +#- id: 007_ee82c7bf12 +# description: "" +# tests: +# - feel-expression: time(null,11,45,null) +# expected: +# result: +# value: null +#- id: 008_08078c6c29 +# description: "" +# tests: +# - feel-expression: time(12,null,null,duration("P0D")) +# expected: +# result: +# value: null +#- id: 009_804c21ed52 +# description: "" +# tests: +# - feel-expression: time(12,11,null,null) +# expected: +# result: +# value: null +#- id: 010_cc773bb44b +# description: "" +# tests: +# - feel-expression: time(12,null,null,null) +# expected: +# result: +# value: null +#- id: 011_ad5b3a26b5 +# description: "" +# tests: +# - feel-expression: time(null,0,null,null) +# expected: +# result: +# value: null +#- id: 012_3c2f416fc9 +# description: "" +# tests: +# - feel-expression: time(null,null,15,null) +# expected: +# result: +# value: null +#- id: 013_7f22c0bda8 +# description: "" +# tests: +# - feel-expression: time(null,null,null,duration("P0D")) +# expected: +# result: +# value: null +#- id: 014_0dc13176e8 +# description: "" +# tests: +# - feel-expression: time(null,null,null,null) +# expected: +# result: +# value: null +#- id: 015_376d693a79 +# description: "" +# tests: +# - feel-expression: time(12,00,00,null) +# expected: +# result: +# value: "12:00:00" +# type: time +#- id: 016_c3cccff405 +# description: "" +# tests: +# - feel-expression: time() +# expected: +# result: +# value: null +- id: 017_f3683885f5 + description: "" + tests: + - feel-expression: time("01:02:03") + expected: + result: + value: "01:02:03" + type: time +- id: 018_35f1f2cce8 + description: "" + tests: + - feel-expression: time("00:00:00") + expected: + result: + value: "00:00:00" + type: time +- id: 019_879be89d63 + description: "" + tests: + - feel-expression: time("11:22:33.444") + expected: + result: + value: "11:22:33.444" + type: time +- id: 020_72b421086e + description: "" + tests: + - feel-expression: time("11:22:33.123456789") + expected: + result: + value: "11:22:33.123456789" + type: time +#- id: 021_5c50fa1dff +# description: "" +# tests: +# - feel-expression: time("23:59:00Z") +# expected: +# result: +# value: 23:59:00Z +# type: time +#- id: 022_55e76d3595 +# description: "" +# tests: +# - feel-expression: time("11:00:00Z") +# expected: +# result: +# value: 11:00:00Z +# type: time +#- id: 023_5cbbb85435 +# description: "" +# tests: +# - feel-expression: time("00:00:00Z") +# expected: +# result: +# value: 00:00:00Z +# type: time +- id: 024_5f7f735e8f + description: "" + tests: + - feel-expression: time("13:20:00+02:00") + expected: + result: + value: 13:20:00+02:00 + type: time +- id: 025_139b25b795 + description: "" + tests: + - feel-expression: time("13:20:00-05:00") + expected: + result: + value: 13:20:00-05:00 + type: time +#- id: 026_c5208af118 +# description: "" +# tests: +# - feel-expression: time("11:22:33-00:00") +# expected: +# result: +# value: 11:22:33Z +# type: time +#- id: 027_45082fd26c +# description: "" +# tests: +# - feel-expression: time("11:22:33+00:00") +# expected: +# result: +# value: 11:22:33Z +# type: time +#- id: 028_eaea7a943c +# description: "" +# tests: +# - feel-expression: string(time("00:01:00@Etc/UTC")) +# expected: +# result: +# value: 00:01:00@Etc/UTC +# type: string +#- id: 029_f0d5c2c16a +# description: "" +# tests: +# - feel-expression: string(time("00:01:00@Europe/Paris")) +# expected: +# result: +# value: 00:01:00@Europe/Paris +# type: string +#- id: 030_390d4f4648 +# description: "" +# tests: +# - feel-expression: time(date and time("2017-08-10T10:20:00")) +# expected: +# result: +# value: "10:20:00" +# type: time +#- id: 031_4d086a3b59 +# description: "" +# tests: +# - feel-expression: time(date and time("2017-08-10T10:20:00+00:00")) +# expected: +# result: +# value: 10:20:00Z +# type: time +#- id: 032_d9b0d7f931 +# description: "" +# tests: +# - feel-expression: time(date and time("2017-08-10T10:20:00-00:00")) +# expected: +# result: +# value: 10:20:00Z +# type: time +#- id: 033_8420160da1 +# description: "" +# tests: +# - feel-expression: time(date and time("2017-08-10T10:20:00+01:00")) +# expected: +# result: +# value: 10:20:00+01:00 +# type: time +#- id: 034_13c312c376 +# description: "" +# tests: +# - feel-expression: time(date and time("2017-08-10T10:20:00-01:00")) +# expected: +# result: +# value: 10:20:00-01:00 +# type: time +#- id: 035_fbfce88ac4 +# description: "" +# tests: +# - feel-expression: time(date and time("2017-08-10T10:20:00Z")) +# expected: +# result: +# value: 10:20:00Z +# type: time +#- id: 036_eb05fabc01 +# description: "" +# tests: +# - feel-expression: string(time(date and time("2017-08-10T10:20:00@Europe/Paris"))) +# expected: +# result: +# value: 10:20:00@Europe/Paris +# type: string +#- id: 037_eed195f693 +# description: "" +# tests: +# - feel-expression: string(time(date and time("2017-09-04T11:20:00@Asia/Dhaka"))) +# expected: +# result: +# value: 11:20:00@Asia/Dhaka +# type: string +#- id: 038_05b311131c +# description: "" +# tests: +# - feel-expression: time(11, 59, 45, null) +# expected: +# result: +# value: "11:59:45" +# type: time +#- id: 039_5b65992f0d +# description: "" +# tests: +# - feel-expression: time(11, 59, 45, duration("PT0H")) +# expected: +# result: +# value: 11:59:45Z +# type: time +#- id: 040_6c9d17b491 +# description: "" +# tests: +# - feel-expression: time(11, 59, 45, duration("PT2H")) +# expected: +# result: +# value: 11:59:45+02:00 +# type: time +#- id: 041_29a448d57e +# description: "" +# tests: +# - feel-expression: time(11, 59, 45, duration("-PT2H")) +# expected: +# result: +# value: 11:59:45-02:00 +# type: time +#- id: 042_00146f2977 +# description: "" +# tests: +# - feel-expression: time(11, 59, 00, duration("PT2H1M")) +# expected: +# result: +# value: 11:59:00+02:01 +# type: time +#- id: 043_2edfae8414 +# description: "" +# tests: +# - feel-expression: time(11, 59, 00, duration("-PT2H1M")) +# expected: +# result: +# value: 11:59:00-02:01 +# type: time +#- id: 044_3073ffd026 +# description: "" +# tests: +# - feel-expression: time(11, 59, 00, duration("PT2H1M0S")) +# expected: +# result: +# value: 11:59:00+02:01 +# type: time +#- id: 045_ad1339e858 +# description: "" +# tests: +# - feel-expression: time(11, 59, 00, duration("-PT2H1M0S")) +# expected: +# result: +# value: 11:59:00-02:01 +# type: time +#- id: 046_7b80221ec1 +# description: "" +# tests: +# - feel-expression: string(time(11, 59, 45, duration("PT2H45M55S"))) +# expected: +# result: +# value: 11:59:45+02:45:55 +# type: string +#- id: 047_33cd7b9b15 +# description: "" +# tests: +# - feel-expression: string(time(11, 59, 45, duration("-PT2H45M55S"))) +# expected: +# result: +# value: 11:59:45-02:45:55 +# type: string +#- id: 048_9bedd52886 +# description: "" +# tests: +# - feel-expression: time(11, 59, 45, duration("-PT0H")) +# expected: +# result: +# value: 11:59:45Z +# type: time +#- id: 049_617d9e09d6 +# description: "" +# tests: +# - feel-expression: time(date and time(date and time("2017-08-10T10:20:00"),time("23:59:01"))) +# expected: +# result: +# value: "23:59:01" +# type: time +#- id: 050_524d9a8146 +# description: "" +# tests: +# - feel-expression: time(date and time(date and time("2017-08-10T10:20:00"),time("23:59:01.987654321"))) +# expected: +# result: +# value: "23:59:01.987654321" +# type: time +#- id: 051_a71d2a08f7 +# description: "" +# tests: +# - feel-expression: time(date and time(date and time("2017-09-05T10:20:00"),time("09:15:30+02:00"))) +# expected: +# result: +# value: 09:15:30+02:00 +# type: time +#- id: 052_d825d58888 +# description: "" +# tests: +# - feel-expression: time(date and time(date and time("2017-09-05T10:20:00"),time("09:15:30Z"))) +# expected: +# result: +# value: 09:15:30Z +# type: time +#- id: 053_3d956966c0 +# description: "" +# tests: +# - feel-expression: time(date("2017-08-10")) +# expected: +# result: +# value: 00:00:00Z +# type: time +#- id: 054_fdc3094237 +# description: "" +# tests: +# - feel-expression: time(2017) +# expected: +# result: +# value: null +#- id: 055_9b47db6ea4 +# description: "" +# tests: +# - feel-expression: time([]) +# expected: +# result: +# value: null +#- id: 056_a8e828d64d +# description: "" +# tests: +# - feel-expression: time("") +# expected: +# result: +# value: null +#- id: 057_d039115cce +# description: "" +# tests: +# - feel-expression: time("23:59:60") +# expected: +# result: +# value: null +#- id: 058_81dd4b1639 +# description: "" +# tests: +# - feel-expression: time("24:00:01") +# expected: +# result: +# value: null +#- id: 059_c7e1705fe1 +# description: "" +# tests: +# - feel-expression: time("24:01:00") +# expected: +# result: +# value: null +#- id: 060_0cf4734fae +# description: "" +# tests: +# - feel-expression: time("25:00:00") +# expected: +# result: +# value: null +#- id: 061_da2717f085 +# description: "" +# tests: +# - feel-expression: time("00:60:00") +# expected: +# result: +# value: null +#- id: 062_6cd1313fa9 +# description: "" +# tests: +# - feel-expression: time("00:00:61") +# expected: +# result: +# value: null +#- id: 063_e85c40b474 +# description: "" +# tests: +# - feel-expression: time("7:00:00") +# expected: +# result: +# value: null +#- id: 064_df74038c67 +# description: "" +# tests: +# - feel-expression: time("07:1:00") +# expected: +# result: +# value: null +#- id: 065_79eaef6fee +# description: "" +# tests: +# - feel-expression: time("07:01:2") +# expected: +# result: +# value: null +#- id: 066_5116e12fd3 +# description: "" +# tests: +# - feel-expression: time("13:20:00@xyz/abc") +# expected: +# result: +# value: null +#- id: 067_8285edad7b +# description: "" +# tests: +# - feel-expression: time("13:20:00+19:00") +# expected: +# result: +# value: null +#- id: 068_ad528abb23 +# description: "" +# tests: +# - feel-expression: time("13:20:00-19:00") +# expected: +# result: +# value: null +#- id: 069_5096701e2e +# description: "" +# tests: +# - feel-expression: time("13:20:00+5:00") +# expected: +# result: +# value: null +#- id: 070_8b2e39f570 +# description: "" +# tests: +# - feel-expression: time("13:20:00+5") +# expected: +# result: +# value: null +#- id: 071_cf9417648b +# description: "" +# tests: +# - feel-expression: time("13:20:00+02:00@Europe/Paris") +# expected: +# result: +# value: null +#- id: 072_4c8c3835e4 +# description: "" +# tests: +# - feel-expression: time("7:20") +# expected: +# result: +# value: null +#- id: 073_a5fc245959 +# description: "" +# tests: +# - feel-expression: time("07:2") +# expected: +# result: +# value: null +#- id: 074_387d4411ea +# description: "" +# tests: +# - feel-expression: time("11:30:00T") +# expected: +# result: +# value: null +#- id: 075_1606dda03d +# description: "" +# tests: +# - feel-expression: time("2012T-12-2511:00:00Z") +# expected: +# result: +# value: null +#- id: 076_cb117ca612 +# description: "" +# tests: +# - feel-expression: time(24, 59, 45, null) +# expected: +# result: +# value: null +#- id: 077_a4daad060c +# description: "" +# tests: +# - feel-expression: time(-24, 59, 45, null) +# expected: +# result: +# value: null +#- id: 078_c2fe73418b +# description: "" +# tests: +# - feel-expression: time(23, 60, 45, null) +# expected: +# result: +# value: null +#- id: 079_d2d226c3cd +# description: "" +# tests: +# - feel-expression: time(23, 59, 60, null) +# expected: +# result: +# value: null +#- id: 080_2bbb8c86af +# description: "" +# tests: +# - feel-expression: time(from:date and time("2012-12-24T23:59:00")) +# expected: +# result: +# value: "23:59:00" +# type: time +- id: 081_69f4e0231e + description: "" + tests: + - feel-expression: 'time(from: "12:45:00")' + expected: + result: + value: "12:45:00" + type: time +#- id: 082_36a78e5396 +# description: "" +# tests: +# - feel-expression: 'time(hour:11, minute:59, second:0, offset: duration("PT2H1M0S"))' +# expected: +# result: +# value: 11:59:00+02:01 +# type: time +#- id: 083_6b608254c7 +# description: "" +# tests: +# - feel-expression: 'time(hour:11, minute:59, second:0, offset: duration("-PT2H"))' +# expected: +# result: +# value: 11:59:00-02:00 +# type: time diff --git a/tests/feel-unicode.yaml b/tests/feel-unicode.yaml new file mode 100644 index 0000000..57d1e0b --- /dev/null +++ b/tests/feel-unicode.yaml @@ -0,0 +1,118 @@ +#- id: decision_001 +# description: Assert length of string with 4 digit unicode char +# tests: +# - feel-expression: string length("\u0009") +# expected: +# result: +# value: "1" +# type: decimal +#- id: decision_001_a +# description: Assert length of string with 6 digit unicode char +# tests: +# - feel-expression: string length("\U01F40E") +# expected: +# result: +# value: "1" +# type: decimal +#- id: decision_001_b +# description: Assert string with 6 digit unicode char +# tests: +# - feel-expression: "\"\\U01F40E\" = \"\U0001F40E\"" +# expected: +# result: +# value: "true" +# type: boolean +#- id: decision_002 +# description: Escaped encoded unicode +# tests: +# - feel-expression: string length("\\u0009") +# expected: +# result: +# value: "6" +# type: decimal +#- id: decision_003 +# description: encoded unicode - supplementary char (uppercase) +# tests: +# - feel-expression: string length("\uD83D\uDCA9") +# expected: +# result: +# value: "1" +# type: decimal +#- id: decision_003_a +# description: encoded unicode - supplementary char (lowercase) +# tests: +# - feel-expression: string length("\ud83d\udca9") +# expected: +# result: +# value: "1" +# type: decimal +#- id: decision_004 +# description: encoded unicode - string literal with supplementary chars +# tests: +# - feel-expression: string length("\ud83d\udc0e\uD83D\uDE00") +# expected: +# result: +# value: "2" +# type: decimal +#- id: decision_004_a +# description: literal unicode - supplementary 2 char - in string literal +# tests: +# - feel-expression: "string length(\"\U0001F40E\U0001F600\")" +# expected: +# result: +# value: "2" +# type: decimal +- id: decision_005 + description: encoded unicode - string contains with supplementary chars + tests: + - feel-expression: contains("\ud83d\udc0e\uD83D\uDE00", "\uD83D\uDE00") + expected: + result: + value: "true" + type: boolean +#- id: decision_005_a +# description: literal unicode - string contains with supplementary chars +# tests: +# - feel-expression: "contains(\"\\ud83d\\udc0e\\uD83D\\uDE00\", \"\U0001F600\")" +# expected: +# result: +# value: "true" +# type: boolean +#- id: decision_006 +# description: literal unicode - context property name as supplementary character +# tests: +# - feel-expression: "{\U0001F40E: \"bar\"}" +# expected: +# components: +# - name: "\U0001F40E" +# expected: +# result: +# value: bar +# type: string +#- id: decision_007 +# description: literal unicode - context property and value supplementary characters +# tests: +# - feel-expression: "{\U0001F40E: \"\U0001F600\"}" +# expected: +# components: +# - name: "\U0001F40E" +# expected: +# result: +# value: "\U0001F600" +# type: string +- id: endswith_001 + description: literal unicode - string ends with with supplementary chars + tests: + - feel-expression: ends with("\ud83d\udc0e\uD83D\uDE00", "\uD83D\uDE00") + expected: + result: + value: "true" + type: boolean +#- id: substring_004 +# description: escape 6 digit unicode substring +# tests: +# - feel-expression: substring("\U01F40Efoo", 2) = "foo" +# expected: +# result: +# value: "true" +# type: boolean diff --git a/tests/feel-upper-case-function.yaml b/tests/feel-upper-case-function.yaml new file mode 100644 index 0000000..2929af1 --- /dev/null +++ b/tests/feel-upper-case-function.yaml @@ -0,0 +1,64 @@ +- id: 001_2395aaad55 + description: "" + tests: + - feel-expression: upper case("a") + expected: + result: + value: A + type: string +- id: 002_991789dded + description: "" + tests: + - feel-expression: upper case("abc") + expected: + result: + value: ABC + type: string +- id: 003_d8306d8d00 + description: "" + tests: + - feel-expression: upper case("") + expected: + result: + value: "" + type: string +- id: 004_310caf7262 + description: "" + tests: + - feel-expression: upper case("1") + expected: + result: + value: "1" + type: string +- id: 005_b316d773ac + description: "" + tests: + - feel-expression: upper case("?@{") + expected: + result: + value: ?@{ + type: string +- id: 006_d9bd3c14bc + description: "" + tests: + - feel-expression: upper case(string:"AbDcF") + expected: + result: + value: ABDCF + type: string +- id: 007_31fc6c1967 + description: "" + tests: + - feel-expression: upper case(string:"xyZ ") + expected: + result: + value: 'XYZ ' + type: string +- id: 008_26e369a9d9 + description: "" + tests: + - feel-expression: upper case(string:"123ABC") + expected: + result: + value: 123ABC + type: string diff --git a/tests/feel-week-of-year-function.yaml b/tests/feel-week-of-year-function.yaml new file mode 100644 index 0000000..a2cb561 --- /dev/null +++ b/tests/feel-week-of-year-function.yaml @@ -0,0 +1,151 @@ +- id: date_001 + description: 'date: during year 2019-09-17' + tests: + - feel-expression: week of year(@"2019-09-17") + expected: + result: + value: "38" + type: decimal +- id: date_002 + description: 'date: @"2003-12-29"' + tests: + - feel-expression: week of year(@"2003-12-29") + expected: + result: + value: "1" + type: decimal +- id: date_003 + description: 'date: @"2003-12-31"' + tests: + - feel-expression: week of year(@"2003-12-31") + expected: + result: + value: "1" + type: decimal +- id: date_004 + description: 'date: @"2004-01-01"' + tests: + - feel-expression: week of year(@"2004-01-01") + expected: + result: + value: "1" + type: decimal +- id: date_005 + description: 'date: @"2010-01-01"' + tests: + - feel-expression: week of year(@"2010-01-01") + expected: + result: + value: "53" + type: decimal +#- id: date_006 +# description: 'date: unknown type at compile time with valid date as runtime input' +# tests: +# - feel-expression: week of year(date_input_001) +# expected: +# result: +# value: "1" +# type: decimal +- id: date_007 + description: 'date: will accept date as named param' + tests: + - feel-expression: 'week of year(date: @"2019-09-17")' + expected: + result: + value: "38" + type: decimal +#- id: date_008 +# description: 'date: spec examples ' +# tests: +# - feel-expression: "" +# expected: +# results: +# - result: +# value: "53" +# type: decimal +# - result: +# value: "1" +# type: decimal +# - result: +# value: "1" +# type: decimal +- id: datetime_001 + description: 'datetime: first day of year' + tests: + - feel-expression: week of year(@"1970-01-01T10:10:10") + expected: + result: + value: "1" + type: decimal +#- id: datetime_004 +# description: 'datetime: unknown type at compile time with valid datetime as runtime input' +# tests: +# - feel-expression: week of year(date_input_001) +# expected: +# result: +# value: "1" +# type: decimal +- id: datetime_005 + description: 'datetime: will accept date time as named param' + tests: + - feel-expression: 'week of year(date: @"2019-09-17T10:10:10")' + expected: + result: + value: "38" + type: decimal +#- id: null_001 +# description: null param gives null result +# tests: +# - feel-expression: week of year(null) +# expected: +# result: +# value: null +#- id: null_002 +# description: no param gives null result +# tests: +# - feel-expression: week of year() +# expected: +# result: +# value: null +#- id: null_003 +# description: invalid param type gives null result +# tests: +# - feel-expression: week of year("foo") +# expected: +# result: +# value: null +#- id: null_004 +# description: null value named param gives null result +# tests: +# - feel-expression: 'week of year(date: null)' +# expected: +# result: +# value: null +#- id: null_005 +# description: invalid type as named param gives null result +# tests: +# - feel-expression: 'week of year(date: "foo")' +# expected: +# result: +# value: null +#- id: null_006 +# description: invalidly named param gives null result +# tests: +# - feel-expression: 'week of year(value: @"1970-01-01")' +# expected: +# result: +# value: null +#- id: null_007 +# description: unknown type at compile time with invalid type as runtime input +# tests: +# - feel-expression: week of year(date_input_001) +# expected: +# result: +# value: null +#- id: null_008 +# description: too many params gives null result +# tests: +# - feel-expression: week of year(@"1970-01-01", @"1970-01-01") +# expected: +# result: +# value: null diff --git a/tests/feel_test.go b/tests/feel_test.go new file mode 100644 index 0000000..99985f7 --- /dev/null +++ b/tests/feel_test.go @@ -0,0 +1,107 @@ +package tests + +import ( + "fmt" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/pbinitiative/feel" + "github.com/pbinitiative/feel/cmd/testcase-extractor/fs" + "github.com/pbinitiative/feel/cmd/testcase-extractor/model/testconfig" + "github.com/stretchr/testify/assert" + "gopkg.in/yaml.v3" + "log" + "os" + "testing" +) + +func Test_FeelTests(t *testing.T) { + testConfigFiles := fs.FindFiles("./", "*.yaml", false) + for _, testConfigFile := range testConfigFiles { + runFeelTests(t, testConfigFile) + } +} + +func runFeelTests(t *testing.T, testConfigFile string) { + testCases, err := loadTestConfigs(testConfigFile) + + if err != nil { + t.Fatalf("Failed to load test configuration for FEEL expressions tests: %v", err) + } + + for _, testCase := range testCases { + for _, test := range testCase.Tests { + testName := fmt.Sprintf( + "description: %s, expression: %s", + testCase.Description, + test.FeelExpression, + ) + t.Run(testName, func(t *testing.T) { + log.Default().Println(testName) + + result, err := SafeCall( + func() (any, error) { + return feel.EvalString(test.FeelExpression) + }) + + if err != nil { + t.Fatalf( + "Failed: %v"+ + "\nfile: %v"+ + "\nid: %s"+ + "\ndescription: %s"+ + "\nexpression: %s"+ + "\nexpected:"+ + "\n\t%v", + err, + testConfigFile, + testCase.Id, + testCase.Description, + test.FeelExpression, + test.ExpectedResult, + ) + } + + expected := CreateExpected(t, test.ExpectedResult) + assert.NoError(t, err) + + diff := cmp.Diff( + expected, + result, + // FEELDate, FEELTime don't not export `t` + cmpopts.IgnoreUnexported( + feel.FEELDate{}, + feel.FEELTime{}, + ), + ) + assert.Empty(t, diff, + "\nfile: %s"+ + "\nid: %s"+ + "\ndescription: %s"+ + "\nexpression: %s"+ + "\nexpected:"+ + "\n\t%v", + testConfigFile, + testCase.Id, + testCase.Description, + test.FeelExpression, + test.ExpectedResult, + ) + }) + } + } +} + +func loadTestConfigs(filepath string) ([]testconfig.TestCase, error) { + data, err := os.ReadFile(filepath) + if err != nil { + return nil, err + } + + var testConfigs []testconfig.TestCase + err = yaml.Unmarshal(data, &testConfigs) + if err != nil { + return nil, err + } + + return testConfigs, nil +} diff --git a/tests/feel_test_helper.go b/tests/feel_test_helper.go new file mode 100644 index 0000000..7f1fa36 --- /dev/null +++ b/tests/feel_test_helper.go @@ -0,0 +1,109 @@ +package tests + +import ( + "fmt" + "github.com/pbinitiative/feel" + "github.com/pbinitiative/feel/cmd/testcase-extractor/model/testconfig" + "strconv" + "strings" + "testing" +) + +// SafeCall wraps a function to recover from panics and return errors +func SafeCall[T any](fn func() (T, error)) (result T, err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("panic occurred: %v", r) + } + }() + + return fn() +} + +// CreateExpected creates an expected result ready for comparison in test +// functions. Expected results are create based on expected result type +// (boolean, dateTime, ...) +func CreateExpected(t *testing.T, result testconfig.ExpectedResult) interface{} { + switch { + case result.Components != nil: + comps := make(map[string]any) + for _, comp := range *result.Components { + comps[comp.Name] = CreateExpected(t, comp.ExpectedResult) + } + return comps + + case result.Values != nil: + vals := make([]any, 0) + for _, val := range *result.Values { + vals = append(vals, CreateExpected(t, val)) + } + return vals + + case result.Value != nil: + if result.Value.Value == nil { + return nil + } + + value := *result.Value.Value + theType := *result.Value.Type + switch theType { + case "boolean": + b, err := strconv.ParseBool(value) + if err != nil { + t.Fatalf("Cannot parse expected value as boolean: %v", err) + } + return b + case "dateTime": + datetime, err := feel.ParseDatetime(value) + if err != nil { + t.Fatalf("Cannot parse expected value as FEEL datetime: %v", err) + } + return datetime + case "date": + date, err := feel.ParseDate(value) + if err != nil { + t.Fatalf("Cannot parse expected value as FEEL date: %v", err) + } + return date + case "decimal", "double": + return feel.N(value) + case "duration": + dur, err := feel.ParseDuration(value) + if err != nil { + t.Fatalf("Cannot parse expected value as FEEL duration: %v", err) + } + return dur + case "string": + return value + case "time": + time, err := feel.ParseTime(value) + if err != nil { + t.Fatalf("Cannot parse expected value as FEEL time: %v", err) + } + return time + + default: + t.Fatalf( + "Unsupported value type: '%s'. Supported types are: %s", + theType, + strings.Join([]string{ + "boolean", + "date", + "dateTime", + "decimal", "double", + "duration", + "string", + "time", + }, ", "), + ) + } + default: + t.Fatalf( + "Unsupported 'ExpectedResult' type: %#v."+ + " Supported types are 'Components', 'Value' and 'Values'", + result, + ) + } + + return nil +} diff --git a/tests/tck/tck_test.go b/tests/tck/tck_test.go new file mode 100644 index 0000000..458371a --- /dev/null +++ b/tests/tck/tck_test.go @@ -0,0 +1,117 @@ +package tck + +import ( + "fmt" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/pbinitiative/feel" + "github.com/pbinitiative/feel/cmd/testcase-extractor/fs" + "github.com/pbinitiative/feel/cmd/testcase-extractor/model/tcktestconfig" + "github.com/pbinitiative/feel/tests" + "github.com/stretchr/testify/assert" + "gopkg.in/yaml.v3" + "log" + "os" + "testing" +) + +func Test_TckFeelTests(t *testing.T) { + testConfigFiles := fs.FindFiles("./", "*.yaml", true) + for _, testConfigFile := range testConfigFiles { + runFeelTests(t, testConfigFile) + } +} + +func runFeelTests(t *testing.T, testConfigFile string) { + testConfigs, err := loadTckTestConfigs(testConfigFile) + + if err != nil { + t.Fatalf("Failed to load test configuration for FEEL expressions tests: %v", err) + } + + for _, testConfig := range testConfigs { + for _, testCase := range testConfig.TestCases { + for _, test := range testCase.Tests { + testName := fmt.Sprintf( + "model: '%s', testCase: '%s, %s', expression: '%s'", + testConfig.Model.Name, + testCase.Id, testCase.Description, + test.FeelExpression, + ) + t.Run(testName, func(t *testing.T) { + log.Default().Println(testName) + + result, err := tests.SafeCall( + func() (any, error) { + return feel.EvalString(test.FeelExpression) + }) + + if err != nil { + t.Fatalf( + "Failed: %v"+ + "\ndir: %s"+ + "\nmodel: %s"+ + "\ntestcase:"+ + "\n\tid: %s"+ + "\n\tdescription: %s"+ + "\n\texpression: %s"+ + "\n\texpected:"+ + " \n\t\t%v", + err, + testConfig.Model.Dir, + testConfig.Model.Name, + testCase.Id, + testCase.Description, + test.FeelExpression, + test.ExpectedResult, + ) + } + + expected := tests.CreateExpected(t, test.ExpectedResult) + assert.NoError(t, err) + + diff := cmp.Diff( + expected, + result, + // FEELDate, FEELTime don't not export `t` + cmpopts.IgnoreUnexported( + feel.FEELDate{}, + feel.FEELTime{}, + ), + ) + assert.Empty(t, diff, + "\ndir: %s"+ + "\nmodel: %s"+ + "\ntestcase:"+ + "\n\tid: %s"+ + "\n\tdescription: %s"+ + "\n\texpression: %s"+ + "\n\texpected:"+ + " \n\t\t%v", + testConfig.Model.Dir, + testConfig.Model.Name, + testCase.Id, + testCase.Description, + test.FeelExpression, + test.ExpectedResult, + ) + }) + } + } + } +} + +func loadTckTestConfigs(filepath string) ([]tcktestconfig.TestConfig, error) { + data, err := os.ReadFile(filepath) + if err != nil { + return nil, err + } + + var testConfigs []tcktestconfig.TestConfig + err = yaml.Unmarshal(data, &testConfigs) + if err != nil { + return nil, err + } + + return testConfigs, nil +}