From 1af8b37a0f957a475de96a06f3b0fd9d342074f8 Mon Sep 17 00:00:00 2001 From: Tim Voronov Date: Wed, 13 Feb 2019 12:31:18 -0500 Subject: [PATCH] New type system (#232) * New type system * Fixed dot notation for HTML elements --- pkg/compiler/scope.go | 7 +- pkg/drivers/cdp/document.go | 26 ++- pkg/drivers/cdp/element.go | 22 +-- pkg/drivers/cdp/helpers.go | 7 +- pkg/drivers/driver.go | 3 +- pkg/drivers/http/document.go | 16 +- pkg/drivers/http/driver.go | 2 +- pkg/drivers/http/element.go | 16 +- pkg/runtime/collections/sort.go | 4 +- pkg/runtime/collections/sort_test.go | 20 +- pkg/runtime/core/errors_test.go | 11 +- pkg/runtime/core/scope_test.go | 44 +++-- pkg/runtime/core/type.go | 83 +++++++++ pkg/runtime/core/type_test.go | 109 +++++++++++ pkg/runtime/core/value.go | 145 ++++----------- pkg/runtime/core/value_test.go | 76 -------- .../expressions/clauses/collect_iterator.go | 8 +- pkg/runtime/expressions/clauses/limit.go | 8 +- pkg/runtime/expressions/clauses/sort.go | 2 +- pkg/runtime/expressions/data_source.go | 16 +- pkg/runtime/expressions/data_source_test.go | 6 +- pkg/runtime/expressions/literals/object.go | 6 +- pkg/runtime/expressions/member.go | 3 +- pkg/runtime/expressions/operators/array.go | 4 +- pkg/runtime/expressions/operators/equality.go | 1 + pkg/runtime/expressions/operators/in.go | 4 +- pkg/runtime/expressions/operators/logical.go | 6 +- pkg/runtime/expressions/operators/operator.go | 78 ++++---- pkg/runtime/expressions/operators/range.go | 10 +- pkg/runtime/expressions/operators/unary.go | 1 + pkg/runtime/expressions/param_test.go | 5 +- pkg/runtime/values/array.go | 26 +-- pkg/runtime/values/array_test.go | 3 +- pkg/runtime/values/binary.go | 14 +- pkg/runtime/values/boolean.go | 20 +- pkg/runtime/values/boolean_test.go | 3 +- pkg/runtime/values/date_time.go | 16 +- pkg/runtime/values/float.go | 21 ++- pkg/runtime/values/helpers.go | 92 ++++----- pkg/runtime/values/helpers_test.go | 51 ++--- pkg/runtime/values/int.go | 22 ++- pkg/runtime/values/none.go | 12 +- pkg/runtime/values/object.go | 37 ++-- pkg/runtime/values/object_test.go | 3 +- pkg/runtime/values/string.go | 24 ++- pkg/runtime/values/types/helpers.go | 44 +++++ pkg/runtime/values/types/helpers_test.go | 176 ++++++++++++++++++ pkg/runtime/values/types/types.go | 17 ++ pkg/runtime/values/types/types_test.go | 84 +++++++++ pkg/stdlib/arrays/append.go | 5 +- pkg/stdlib/arrays/first.go | 3 +- pkg/stdlib/arrays/flatten.go | 7 +- pkg/stdlib/arrays/intersection.go | 3 +- pkg/stdlib/arrays/last.go | 3 +- pkg/stdlib/arrays/minus.go | 3 +- pkg/stdlib/arrays/nth.go | 5 +- pkg/stdlib/arrays/pop.go | 3 +- pkg/stdlib/arrays/position.go | 5 +- pkg/stdlib/arrays/push.go | 5 +- pkg/stdlib/arrays/remove_nth.go | 5 +- pkg/stdlib/arrays/remove_value.go | 5 +- pkg/stdlib/arrays/remove_values.go | 5 +- pkg/stdlib/arrays/reverse.go | 3 +- pkg/stdlib/arrays/shift.go | 3 +- pkg/stdlib/arrays/slice.go | 7 +- pkg/stdlib/arrays/sorted.go | 4 +- pkg/stdlib/arrays/sorted_unique.go | 3 +- pkg/stdlib/arrays/union.go | 5 +- pkg/stdlib/arrays/union_distinct.go | 6 +- pkg/stdlib/arrays/unique.go | 3 +- pkg/stdlib/arrays/unshift.go | 5 +- pkg/stdlib/collections/length.go | 27 +-- pkg/stdlib/datetime/add_subtract.go | 7 +- pkg/stdlib/datetime/compare.go | 6 +- pkg/stdlib/datetime/date.go | 3 +- pkg/stdlib/datetime/day.go | 3 +- pkg/stdlib/datetime/dayofweek.go | 6 +- pkg/stdlib/datetime/dayofyear.go | 6 +- pkg/stdlib/datetime/daysinmonth.go | 3 +- pkg/stdlib/datetime/diff.go | 3 +- pkg/stdlib/datetime/format.go | 5 +- pkg/stdlib/datetime/helpers_test.go | 8 +- pkg/stdlib/datetime/hour.go | 3 +- pkg/stdlib/datetime/leapyear.go | 3 +- pkg/stdlib/datetime/millisecond.go | 3 +- pkg/stdlib/datetime/minute.go | 3 +- pkg/stdlib/datetime/month.go | 3 +- pkg/stdlib/datetime/quarter.go | 3 +- pkg/stdlib/datetime/second.go | 3 +- pkg/stdlib/datetime/year.go | 3 +- pkg/stdlib/html/click.go | 5 +- pkg/stdlib/html/click_all.go | 3 +- pkg/stdlib/html/document.go | 14 +- pkg/stdlib/html/download.go | 3 +- pkg/stdlib/html/element.go | 5 +- pkg/stdlib/html/hover.go | 5 +- pkg/stdlib/html/inner_html.go | 5 +- pkg/stdlib/html/inner_html_all.go | 5 +- pkg/stdlib/html/inner_text.go | 5 +- pkg/stdlib/html/inner_text_all.go | 5 +- pkg/stdlib/html/input.go | 9 +- pkg/stdlib/html/lib.go | 6 +- pkg/stdlib/html/navigate.go | 7 +- pkg/stdlib/html/navigate_back.go | 7 +- pkg/stdlib/html/navigate_forward.go | 7 +- pkg/stdlib/html/pagination.go | 12 +- pkg/stdlib/html/parse.go | 3 +- pkg/stdlib/html/pdf.go | 47 ++--- pkg/stdlib/html/screenshot.go | 25 +-- pkg/stdlib/html/scroll_bottom.go | 3 +- pkg/stdlib/html/scroll_element.go | 5 +- pkg/stdlib/html/scroll_top.go | 3 +- pkg/stdlib/html/select.go | 9 +- pkg/stdlib/html/wait_class.go | 11 +- pkg/stdlib/html/wait_class_all.go | 9 +- pkg/stdlib/html/wait_element.go | 5 +- pkg/stdlib/html/wait_navigation.go | 5 +- pkg/stdlib/math/abs.go | 3 +- pkg/stdlib/math/acos.go | 3 +- pkg/stdlib/math/asin.go | 3 +- pkg/stdlib/math/atan.go | 3 +- pkg/stdlib/math/atan2.go | 5 +- pkg/stdlib/math/average.go | 5 +- pkg/stdlib/math/ceil.go | 3 +- pkg/stdlib/math/cos.go | 3 +- pkg/stdlib/math/degrees.go | 3 +- pkg/stdlib/math/exp.go | 3 +- pkg/stdlib/math/exp2.go | 3 +- pkg/stdlib/math/floor.go | 3 +- pkg/stdlib/math/lib.go | 6 +- pkg/stdlib/math/log.go | 3 +- pkg/stdlib/math/log10.go | 3 +- pkg/stdlib/math/log2.go | 3 +- pkg/stdlib/math/max.go | 5 +- pkg/stdlib/math/mean.go | 6 +- pkg/stdlib/math/median.go | 3 +- pkg/stdlib/math/min.go | 5 +- pkg/stdlib/math/percentile.go | 5 +- pkg/stdlib/math/pow.go | 5 +- pkg/stdlib/math/radians.go | 3 +- pkg/stdlib/math/range.go | 7 +- pkg/stdlib/math/round.go | 3 +- pkg/stdlib/math/sin.go | 3 +- pkg/stdlib/math/sqrt.go | 3 +- pkg/stdlib/math/stddev_population.go | 3 +- pkg/stdlib/math/stddev_sample.go | 3 +- pkg/stdlib/math/sum.go | 5 +- pkg/stdlib/math/tan.go | 3 +- pkg/stdlib/math/variance.go | 6 +- pkg/stdlib/math/variance_population.go | 3 +- pkg/stdlib/math/variance_sample.go | 3 +- pkg/stdlib/objects/has.go | 5 +- pkg/stdlib/objects/keep_keys.go | 14 +- pkg/stdlib/objects/keys.go | 5 +- pkg/stdlib/objects/keys_test.go | 5 +- pkg/stdlib/objects/merge.go | 13 +- pkg/stdlib/objects/merge_recursive.go | 5 +- pkg/stdlib/objects/values.go | 16 +- pkg/stdlib/objects/zip.go | 16 +- pkg/stdlib/strings/concat.go | 11 +- pkg/stdlib/strings/contains.go | 7 +- pkg/stdlib/strings/find.go | 9 +- pkg/stdlib/strings/fmt.go | 3 +- pkg/stdlib/strings/json_test.go | 19 +- pkg/stdlib/strings/random.go | 3 +- pkg/stdlib/strings/regex.go | 3 +- pkg/stdlib/strings/split.go | 3 +- pkg/stdlib/strings/substitute.go | 3 +- pkg/stdlib/strings/substr.go | 9 +- pkg/stdlib/types/is_array.go | 3 +- pkg/stdlib/types/is_binary.go | 3 +- pkg/stdlib/types/is_boolean.go | 3 +- pkg/stdlib/types/is_date_time.go | 3 +- pkg/stdlib/types/is_float.go | 3 +- pkg/stdlib/types/is_html_document.go | 3 +- pkg/stdlib/types/is_html_element.go | 3 +- pkg/stdlib/types/is_int.go | 3 +- pkg/stdlib/types/is_nan.go | 3 +- pkg/stdlib/types/is_none.go | 3 +- pkg/stdlib/types/is_object.go | 3 +- pkg/stdlib/types/is_string.go | 3 +- pkg/stdlib/types/to_boolean.go | 13 +- pkg/stdlib/types/to_float.go | 15 +- pkg/stdlib/types/to_int.go | 15 +- pkg/stdlib/utils/wait.go | 3 +- 185 files changed, 1379 insertions(+), 820 deletions(-) create mode 100644 pkg/runtime/core/type.go create mode 100644 pkg/runtime/core/type_test.go delete mode 100644 pkg/runtime/core/value_test.go create mode 100644 pkg/runtime/values/types/helpers.go create mode 100644 pkg/runtime/values/types/helpers_test.go create mode 100644 pkg/runtime/values/types/types.go create mode 100644 pkg/runtime/values/types/types_test.go diff --git a/pkg/compiler/scope.go b/pkg/compiler/scope.go index 34628718..9acac22e 100644 --- a/pkg/compiler/scope.go +++ b/pkg/compiler/scope.go @@ -2,6 +2,7 @@ package compiler import ( "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type ( @@ -35,13 +36,13 @@ func (s *scope) GetVariable(name string) (core.Type, error) { parents, err := s.parent.GetVariable(name) if err != nil { - return core.NoneType, err + return types.None, err } return parents, nil } - return core.NoneType, core.Error(ErrVariableNotFound, name) + return types.None, core.Error(ErrVariableNotFound, name) } func (s *scope) SetVariable(name string) error { @@ -52,7 +53,7 @@ func (s *scope) SetVariable(name string) error { } // TODO: add type detection - s.vars[name] = core.NoneType + s.vars[name] = types.None return nil } diff --git a/pkg/drivers/cdp/document.go b/pkg/drivers/cdp/document.go index 21f3c3a5..b6fc719c 100644 --- a/pkg/drivers/cdp/document.go +++ b/pkg/drivers/cdp/document.go @@ -3,7 +3,6 @@ package cdp import ( "context" "fmt" - "github.com/mafredri/cdp/protocol/dom" "hash/fnv" "sync" "time" @@ -13,7 +12,9 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/logging" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" "github.com/mafredri/cdp" + "github.com/mafredri/cdp/protocol/dom" "github.com/mafredri/cdp/protocol/input" "github.com/mafredri/cdp/protocol/page" "github.com/mafredri/cdp/rpcc" @@ -142,7 +143,7 @@ func (doc *HTMLDocument) MarshalJSON() ([]byte, error) { } func (doc *HTMLDocument) Type() core.Type { - return core.HTMLDocumentType + return types.HTMLDocument } func (doc *HTMLDocument) String() string { @@ -176,22 +177,17 @@ func (doc *HTMLDocument) Copy() core.Value { return values.None } -func (doc *HTMLDocument) Compare(other core.Value) int { +func (doc *HTMLDocument) Compare(other core.Value) int64 { doc.Lock() defer doc.Unlock() - switch other.Type() { - case core.HTMLDocumentType: + if other.Type() == types.HTMLDocument { other := other.(*HTMLDocument) return doc.url.Compare(other.url) - default: - if other.Type() > core.HTMLDocumentType { - return -1 - } - - return 1 } + + return types.Compare(other.Type(), types.HTMLDocument) } func (doc *HTMLDocument) Close() error { @@ -399,7 +395,7 @@ func (doc *HTMLDocument) ClickBySelector(selector values.String) (values.Boolean return values.False, err } - if res.Type() == core.BooleanType { + if res.Type() == types.Boolean { return res.(values.Boolean), nil } @@ -431,7 +427,7 @@ func (doc *HTMLDocument) ClickBySelectorAll(selector values.String) (values.Bool return values.False, err } - if res.Type() == core.BooleanType { + if res.Type() == types.Boolean { return res.(values.Boolean), nil } @@ -461,7 +457,7 @@ func (doc *HTMLDocument) InputBySelector(selector values.String, value core.Valu return values.False, err } - if res.Type() == core.BooleanType && res.(values.Boolean) == values.False { + if res.Type() == types.Boolean && res.(values.Boolean) == values.False { return values.False, nil } @@ -531,7 +527,7 @@ func (doc *HTMLDocument) SelectBySelector(selector values.String, value *values. return arr, nil } - return nil, core.TypeError(core.ArrayType, res.Type()) + return nil, core.TypeError(types.Array, res.Type()) } func (doc *HTMLDocument) HoverBySelector(selector values.String) error { diff --git a/pkg/drivers/cdp/element.go b/pkg/drivers/cdp/element.go index 1fa3583c..32d61bb0 100644 --- a/pkg/drivers/cdp/element.go +++ b/pkg/drivers/cdp/element.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "github.com/gofrs/uuid" "hash/fnv" "strconv" "strings" @@ -16,6 +15,8 @@ import ( "github.com/MontFerret/ferret/pkg/drivers/common" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" + "github.com/gofrs/uuid" "github.com/mafredri/cdp" "github.com/mafredri/cdp/protocol/dom" "github.com/mafredri/cdp/protocol/input" @@ -195,7 +196,7 @@ func (el *HTMLElement) Close() error { } func (el *HTMLElement) Type() core.Type { - return core.HTMLElementType + return types.HTMLElement } func (el *HTMLElement) MarshalJSON() ([]byte, error) { @@ -212,9 +213,8 @@ func (el *HTMLElement) String() string { return el.InnerHTML().String() } -func (el *HTMLElement) Compare(other core.Value) int { - switch other.Type() { - case core.HTMLDocumentType: +func (el *HTMLElement) Compare(other core.Value) int64 { + if other.Type() == types.HTMLElement { other := other.(*HTMLElement) id := int(el.id.backendID) @@ -229,13 +229,9 @@ func (el *HTMLElement) Compare(other core.Value) int { } return -1 - default: - if other.Type() > core.HTMLElementType { - return -1 - } - - return 1 } + + return types.Compare(other.Type(), types.HTMLElement) } func (el *HTMLElement) Unwrap() interface{} { @@ -711,7 +707,7 @@ func (el *HTMLElement) WaitForClass(class values.String, timeout values.Int) err func() (core.Value, error) { current := el.GetAttribute("class") - if current.Type() != core.StringType { + if current.Type() != types.String { return values.None, nil } @@ -850,7 +846,7 @@ func (el *HTMLElement) Select(value *values.Array) (*values.Array, error) { return arr, nil } - return nil, core.TypeError(core.ArrayType, res.Type()) + return nil, core.TypeError(types.Array, res.Type()) } func (el *HTMLElement) ScrollIntoView() error { diff --git a/pkg/drivers/cdp/helpers.go b/pkg/drivers/cdp/helpers.go index 985c011f..d35a45bb 100644 --- a/pkg/drivers/cdp/helpers.go +++ b/pkg/drivers/cdp/helpers.go @@ -4,6 +4,10 @@ import ( "bytes" "context" "errors" + "golang.org/x/sync/errgroup" + "math" + "strings" + "github.com/MontFerret/ferret/pkg/drivers/cdp/eval" "github.com/MontFerret/ferret/pkg/drivers/cdp/events" "github.com/MontFerret/ferret/pkg/drivers/common" @@ -13,9 +17,6 @@ import ( "github.com/mafredri/cdp/protocol/dom" "github.com/mafredri/cdp/protocol/page" "github.com/mafredri/cdp/protocol/runtime" - "golang.org/x/sync/errgroup" - "math" - "strings" ) type ( diff --git a/pkg/drivers/driver.go b/pkg/drivers/driver.go index b7fe5cdd..52c61284 100644 --- a/pkg/drivers/driver.go +++ b/pkg/drivers/driver.go @@ -2,9 +2,10 @@ package drivers import ( "context" + "io" + "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "io" ) type ( diff --git a/pkg/drivers/http/document.go b/pkg/drivers/http/document.go index 7f6fad7b..86098019 100644 --- a/pkg/drivers/http/document.go +++ b/pkg/drivers/http/document.go @@ -3,6 +3,7 @@ package http import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" "github.com/PuerkitoBio/goquery" ) @@ -33,22 +34,17 @@ func NewHTMLDocument( } func (doc *HTMLDocument) Type() core.Type { - return core.HTMLDocumentType + return types.HTMLDocument } -func (doc *HTMLDocument) Compare(other core.Value) int { - switch other.Type() { - case core.HTMLDocumentType: +func (doc *HTMLDocument) Compare(other core.Value) int64 { + if other.Type() == types.HTMLDocument { otherDoc := other.(values.HTMLDocument) return doc.url.Compare(otherDoc.URL()) - default: - if other.Type() > core.HTMLDocumentType { - return -1 - } - - return 1 } + + return types.Compare(other.Type(), types.HTMLDocument) } func (doc *HTMLDocument) URL() core.Value { diff --git a/pkg/drivers/http/driver.go b/pkg/drivers/http/driver.go index 9974ed27..26166251 100644 --- a/pkg/drivers/http/driver.go +++ b/pkg/drivers/http/driver.go @@ -3,11 +3,11 @@ package http import ( "bytes" "context" - "github.com/MontFerret/ferret/pkg/runtime/logging" "net/http" "net/url" "github.com/MontFerret/ferret/pkg/drivers/common" + "github.com/MontFerret/ferret/pkg/runtime/logging" "github.com/MontFerret/ferret/pkg/runtime/values" "github.com/PuerkitoBio/goquery" "github.com/corpix/uarand" diff --git a/pkg/drivers/http/element.go b/pkg/drivers/http/element.go index a1ea4f21..4b8358fc 100644 --- a/pkg/drivers/http/element.go +++ b/pkg/drivers/http/element.go @@ -7,6 +7,7 @@ import ( "github.com/MontFerret/ferret/pkg/drivers/common" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" "github.com/PuerkitoBio/goquery" ) @@ -29,25 +30,20 @@ func (el *HTMLElement) MarshalJSON() ([]byte, error) { } func (el *HTMLElement) Type() core.Type { - return core.HTMLElementType + return types.HTMLElement } func (el *HTMLElement) String() string { return el.InnerHTML().String() } -func (el *HTMLElement) Compare(other core.Value) int { - switch other.Type() { - case core.HTMLElementType: +func (el *HTMLElement) Compare(other core.Value) int64 { + if other.Type() == types.HTMLElement { // TODO: complete the comparison return -1 - default: - if other.Type() > core.HTMLElementType { - return -1 - } - - return 1 } + + return types.Compare(other.Type(), types.HTMLElement) } func (el *HTMLElement) Unwrap() interface{} { diff --git a/pkg/runtime/collections/sort.go b/pkg/runtime/collections/sort.go index 74dfc452..5fb3c58a 100644 --- a/pkg/runtime/collections/sort.go +++ b/pkg/runtime/collections/sort.go @@ -10,7 +10,7 @@ import ( type ( SortDirection int - Comparator func(ctx context.Context, first, second *core.Scope) (int, error) + Comparator func(ctx context.Context, first, second *core.Scope) (int64, error) Sorter struct { fn Comparator @@ -136,7 +136,7 @@ func (iterator *SortIterator) sort(ctx context.Context, scope *core.Scope) ([]*c break } - eq = eq * int(comp.direction) + eq = eq * int64(comp.direction) if eq == -1 { out = true diff --git a/pkg/runtime/collections/sort_test.go b/pkg/runtime/collections/sort_test.go index 33a7a838..644688b0 100644 --- a/pkg/runtime/collections/sort_test.go +++ b/pkg/runtime/collections/sort_test.go @@ -35,7 +35,7 @@ func TestSort(t *testing.T) { } s, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int, error) { + func(ctx context.Context, first, second *core.Scope) (int64, error) { return first.MustGetVariable(collections.DefaultValueVar).Compare(second.MustGetVariable(collections.DefaultValueVar)), nil }, collections.SortDirectionAsc, @@ -72,7 +72,7 @@ func TestSort(t *testing.T) { } s, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int, error) { + func(ctx context.Context, first, second *core.Scope) (int64, error) { return first.MustGetVariable(collections.DefaultValueVar).Compare(second.MustGetVariable(collections.DefaultValueVar)), nil }, collections.SortDirectionDesc, @@ -120,7 +120,7 @@ func TestSort(t *testing.T) { } s1, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int, error) { + func(ctx context.Context, first, second *core.Scope) (int64, error) { o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one") o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one") @@ -130,7 +130,7 @@ func TestSort(t *testing.T) { ) s2, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int, error) { + func(ctx context.Context, first, second *core.Scope) (int64, error) { o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two") o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two") @@ -183,7 +183,7 @@ func TestSort(t *testing.T) { } s1, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int, error) { + func(ctx context.Context, first, second *core.Scope) (int64, error) { o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one") o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one") @@ -193,7 +193,7 @@ func TestSort(t *testing.T) { ) s2, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int, error) { + func(ctx context.Context, first, second *core.Scope) (int64, error) { o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two") o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two") @@ -246,7 +246,7 @@ func TestSort(t *testing.T) { } s1, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int, error) { + func(ctx context.Context, first, second *core.Scope) (int64, error) { o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one") o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one") @@ -256,7 +256,7 @@ func TestSort(t *testing.T) { ) s2, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int, error) { + func(ctx context.Context, first, second *core.Scope) (int64, error) { o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two") o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two") @@ -309,7 +309,7 @@ func TestSort(t *testing.T) { } s1, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int, error) { + func(ctx context.Context, first, second *core.Scope) (int64, error) { o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one") o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("one") @@ -319,7 +319,7 @@ func TestSort(t *testing.T) { ) s2, _ := collections.NewSorter( - func(ctx context.Context, first, second *core.Scope) (int, error) { + func(ctx context.Context, first, second *core.Scope) (int64, error) { o1, _ := first.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two") o2, _ := second.MustGetVariable(collections.DefaultValueVar).(*values.Object).Get("two") diff --git a/pkg/runtime/core/errors_test.go b/pkg/runtime/core/errors_test.go index dbf1d466..4addd911 100644 --- a/pkg/runtime/core/errors_test.go +++ b/pkg/runtime/core/errors_test.go @@ -24,17 +24,14 @@ func TestSourceError(t *testing.T) { func TestTypeError(t *testing.T) { Convey("Should match", t, func() { - e := core.TypeError(core.BooleanType) + e := core.TypeError(TypeA{}) So(e, ShouldNotBeNil) - e = core.TypeError(core.BooleanType, core.BooleanType) + e = core.TypeError(TypeA{}, TypeB{}) So(e, ShouldNotBeNil) - e = core.TypeError(core.BooleanType, core.BooleanType, core.IntType, core.FloatType) - So(e, ShouldNotBeNil) - - cause := errors.New("invalid type: expected none or boolean or int or float, but got none") - e = core.TypeError(core.NoneType, core.NoneType, core.BooleanType, core.IntType, core.FloatType) + cause := errors.New("invalid type: expected type_b or type_c, but got type_a") + e = core.TypeError(TypeA{}, TypeB{}, TypeC{}) So(e.Error(), ShouldEqual, cause.Error()) }) } diff --git a/pkg/runtime/core/scope_test.go b/pkg/runtime/core/scope_test.go index d3e45a1e..af9c8f9e 100644 --- a/pkg/runtime/core/scope_test.go +++ b/pkg/runtime/core/scope_test.go @@ -160,39 +160,55 @@ func BenchmarkScope(b *testing.B) { } } -type TestCloser struct { - closed bool +type ( + TestCloserType struct{} + + TestCloserValue struct { + closed bool + } +) + +func (tct TestCloserType) ID() int64 { + return 99 } -func (tc *TestCloser) MarshalJSON() ([]byte, error) { +func (tct TestCloserType) String() string { + return "TestCloser" +} + +func (tct TestCloserType) Equals(other core.Type) bool { + return other.ID() == tct.ID() +} + +func (tc *TestCloserValue) MarshalJSON() ([]byte, error) { return nil, core.ErrNotImplemented } -func (tc *TestCloser) Type() core.Type { - return core.NoneType +func (tc *TestCloserValue) Type() core.Type { + return TestCloserType{} } -func (tc *TestCloser) String() string { +func (tc *TestCloserValue) String() string { return "" } -func (tc *TestCloser) Compare(other core.Value) int { +func (tc *TestCloserValue) Compare(other core.Value) int64 { return 0 } -func (tc *TestCloser) Unwrap() interface{} { +func (tc *TestCloserValue) Unwrap() interface{} { return tc } -func (tc *TestCloser) Hash() uint64 { +func (tc *TestCloserValue) Hash() uint64 { return 0 } -func (tc *TestCloser) Copy() core.Value { - return &TestCloser{} +func (tc *TestCloserValue) Copy() core.Value { + return &TestCloserValue{} } -func (tc *TestCloser) Close() error { +func (tc *TestCloserValue) Close() error { if tc.closed { return core.Error(core.ErrInvalidOperation, "already closed") } @@ -206,7 +222,7 @@ func TestCloseFunc(t *testing.T) { Convey("Should close root scope and close all io.Closer values", t, func() { rs, cf := core.NewRootScope() - tc := &TestCloser{} + tc := &TestCloserValue{} rs.SetVariable("disposable", tc) So(tc.closed, ShouldBeFalse) @@ -220,7 +236,7 @@ func TestCloseFunc(t *testing.T) { Convey("Should return error if it's already closed", t, func() { rs, cf := core.NewRootScope() - tc := &TestCloser{} + tc := &TestCloserValue{} rs.SetVariable("disposable", tc) So(tc.closed, ShouldBeFalse) diff --git a/pkg/runtime/core/type.go b/pkg/runtime/core/type.go new file mode 100644 index 00000000..8a3ca95b --- /dev/null +++ b/pkg/runtime/core/type.go @@ -0,0 +1,83 @@ +package core + +import ( + "github.com/pkg/errors" + "math/rand" +) + +// Type represents runtime type with id for quick type check +// and Name for error messages + +//revive:disable-next-line:redefines-builtin-id +type ( + Type interface { + ID() int64 + String() string + Equals(other Type) bool + } + + BaseType struct { + id int64 + name string + } +) + +func NewType(name string) Type { + return BaseType{rand.Int63(), name} +} + +func (t BaseType) ID() int64 { + return t.id +} + +func (t BaseType) String() string { + return t.name +} + +func (t BaseType) Equals(other Type) bool { + return t.id == other.ID() +} + +// IsTypeOf return true when value's type +// is equal to check type. +// Returns false, otherwise. +func IsTypeOf(value Value, check Type) bool { + return value.Type().ID() == check.ID() +} + +// ValidateType checks the match of +// value's type and required types. +func ValidateType(value Value, required ...Type) error { + var valid bool + tid := value.Type().ID() + + for _, t := range required { + if tid == t.ID() { + valid = true + break + } + } + + if !valid { + return TypeError(value.Type(), required...) + } + + return nil +} + +// ValidateValueTypePairs validate pairs of +// Values and Types. +// Returns error when type didn't match +func ValidateValueTypePairs(pairs ...PairValueType) error { + var err error + + for idx, pair := range pairs { + err = ValidateType(pair.Value, pair.Types...) + + if err != nil { + return errors.Errorf("pair %d: %v", idx, err) + } + } + + return nil +} diff --git a/pkg/runtime/core/type_test.go b/pkg/runtime/core/type_test.go new file mode 100644 index 00000000..6f6619a4 --- /dev/null +++ b/pkg/runtime/core/type_test.go @@ -0,0 +1,109 @@ +package core_test + +import ( + "github.com/MontFerret/ferret/pkg/runtime/core" + . "github.com/smartystreets/goconvey/convey" + "testing" +) + +type ( + Value struct { + type_ core.Type + } + + TypeA struct{} + + TypeB struct{} + + TypeC struct{} +) + +func (t Value) MarshalJSON() ([]byte, error) { + return nil, nil +} + +func (t Value) Type() core.Type { + return t.type_ +} + +func (t Value) String() string { + return "" +} + +func (t Value) Compare(other core.Value) int64 { + return 0 +} + +func (t Value) Unwrap() interface{} { + return nil +} + +func (t Value) Hash() uint64 { + return 0 +} + +func (t Value) Copy() core.Value { + return t +} + +func (t TypeA) ID() int64 { + return 1 +} + +func (t TypeA) String() string { + return "type_a" +} + +func (t TypeA) Equals(other core.Type) bool { + return t.ID() == other.ID() +} + +func (t TypeB) ID() int64 { + return 2 +} + +func (t TypeB) String() string { + return "type_b" +} + +func (t TypeB) Equals(other core.Type) bool { + return t.ID() == other.ID() +} + +func (t TypeC) ID() int64 { + return 3 +} + +func (t TypeC) String() string { + return "type_c" +} + +func (t TypeC) Equals(other core.Type) bool { + return t.ID() == other.ID() +} + +func TestType(t *testing.T) { + typeA := TypeA{} + typeB := TypeB{} + + Convey("IsTypeOf", t, func() { + Convey("Should return 'false' when types are different", func() { + vA := Value{typeA} + + So(core.IsTypeOf(vA, typeB), ShouldBeFalse) + }) + }) +} + +func TestValidateType(t *testing.T) { + typeA := TypeA{} + typeB := TypeB{} + + Convey("Should validate types", t, func() { + vA := Value{typeA} + vB := Value{typeB} + + So(core.ValidateType(vA, typeA), ShouldBeNil) + So(core.ValidateType(vB, typeA), ShouldNotBeNil) + }) +} diff --git a/pkg/runtime/core/value.go b/pkg/runtime/core/value.go index 9af3ec64..fa581889 100644 --- a/pkg/runtime/core/value.go +++ b/pkg/runtime/core/value.go @@ -1,120 +1,41 @@ package core import ( + "context" "encoding/json" - - "github.com/pkg/errors" ) -//revive:disable-next-line:redefines-builtin-id -type Type int64 +type ( + // Value represents an interface of + // any type that needs to be used during runtime + Value interface { + json.Marshaler + Type() Type + String() string + Compare(other Value) int64 + Unwrap() interface{} + Hash() uint64 + Copy() Value + } -const ( - NoneType Type = 0 - BooleanType Type = 1 - IntType Type = 2 - FloatType Type = 3 - StringType Type = 4 - DateTimeType Type = 5 - ArrayType Type = 6 - ObjectType Type = 7 - HTMLElementType Type = 8 - HTMLDocumentType Type = 9 - BinaryType Type = 10 - CustomType Type = 99 + // Getter represents an interface of + // complex types that needs to be used to read values by path. + // The interface is created to let user-defined types be used in dot notation data access. + Getter interface { + GetIn(ctx context.Context, path []Value) (Value, error) + } + + // Setter represents an interface of + // complex types that needs to be used to write values by path. + // The interface is created to let user-defined types be used in dot notation assignment. + Setter interface { + SetIn(ctx context.Context, path []Value, value Value) error + } + + // PairValueType is a supporting + // structure that used in validateValueTypePairs. + PairValueType struct { + Value Value + Types []Type + } ) - -var typestr = map[Type]string{ - NoneType: "none", - BooleanType: "boolean", - IntType: "int", - FloatType: "float", - StringType: "string", - DateTimeType: "datetime", - ArrayType: "array", - ObjectType: "object", - HTMLElementType: "HTMLElement", - HTMLDocumentType: "HTMLDocument", - BinaryType: "BinaryType", - CustomType: "CustomType", -} - -func (t Type) String() string { - return typestr[t] -} - -// Value represents an interface of -// any type that needs to be used during runtime -type Value interface { - json.Marshaler - Type() Type - String() string - Compare(other Value) int - Unwrap() interface{} - Hash() uint64 - Copy() Value -} - -// Getter represents an interface of -// complex types that needs to be used to read values by path. -// The interface is created to let user-defined types be used in dot notation data access. -type Getter interface { - GetIn(path []Value) (Value, error) -} - -// Setter represents an interface of -// complex types that needs to be used to write values by path. -// The interface is created to let user-defined types be used in dot notation assignment. -type Setter interface { - SetIn(path []Value, value Value) error -} - -// IsTypeOf return true when value's type -// is equal to check type. -// Returns false, otherwise. -func IsTypeOf(value Value, check Type) bool { - return value.Type() == check -} - -// ValidateType checks the match of -// value's type and required types. -func ValidateType(value Value, required ...Type) error { - var valid bool - ct := value.Type() - - for _, t := range required { - if ct == t { - valid = true - break - } - } - - if !valid { - return TypeError(value.Type(), required...) - } - - return nil -} - -// PairValueType is a supporting -// structure that used in validateValueTypePairs. -type PairValueType struct { - Value Value - Types []Type -} - -// ValidateValueTypePairs validate pairs of -// Values and Types. -// Returns error when type didn't match -func ValidateValueTypePairs(pairs ...PairValueType) error { - var err error - - for idx, pair := range pairs { - err = ValidateType(pair.Value, pair.Types...) - if err != nil { - return errors.Errorf("pair %d: %v", idx, err) - } - } - - return nil -} diff --git a/pkg/runtime/core/value_test.go b/pkg/runtime/core/value_test.go deleted file mode 100644 index 9d727117..00000000 --- a/pkg/runtime/core/value_test.go +++ /dev/null @@ -1,76 +0,0 @@ -package core_test - -import ( - "testing" - "time" - - "github.com/MontFerret/ferret/pkg/drivers/http" - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" - . "github.com/smartystreets/goconvey/convey" -) - -func TestTypeString(t *testing.T) { - Convey("The string representation of the type should match this type", t, func() { - So(core.Type(0).String(), ShouldEqual, "none") - So(core.Type(1).String(), ShouldEqual, "boolean") - So(core.Type(2).String(), ShouldEqual, "int") - So(core.Type(3).String(), ShouldEqual, "float") - So(core.Type(4).String(), ShouldEqual, "string") - So(core.Type(5).String(), ShouldEqual, "datetime") - So(core.Type(6).String(), ShouldEqual, "array") - So(core.Type(7).String(), ShouldEqual, "object") - So(core.Type(8).String(), ShouldEqual, "HTMLElement") - So(core.Type(9).String(), ShouldEqual, "HTMLDocument") - So(core.Type(10).String(), ShouldEqual, "BinaryType") - }) -} - -func TestIsTypeOf(t *testing.T) { - Convey("Check type by value", t, func() { - - So(core.IsTypeOf(values.None, core.NoneType), ShouldBeTrue) - So(core.IsTypeOf(values.NewBoolean(true), core.BooleanType), ShouldBeTrue) - So(core.IsTypeOf(values.NewInt(1), core.IntType), ShouldBeTrue) - So(core.IsTypeOf(values.NewFloat(1.1), core.FloatType), ShouldBeTrue) - So(core.IsTypeOf(values.NewString("test"), core.StringType), ShouldBeTrue) - So(core.IsTypeOf(values.NewDateTime(time.Now()), core.DateTimeType), ShouldBeTrue) - So(core.IsTypeOf(values.NewArray(1), core.ArrayType), ShouldBeTrue) - So(core.IsTypeOf(values.NewObject(), core.ObjectType), ShouldBeTrue) - So(core.IsTypeOf(&http.HTMLElement{}, core.HTMLElementType), ShouldBeTrue) - So(core.IsTypeOf(&http.HTMLDocument{}, core.HTMLDocumentType), ShouldBeTrue) - So(core.IsTypeOf(values.NewBinary([]byte{}), core.BinaryType), ShouldBeTrue) - }) -} - -func TestValidateType(t *testing.T) { - Convey("Value should match type", t, func() { - - So(core.ValidateType(values.None, core.NoneType), ShouldBeNil) - So(core.ValidateType(values.NewBoolean(true), core.BooleanType), ShouldBeNil) - So(core.ValidateType(values.NewInt(1), core.IntType), ShouldBeNil) - So(core.ValidateType(values.NewFloat(1.1), core.FloatType), ShouldBeNil) - So(core.ValidateType(values.NewString("test"), core.StringType), ShouldBeNil) - So(core.ValidateType(values.NewDateTime(time.Now()), core.DateTimeType), ShouldBeNil) - So(core.ValidateType(values.NewArray(1), core.ArrayType), ShouldBeNil) - So(core.ValidateType(values.NewObject(), core.ObjectType), ShouldBeNil) - So(core.ValidateType(&http.HTMLElement{}, core.HTMLElementType), ShouldBeNil) - So(core.ValidateType(&http.HTMLDocument{}, core.HTMLDocumentType), ShouldBeNil) - So(core.ValidateType(values.NewBinary([]byte{}), core.BinaryType), ShouldBeNil) - }) - - Convey("Value should not match type", t, func() { - - So(core.ValidateType(values.None, core.BooleanType), ShouldBeError) - So(core.ValidateType(values.NewBoolean(true), core.IntType, core.NoneType), ShouldBeError) - So(core.ValidateType(values.NewInt(1), core.NoneType), ShouldBeError) - So(core.ValidateType(values.NewFloat(1.1), core.StringType), ShouldBeError) - So(core.ValidateType(values.NewString("test"), core.IntType, core.FloatType), ShouldBeError) - So(core.ValidateType(values.NewDateTime(time.Now()), core.BooleanType), ShouldBeError) - So(core.ValidateType(values.NewArray(1), core.StringType), ShouldBeError) - So(core.ValidateType(values.NewObject(), core.BooleanType), ShouldBeError) - So(core.ValidateType(&http.HTMLElement{}, core.ArrayType), ShouldBeError) - So(core.ValidateType(&http.HTMLDocument{}, core.HTMLElementType), ShouldBeError) - So(core.ValidateType(values.NewBinary([]byte{}), core.NoneType), ShouldBeError) - }) -} diff --git a/pkg/runtime/expressions/clauses/collect_iterator.go b/pkg/runtime/expressions/clauses/collect_iterator.go index 7a0dcee4..524ab7d6 100644 --- a/pkg/runtime/expressions/clauses/collect_iterator.go +++ b/pkg/runtime/expressions/clauses/collect_iterator.go @@ -2,9 +2,11 @@ package clauses import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/collections" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type CollectIterator struct { @@ -59,7 +61,7 @@ func NewCollectIterator( } func newGroupSorter(selector *CollectSelector) (*collections.Sorter, error) { - return collections.NewSorter(func(ctx context.Context, first, second *core.Scope) (int, error) { + return collections.NewSorter(func(ctx context.Context, first, second *core.Scope) (int64, error) { f, err := selector.expression.Exec(ctx, first) if err != nil { @@ -213,7 +215,7 @@ func (iterator *CollectIterator) group(ctx context.Context, scope *core.Scope) ( arr, ok := groupValue.(*values.Array) if !ok { - return nil, core.TypeError(groupValue.Type(), core.IntType) + return nil, core.TypeError(groupValue.Type(), types.Int) } value, err := proj.selector.expression.Exec(ctx, dataSourceScope) @@ -235,7 +237,7 @@ func (iterator *CollectIterator) group(ctx context.Context, scope *core.Scope) ( counter, ok := groupValue.(values.Int) if !ok { - return nil, core.TypeError(groupValue.Type(), core.IntType) + return nil, core.TypeError(groupValue.Type(), types.Int) } groupValue = counter + 1 diff --git a/pkg/runtime/expressions/clauses/limit.go b/pkg/runtime/expressions/clauses/limit.go index 7395a4f6..90392517 100644 --- a/pkg/runtime/expressions/clauses/limit.go +++ b/pkg/runtime/expressions/clauses/limit.go @@ -2,8 +2,10 @@ package clauses import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/collections" "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type LimitClause struct { @@ -71,13 +73,13 @@ func (clause *LimitClause) Iterate(ctx context.Context, scope *core.Scope) (coll } func (clause *LimitClause) parseValue(val core.Value) (int, error) { - if val.Type() == core.IntType { + if val.Type() == types.Int { return val.Unwrap().(int), nil } - if val.Type() == core.FloatType { + if val.Type() == types.Float { return int(val.Unwrap().(float64)), nil } - return -1, core.TypeError(val.Type(), core.IntType, core.FloatType) + return -1, core.TypeError(val.Type(), types.Int, types.Float) } diff --git a/pkg/runtime/expressions/clauses/sort.go b/pkg/runtime/expressions/clauses/sort.go index 6256ff82..dd9c2233 100644 --- a/pkg/runtime/expressions/clauses/sort.go +++ b/pkg/runtime/expressions/clauses/sort.go @@ -71,7 +71,7 @@ func (clause *SortClause) Iterate(ctx context.Context, scope *core.Scope) (colle } func newSorter(srt *SorterExpression) (*collections.Sorter, error) { - return collections.NewSorter(func(ctx context.Context, first, second *core.Scope) (int, error) { + return collections.NewSorter(func(ctx context.Context, first, second *core.Scope) (int64, error) { f, err := srt.expression.Exec(ctx, first) if err != nil { diff --git a/pkg/runtime/expressions/data_source.go b/pkg/runtime/expressions/data_source.go index f9301390..eb8f6795 100644 --- a/pkg/runtime/expressions/data_source.go +++ b/pkg/runtime/expressions/data_source.go @@ -2,9 +2,11 @@ package expressions import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/collections" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type DataSource struct { @@ -44,11 +46,11 @@ func (ds *DataSource) Iterate(ctx context.Context, scope *core.Scope) (collectio } switch data.Type() { - case core.ArrayType: + case types.Array: return collections.NewIndexedIterator(ds.valVariable, ds.keyVariable, data.(collections.IndexedCollection)) - case core.ObjectType: + case types.Object: return collections.NewKeyedIterator(ds.valVariable, ds.keyVariable, data.(collections.KeyedCollection)) - case core.HTMLElementType, core.HTMLDocumentType: + case types.HTMLElement, types.HTMLDocument: return collections.NewHTMLNodeIterator(ds.valVariable, ds.keyVariable, data.(values.HTMLNode)) default: // fallback to user defined types @@ -69,10 +71,10 @@ func (ds *DataSource) Iterate(ctx context.Context, scope *core.Scope) (collectio default: return nil, core.TypeError( data.Type(), - core.ArrayType, - core.ObjectType, - core.HTMLDocumentType, - core.HTMLElementType, + types.Array, + types.Object, + types.HTMLDocument, + types.HTMLElement, ) } } diff --git a/pkg/runtime/expressions/data_source_test.go b/pkg/runtime/expressions/data_source_test.go index 605430a4..caebfb22 100644 --- a/pkg/runtime/expressions/data_source_test.go +++ b/pkg/runtime/expressions/data_source_test.go @@ -11,6 +11,8 @@ import ( . "github.com/smartystreets/goconvey/convey" ) +var testIterableCollectionType = core.NewType("TestIterableCollection") + type ( testIterableCollection struct { values collections.IndexedCollection @@ -32,12 +34,12 @@ func (c *testIterableCollection) MarshalJSON() ([]byte, error) { return nil, core.ErrInvalidOperation } func (c *testIterableCollection) Type() core.Type { - return core.Type(11) + return testIterableCollectionType } func (c *testIterableCollection) String() string { return "" } -func (c *testIterableCollection) Compare(other core.Value) int { +func (c *testIterableCollection) Compare(other core.Value) int64 { return 1 } func (c *testIterableCollection) Unwrap() interface{} { diff --git a/pkg/runtime/expressions/literals/object.go b/pkg/runtime/expressions/literals/object.go index 8aa1b54f..b9a35c24 100644 --- a/pkg/runtime/expressions/literals/object.go +++ b/pkg/runtime/expressions/literals/object.go @@ -2,8 +2,10 @@ package literals import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type ( @@ -49,8 +51,8 @@ func (l *ObjectLiteral) Exec(ctx context.Context, scope *core.Scope) (core.Value return values.None, err } - if name.Type() != core.StringType { - return values.None, core.TypeError(name.Type(), core.StringType) + if name.Type() != types.String { + return values.None, core.TypeError(name.Type(), types.String) } obj.Set(name.(values.String), val) diff --git a/pkg/runtime/expressions/member.go b/pkg/runtime/expressions/member.go index 00cdebbf..9e4dc5a0 100644 --- a/pkg/runtime/expressions/member.go +++ b/pkg/runtime/expressions/member.go @@ -2,6 +2,7 @@ package expressions import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" ) @@ -46,7 +47,7 @@ func (e *MemberExpression) Exec(ctx context.Context, scope *core.Scope) (core.Va strPath[idx] = segment } - out, err := values.GetIn(val, strPath) + out, err := values.GetIn(ctx, val, strPath) if err != nil { return values.None, core.SourceError(e.src, err) diff --git a/pkg/runtime/expressions/operators/array.go b/pkg/runtime/expressions/operators/array.go index 2820b407..d06bc483 100644 --- a/pkg/runtime/expressions/operators/array.go +++ b/pkg/runtime/expressions/operators/array.go @@ -2,8 +2,10 @@ package operators import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type ( @@ -88,7 +90,7 @@ func (operator *ArrayOperator) Exec(ctx context.Context, scope *core.Scope) (cor } func (operator *ArrayOperator) Eval(ctx context.Context, left, right core.Value) (core.Value, error) { - err := core.ValidateType(left, core.ArrayType) + err := core.ValidateType(left, types.Array) if err != nil { // TODO: Return the error? AQL just returns false diff --git a/pkg/runtime/expressions/operators/equality.go b/pkg/runtime/expressions/operators/equality.go index 762d0fb2..c14d7bc8 100644 --- a/pkg/runtime/expressions/operators/equality.go +++ b/pkg/runtime/expressions/operators/equality.go @@ -2,6 +2,7 @@ package operators import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/core" ) diff --git a/pkg/runtime/expressions/operators/in.go b/pkg/runtime/expressions/operators/in.go index 8d82d235..0fd96693 100644 --- a/pkg/runtime/expressions/operators/in.go +++ b/pkg/runtime/expressions/operators/in.go @@ -2,8 +2,10 @@ package operators import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type InOperator struct { @@ -45,7 +47,7 @@ func (operator *InOperator) Exec(ctx context.Context, scope *core.Scope) (core.V } func (operator *InOperator) Eval(_ context.Context, left, right core.Value) (core.Value, error) { - err := core.ValidateType(right, core.ArrayType) + err := core.ValidateType(right, types.Array) if err != nil { // TODO: Return the error? AQL just returns false diff --git a/pkg/runtime/expressions/operators/logical.go b/pkg/runtime/expressions/operators/logical.go index 5e6e836c..a2645b41 100644 --- a/pkg/runtime/expressions/operators/logical.go +++ b/pkg/runtime/expressions/operators/logical.go @@ -2,8 +2,10 @@ package operators import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type ( @@ -70,7 +72,7 @@ func (operator *LogicalOperator) Exec(ctx context.Context, scope *core.Scope) (c leftBool := values.ToBoolean(left) if operator.value == LogicalOperatorTypeAnd && leftBool == values.False { - if left.Type() == core.BooleanType { + if left.Type() == types.Boolean { return values.False, nil } @@ -98,7 +100,7 @@ func (operator *LogicalOperator) Eval(_ context.Context, left, right core.Value) leftBool := values.ToBoolean(left) if operator.value == LogicalOperatorTypeAnd && leftBool == values.False { - if left.Type() == core.BooleanType { + if left.Type() == types.Boolean { return values.False, nil } diff --git a/pkg/runtime/expressions/operators/operator.go b/pkg/runtime/expressions/operators/operator.go index 268308f2..564737e6 100644 --- a/pkg/runtime/expressions/operators/operator.go +++ b/pkg/runtime/expressions/operators/operator.go @@ -2,8 +2,10 @@ package operators import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type ( @@ -89,15 +91,15 @@ func Not(left, _ core.Value) core.Value { // Adds numbers // Concats strings func Add(left, right core.Value) core.Value { - if left.Type() == core.IntType { - if right.Type() == core.IntType { + if left.Type() == types.Int { + if right.Type() == types.Int { l := left.(values.Int) r := right.(values.Int) return l + r } - if right.Type() == core.FloatType { + if right.Type() == types.Float { l := left.(values.Int) r := right.(values.Float) @@ -105,15 +107,15 @@ func Add(left, right core.Value) core.Value { } } - if left.Type() == core.FloatType { - if right.Type() == core.FloatType { + if left.Type() == types.Float { + if right.Type() == types.Float { l := left.(values.Float) r := right.(values.Float) return l + r } - if right.Type() == core.IntType { + if right.Type() == types.Int { l := left.(values.Float) r := right.(values.Int) @@ -125,15 +127,15 @@ func Add(left, right core.Value) core.Value { } func Subtract(left, right core.Value) core.Value { - if left.Type() == core.IntType { - if right.Type() == core.IntType { + if left.Type() == types.Int { + if right.Type() == types.Int { l := left.(values.Int) r := right.(values.Int) return l - r } - if right.Type() == core.FloatType { + if right.Type() == types.Float { l := left.(values.Int) r := right.(values.Float) @@ -141,15 +143,15 @@ func Subtract(left, right core.Value) core.Value { } } - if left.Type() == core.FloatType { - if right.Type() == core.FloatType { + if left.Type() == types.Float { + if right.Type() == types.Float { l := left.(values.Float) r := right.(values.Float) return l - r } - if right.Type() == core.IntType { + if right.Type() == types.Int { l := left.(values.Float) r := right.(values.Int) @@ -161,15 +163,15 @@ func Subtract(left, right core.Value) core.Value { } func Multiply(left, right core.Value) core.Value { - if left.Type() == core.IntType { - if right.Type() == core.IntType { + if left.Type() == types.Int { + if right.Type() == types.Int { l := left.(values.Int) r := right.(values.Int) return l * r } - if right.Type() == core.FloatType { + if right.Type() == types.Float { l := left.(values.Int) r := right.(values.Float) @@ -177,15 +179,15 @@ func Multiply(left, right core.Value) core.Value { } } - if left.Type() == core.FloatType { - if right.Type() == core.FloatType { + if left.Type() == types.Float { + if right.Type() == types.Float { l := left.(values.Float) r := right.(values.Float) return l * r } - if right.Type() == core.IntType { + if right.Type() == types.Int { l := left.(values.Float) r := right.(values.Int) @@ -197,15 +199,15 @@ func Multiply(left, right core.Value) core.Value { } func Divide(left, right core.Value) core.Value { - if left.Type() == core.IntType { - if right.Type() == core.IntType { + if left.Type() == types.Int { + if right.Type() == types.Int { l := left.(values.Int) r := right.(values.Int) return l / r } - if right.Type() == core.FloatType { + if right.Type() == types.Float { l := left.(values.Int) r := right.(values.Float) @@ -213,15 +215,15 @@ func Divide(left, right core.Value) core.Value { } } - if left.Type() == core.FloatType { - if right.Type() == core.FloatType { + if left.Type() == types.Float { + if right.Type() == types.Float { l := left.(values.Float) r := right.(values.Float) return l / r } - if right.Type() == core.IntType { + if right.Type() == types.Int { l := left.(values.Float) r := right.(values.Int) @@ -233,15 +235,15 @@ func Divide(left, right core.Value) core.Value { } func Modulus(left, right core.Value) core.Value { - if left.Type() == core.IntType { - if right.Type() == core.IntType { + if left.Type() == types.Int { + if right.Type() == types.Int { l := left.(values.Int) r := right.(values.Int) return l % r } - if right.Type() == core.FloatType { + if right.Type() == types.Float { l := left.(values.Int) r := right.(values.Float) @@ -249,15 +251,15 @@ func Modulus(left, right core.Value) core.Value { } } - if left.Type() == core.FloatType { - if right.Type() == core.FloatType { + if left.Type() == types.Float { + if right.Type() == types.Float { l := left.(values.Float) r := right.(values.Float) return values.Int(l) % values.Int(r) } - if right.Type() == core.IntType { + if right.Type() == types.Int { l := left.(values.Float) r := right.(values.Int) @@ -269,13 +271,13 @@ func Modulus(left, right core.Value) core.Value { } func Increment(left, _ core.Value) core.Value { - if left.Type() == core.IntType { + if left.Type() == types.Int { l := left.(values.Int) return l + 1 } - if left.Type() == core.FloatType { + if left.Type() == types.Float { l := left.(values.Float) return l + 1 @@ -285,13 +287,13 @@ func Increment(left, _ core.Value) core.Value { } func Decrement(left, _ core.Value) core.Value { - if left.Type() == core.IntType { + if left.Type() == types.Int { l := left.(values.Int) return l - 1 } - if left.Type() == core.FloatType { + if left.Type() == types.Float { l := left.(values.Float) return l - 1 @@ -301,13 +303,13 @@ func Decrement(left, _ core.Value) core.Value { } func Negative(value, _ core.Value) core.Value { - err := core.ValidateType(value, core.IntType, core.FloatType) + err := core.ValidateType(value, types.Int, types.Float) if err != nil { return values.ZeroInt } - if value.Type() == core.IntType { + if value.Type() == types.Int { return -value.(values.Int) } @@ -315,13 +317,13 @@ func Negative(value, _ core.Value) core.Value { } func Positive(value, _ core.Value) core.Value { - err := core.ValidateType(value, core.IntType, core.FloatType) + err := core.ValidateType(value, types.Int, types.Float) if err != nil { return values.ZeroInt } - if value.Type() == core.IntType { + if value.Type() == types.Int { return +value.(values.Int) } diff --git a/pkg/runtime/expressions/operators/range.go b/pkg/runtime/expressions/operators/range.go index 77675a90..e19c0cdb 100644 --- a/pkg/runtime/expressions/operators/range.go +++ b/pkg/runtime/expressions/operators/range.go @@ -2,8 +2,10 @@ package operators import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type RangeOperator struct { @@ -43,13 +45,13 @@ func (operator *RangeOperator) Exec(ctx context.Context, scope *core.Scope) (cor } func (operator *RangeOperator) Eval(_ context.Context, left, right core.Value) (core.Value, error) { - err := core.ValidateType(left, core.IntType, core.FloatType) + err := core.ValidateType(left, types.Int, types.Float) if err != nil { return values.None, core.SourceError(operator.src, err) } - err = core.ValidateType(right, core.IntType, core.FloatType) + err = core.ValidateType(right, types.Int, types.Float) if err != nil { return values.None, core.SourceError(operator.src, err) @@ -58,13 +60,13 @@ func (operator *RangeOperator) Eval(_ context.Context, left, right core.Value) ( var start int var end int - if left.Type() == core.FloatType { + if left.Type() == types.Float { start = int(left.(values.Float)) } else { start = int(left.(values.Int)) } - if right.Type() == core.FloatType { + if right.Type() == types.Float { end = int(right.(values.Float)) } else { end = int(right.(values.Int)) diff --git a/pkg/runtime/expressions/operators/unary.go b/pkg/runtime/expressions/operators/unary.go index c7982773..78f85083 100644 --- a/pkg/runtime/expressions/operators/unary.go +++ b/pkg/runtime/expressions/operators/unary.go @@ -2,6 +2,7 @@ package operators import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" ) diff --git a/pkg/runtime/expressions/param_test.go b/pkg/runtime/expressions/param_test.go index a9257f07..743ee290 100644 --- a/pkg/runtime/expressions/param_test.go +++ b/pkg/runtime/expressions/param_test.go @@ -2,6 +2,7 @@ package expressions_test import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/values/types" "testing" "github.com/MontFerret/ferret/pkg/runtime/core" @@ -41,7 +42,7 @@ func TestParameterExpressionExec(t *testing.T) { value, err := existExp.Exec(ctx, &core.Scope{}) So(err, ShouldBeNil) - So(value.Type(), ShouldEqual, core.IntType) + So(value.Type().Equals(types.Int), ShouldBeTrue) So(value.String(), ShouldEqual, "1") }) @@ -57,6 +58,6 @@ func TestParameterExpressionExec(t *testing.T) { So(err, ShouldNotBeNil) So(err, ShouldHaveSameTypeAs, core.ErrNotFound) - So(value.Type(), ShouldEqual, core.NoneType) + So(value.Type().Equals(types.None), ShouldBeTrue) }) } diff --git a/pkg/runtime/values/array.go b/pkg/runtime/values/array.go index 276fe7b2..1a1cf2cd 100644 --- a/pkg/runtime/values/array.go +++ b/pkg/runtime/values/array.go @@ -7,6 +7,7 @@ import ( "sort" "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type ( @@ -32,7 +33,7 @@ func (t *Array) MarshalJSON() ([]byte, error) { } func (t *Array) Type() core.Type { - return core.ArrayType + return types.Array } func (t *Array) String() string { @@ -45,22 +46,23 @@ func (t *Array) String() string { return string(marshaled) } -func (t *Array) Compare(other core.Value) int { - switch other.Type() { - case core.ArrayType: +func (t *Array) Compare(other core.Value) int64 { + if other.Type() == types.Array { other := other.(*Array) if t.Length() == 0 && other.Length() == 0 { return 0 } + if t.Length() < other.Length() { return -1 } + if t.Length() > other.Length() { return 1 } - var res = 0 + var res int64 var val core.Value other.ForEach(func(otherVal core.Value, idx int) bool { @@ -71,11 +73,9 @@ func (t *Array) Compare(other core.Value) int { }) return res - case core.ObjectType: - return -1 - default: - return 1 } + + return types.Compare(types.Array, other.Type()) } func (t *Array) Unwrap() interface{} { @@ -216,9 +216,13 @@ func (t *Array) Clone() core.Cloneable { var value core.Value for idx := NewInt(0); idx < t.Length(); idx++ { value = t.Get(idx) - if IsCloneable(value) { - value = value.(core.Cloneable).Clone() + + cloneable, ok := value.(core.Cloneable) + + if ok { + value = cloneable.Clone() } + cloned.Push(value) } diff --git a/pkg/runtime/values/array_test.go b/pkg/runtime/values/array_test.go index d2160b84..09f15903 100644 --- a/pkg/runtime/values/array_test.go +++ b/pkg/runtime/values/array_test.go @@ -2,6 +2,7 @@ package values_test import ( "encoding/json" + "github.com/MontFerret/ferret/pkg/runtime/values/types" "testing" "github.com/MontFerret/ferret/pkg/runtime/core" @@ -56,7 +57,7 @@ func TestArray(t *testing.T) { Convey("Should return type", func() { arr := values.NewArray(1) - So(arr.Type(), ShouldEqual, core.ArrayType) + So(arr.Type().Equals(types.Array), ShouldBeTrue) }) }) diff --git a/pkg/runtime/values/binary.go b/pkg/runtime/values/binary.go index ba9fc67e..9fa5086d 100644 --- a/pkg/runtime/values/binary.go +++ b/pkg/runtime/values/binary.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type Binary []byte @@ -30,17 +31,16 @@ func (b Binary) MarshalJSON() ([]byte, error) { } func (b Binary) Type() core.Type { - return core.BinaryType + return types.Binary } func (b Binary) String() string { return string(b) } -func (b Binary) Compare(other core.Value) int { - // TODO: Lame comparison, need to think more about it - switch other.Type() { - case core.BooleanType: +func (b Binary) Compare(other core.Value) int64 { + if other.Type() == types.Binary { + // TODO: Lame comparison, need to think more about it b2 := other.(*Binary) if b2.Length() == b.Length() { @@ -52,9 +52,9 @@ func (b Binary) Compare(other core.Value) int { } return -1 - default: - return 1 } + + return types.Compare(types.Binary, other.Type()) } func (b Binary) Unwrap() interface{} { diff --git a/pkg/runtime/values/boolean.go b/pkg/runtime/values/boolean.go index eee31a90..395fa2c7 100644 --- a/pkg/runtime/values/boolean.go +++ b/pkg/runtime/values/boolean.go @@ -6,12 +6,15 @@ import ( "strings" "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type Boolean bool -var False = Boolean(false) -var True = Boolean(true) +const ( + False = Boolean(false) + True = Boolean(true) +) func NewBoolean(input bool) Boolean { return Boolean(input) @@ -60,7 +63,7 @@ func (t Boolean) MarshalJSON() ([]byte, error) { } func (t Boolean) Type() core.Type { - return core.BooleanType + return types.Boolean } func (t Boolean) String() string { @@ -71,11 +74,10 @@ func (t Boolean) String() string { return "false" } -func (t Boolean) Compare(other core.Value) int { +func (t Boolean) Compare(other core.Value) int64 { raw := bool(t) - switch other.Type() { - case core.BooleanType: + if types.Boolean.Equals(other.Type()) { i := other.Unwrap().(bool) if raw == i { @@ -87,11 +89,9 @@ func (t Boolean) Compare(other core.Value) int { } return +1 - case core.NoneType: - return 1 - default: - return -1 } + + return types.Compare(types.Boolean, other.Type()) } func (t Boolean) Unwrap() interface{} { diff --git a/pkg/runtime/values/boolean_test.go b/pkg/runtime/values/boolean_test.go index 2dcafc70..e2d3ef2e 100644 --- a/pkg/runtime/values/boolean_test.go +++ b/pkg/runtime/values/boolean_test.go @@ -3,6 +3,7 @@ package values_test import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" . "github.com/smartystreets/goconvey/convey" "testing" ) @@ -21,7 +22,7 @@ func TestBoolean(t *testing.T) { Convey(".Type", t, func() { Convey("Should return a type", func() { - So(values.True.Type(), ShouldEqual, core.BooleanType) + So(values.True.Type().Equals(types.Boolean), ShouldBeTrue) }) }) diff --git a/pkg/runtime/values/date_time.go b/pkg/runtime/values/date_time.go index c77130db..d6bec709 100644 --- a/pkg/runtime/values/date_time.go +++ b/pkg/runtime/values/date_time.go @@ -5,6 +5,7 @@ import ( "time" "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) const DefaultTimeLayout = time.RFC3339 @@ -59,16 +60,15 @@ func (t DateTime) MarshalJSON() ([]byte, error) { } func (t DateTime) Type() core.Type { - return core.DateTimeType + return types.DateTime } func (t DateTime) String() string { return t.Time.String() } -func (t DateTime) Compare(other core.Value) int { - switch other.Type() { - case core.DateTimeType: +func (t DateTime) Compare(other core.Value) int64 { + if other.Type() == types.DateTime { other := other.(DateTime) if t.After(other.Time) { @@ -80,13 +80,9 @@ func (t DateTime) Compare(other core.Value) int { } return 0 - default: - if other.Type() > core.DateTimeType { - return -1 - } - - return 1 } + + return types.Compare(types.DateTime, other.Type()) } func (t DateTime) Unwrap() interface{} { diff --git a/pkg/runtime/values/float.go b/pkg/runtime/values/float.go index 5ec48377..e425308c 100644 --- a/pkg/runtime/values/float.go +++ b/pkg/runtime/values/float.go @@ -9,11 +9,12 @@ import ( "strconv" "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type Float float64 -var ZeroFloat = Float(0.0) +const ZeroFloat = Float(0.0) func NewFloat(input float64) Float { return Float(input) @@ -75,18 +76,18 @@ func (t Float) MarshalJSON() ([]byte, error) { } func (t Float) Type() core.Type { - return core.FloatType + return types.Float } func (t Float) String() string { return fmt.Sprintf("%f", t) } -func (t Float) Compare(other core.Value) int { +func (t Float) Compare(other core.Value) int64 { + otherType := other.Type() raw := float64(t) - switch other.Type() { - case core.FloatType: + if otherType == types.Float { f := other.Unwrap().(float64) if raw == f { @@ -98,7 +99,9 @@ func (t Float) Compare(other core.Value) int { } return +1 - case core.IntType: + } + + if otherType == types.Int { i := other.Unwrap().(int) f := float64(i) @@ -111,11 +114,9 @@ func (t Float) Compare(other core.Value) int { } return +1 - case core.BooleanType, core.NoneType: - return 1 - default: - return -1 } + + return types.Compare(types.Float, otherType) } func (t Float) Unwrap() interface{} { diff --git a/pkg/runtime/values/helpers.go b/pkg/runtime/values/helpers.go index b5917534..a66afed3 100644 --- a/pkg/runtime/values/helpers.go +++ b/pkg/runtime/values/helpers.go @@ -1,6 +1,7 @@ package values import ( + "context" "encoding/binary" "encoding/json" "hash/fnv" @@ -9,9 +10,10 @@ import ( "time" "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) -func GetIn(from core.Value, byPath []core.Value) (core.Value, error) { +func GetIn(ctx context.Context, from core.Value, byPath []core.Value) (core.Value, error) { if byPath == nil || len(byPath) == 0 { return None, nil } @@ -27,32 +29,32 @@ func GetIn(from core.Value, byPath []core.Value) (core.Value, error) { segmentType := segment.Type() switch result.Type() { - case core.ObjectType: + case types.Object: obj := result.(*Object) - if segmentType != core.StringType { - return nil, core.TypeError(segmentType, core.StringType) + if segmentType != types.String { + return nil, core.TypeError(segmentType, types.String) } result, _ = obj.Get(segment.(String)) break - case core.ArrayType: + case types.Array: arr := result.(*Array) - if segmentType != core.IntType { - return nil, core.TypeError(segmentType, core.IntType) + if segmentType != types.Int { + return nil, core.TypeError(segmentType, types.Int) } result = arr.Get(segment.(Int)) break - case core.HTMLElementType, core.HTMLDocumentType: + case types.HTMLElement, types.HTMLDocument: el := result.(HTMLNode) - if segmentType == core.IntType { + if segmentType == types.Int { result = el.GetChildNode(segment.(Int)) - } else if segmentType == core.StringType { + } else if segmentType == types.String { strSegment := segment.(String) switch strSegment { @@ -73,7 +75,7 @@ func GetIn(from core.Value, byPath []core.Value) (core.Value, error) { case "length": result = el.Length() case "url": - if result.Type() == core.HTMLDocumentType { + if result.Type() == types.HTMLDocument { doc, ok := result.(HTMLDocument) if ok { @@ -88,22 +90,22 @@ func GetIn(from core.Value, byPath []core.Value) (core.Value, error) { return None, err } } else { - return nil, core.TypeError(segmentType, core.IntType, core.StringType) + return nil, core.TypeError(segmentType, types.Int, types.String) } default: getter, ok := result.(core.Getter) if ok { - return getter.GetIn(byPath[i:]) + return getter.GetIn(ctx, byPath[i:]) } return None, core.TypeError( from.Type(), - core.ArrayType, - core.ObjectType, - core.HTMLDocumentType, - core.HTMLElementType, + types.Array, + types.Object, + types.HTMLDocument, + types.HTMLElement, ) } } @@ -111,7 +113,7 @@ func GetIn(from core.Value, byPath []core.Value) (core.Value, error) { return result, nil } -func SetIn(to core.Value, byPath []core.Value, value core.Value) error { +func SetIn(ctx context.Context, to core.Value, byPath []core.Value, value core.Value) error { if byPath == nil || len(byPath) == 0 { return nil } @@ -126,11 +128,11 @@ func SetIn(to core.Value, byPath []core.Value, value core.Value) error { segmentType := segment.Type() switch parent.Type() { - case core.ObjectType: + case types.Object: parent := parent.(*Object) - if segmentType != core.StringType { - return core.TypeError(segmentType, core.StringType) + if segmentType != types.String { + return core.TypeError(segmentType, types.String) } if isTarget == false { @@ -140,9 +142,9 @@ func SetIn(to core.Value, byPath []core.Value, value core.Value) error { } break - case core.ArrayType: - if segmentType != core.IntType { - return core.TypeError(segmentType, core.IntType) + case types.Array: + if segmentType != types.Int { + return core.TypeError(segmentType, types.Int) } parent := parent.(*Array) @@ -160,19 +162,19 @@ func SetIn(to core.Value, byPath []core.Value, value core.Value) error { setter, ok := parent.(core.Setter) if ok { - return setter.SetIn(byPath[idx:], value) + return setter.SetIn(ctx, byPath[idx:], value) } // redefine parent - isArray := segmentType == core.IntType + isArray := segmentType == types.Int // it's not an index if isArray == false { obj := NewObject() parent = obj - if segmentType != core.StringType { - return core.TypeError(segmentType, core.StringType) + if segmentType != types.String { + return core.TypeError(segmentType, types.String) } if isTarget { @@ -190,7 +192,7 @@ func SetIn(to core.Value, byPath []core.Value, value core.Value) error { } // set new parent - if err := SetIn(to, byPath[0:idx-1], parent); err != nil { + if err := SetIn(ctx, to, byPath[0:idx-1], parent); err != nil { return err } @@ -302,9 +304,9 @@ func Unmarshal(value json.RawMessage) (core.Value, error) { func IsCloneable(value core.Value) Boolean { switch value.Type() { - case core.ArrayType: + case types.Array: return NewBoolean(true) - case core.ObjectType: + case types.Object: return NewBoolean(true) default: return NewBoolean(false) @@ -313,15 +315,15 @@ func IsCloneable(value core.Value) Boolean { func ToBoolean(input core.Value) core.Value { switch input.Type() { - case core.BooleanType: + case types.Boolean: return input - case core.NoneType: + case types.None: return False - case core.StringType: + case types.String: return NewBoolean(input.String() != "") - case core.IntType: + case types.Int: return NewBoolean(input.(Int) != 0) - case core.FloatType: + case types.Float: return NewBoolean(input.(Float) != 0) default: return True @@ -330,15 +332,15 @@ func ToBoolean(input core.Value) core.Value { func ToArray(input core.Value) core.Value { switch input.Type() { - case core.BooleanType, - core.IntType, - core.FloatType, - core.StringType, - core.DateTimeType: + case types.Boolean, + types.Int, + types.Float, + types.String, + types.DateTime: return NewArrayWith(input) - case core.HTMLElementType, - core.HTMLDocumentType: + case types.HTMLElement, + types.HTMLDocument: val := input.(HTMLNode) attrs := val.GetAttributes() @@ -357,9 +359,9 @@ func ToArray(input core.Value) core.Value { }) return obj - case core.ArrayType: + case types.Array: return input.Copy() - case core.ObjectType: + case types.Object: obj, ok := input.(*Object) if !ok { diff --git a/pkg/runtime/values/helpers_test.go b/pkg/runtime/values/helpers_test.go index 5e477022..44d942ff 100644 --- a/pkg/runtime/values/helpers_test.go +++ b/pkg/runtime/values/helpers_test.go @@ -1,6 +1,7 @@ package values_test import ( + "context" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" "testing" @@ -8,39 +9,41 @@ import ( . "github.com/smartystreets/goconvey/convey" ) -type CustomType struct { +var CustomType = core.NewType("custom") + +type CustomValue struct { properties map[core.Value]core.Value } -func (t *CustomType) MarshalJSON() ([]byte, error) { +func (t *CustomValue) MarshalJSON() ([]byte, error) { return nil, core.ErrNotImplemented } -func (t *CustomType) Type() core.Type { - return core.CustomType +func (t *CustomValue) Type() core.Type { + return CustomType } -func (t *CustomType) String() string { +func (t *CustomValue) String() string { return "" } -func (t *CustomType) Compare(other core.Value) int { +func (t *CustomValue) Compare(other core.Value) int64 { return other.Compare(t) * -1 } -func (t *CustomType) Unwrap() interface{} { +func (t *CustomValue) Unwrap() interface{} { return t } -func (t *CustomType) Hash() uint64 { +func (t *CustomValue) Hash() uint64 { return 0 } -func (t *CustomType) Copy() core.Value { +func (t *CustomValue) Copy() core.Value { return values.None } -func (t *CustomType) GetIn(path []core.Value) (core.Value, error) { +func (t *CustomValue) GetIn(ctx context.Context, path []core.Value) (core.Value, error) { if path == nil || len(path) == 0 { return values.None, nil } @@ -56,10 +59,10 @@ func (t *CustomType) GetIn(path []core.Value) (core.Value, error) { return propValue, nil } - return values.GetIn(propValue, path[1:]) + return values.GetIn(ctx, propValue, path[1:]) } -func (t *CustomType) SetIn(path []core.Value, value core.Value) error { +func (t *CustomValue) SetIn(ctx context.Context, path []core.Value, value core.Value) error { if path == nil || len(path) == 0 { return nil } @@ -77,17 +80,17 @@ func (t *CustomType) SetIn(path []core.Value, value core.Value) error { return nil } - return values.SetIn(propValue, path[1:], value) + return values.SetIn(ctx, propValue, path[1:], value) } func TestHelpers(t *testing.T) { Convey("Helpers", t, func() { Convey("Getter", func() { Convey("It should get a value by a given path", func() { - ct := &CustomType{ + ct := &CustomValue{ properties: map[core.Value]core.Value{ values.NewString("foo"): values.NewInt(1), - values.NewString("bar"): &CustomType{ + values.NewString("bar"): &CustomValue{ properties: map[core.Value]core.Value{ values.NewString("qaz"): values.NewInt(2), }, @@ -95,14 +98,16 @@ func TestHelpers(t *testing.T) { }, } - foo, err := values.GetIn(ct, []core.Value{ + ctx := context.Background() + + foo, err := values.GetIn(ctx, ct, []core.Value{ values.NewString("foo"), }) So(err, ShouldBeNil) So(foo, ShouldEqual, values.NewInt(1)) - qaz, err := values.GetIn(ct, []core.Value{ + qaz, err := values.GetIn(ctx, ct, []core.Value{ values.NewString("bar"), values.NewString("qaz"), }) @@ -114,10 +119,10 @@ func TestHelpers(t *testing.T) { Convey("Setter", func() { Convey("It should get a value by a given path", func() { - ct := &CustomType{ + ct := &CustomValue{ properties: map[core.Value]core.Value{ values.NewString("foo"): values.NewInt(1), - values.NewString("bar"): &CustomType{ + values.NewString("bar"): &CustomValue{ properties: map[core.Value]core.Value{ values.NewString("qaz"): values.NewInt(2), }, @@ -125,21 +130,23 @@ func TestHelpers(t *testing.T) { }, } - err := values.SetIn(ct, []core.Value{ + ctx := context.Background() + + err := values.SetIn(ctx, ct, []core.Value{ values.NewString("foo"), }, values.NewInt(2)) So(err, ShouldBeNil) So(ct.properties[values.NewString("foo")], ShouldEqual, values.NewInt(2)) - err = values.SetIn(ct, []core.Value{ + err = values.SetIn(ctx, ct, []core.Value{ values.NewString("bar"), values.NewString("qaz"), }, values.NewString("foobar")) So(err, ShouldBeNil) - qaz, err := values.GetIn(ct, []core.Value{ + qaz, err := values.GetIn(ctx, ct, []core.Value{ values.NewString("bar"), values.NewString("qaz"), }) diff --git a/pkg/runtime/values/int.go b/pkg/runtime/values/int.go index ddeb2cd5..dc3674d4 100644 --- a/pkg/runtime/values/int.go +++ b/pkg/runtime/values/int.go @@ -7,11 +7,12 @@ import ( "strconv" "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type Int int64 -var ZeroInt = Int(0) +const ZeroInt = Int(0) func NewInt(input int) Int { return Int(int64(input)) @@ -65,16 +66,17 @@ func (t Int) MarshalJSON() ([]byte, error) { } func (t Int) Type() core.Type { - return core.IntType + return types.Int } func (t Int) String() string { return strconv.Itoa(int(t)) } -func (t Int) Compare(other core.Value) int { - switch other.Type() { - case core.IntType: +func (t Int) Compare(other core.Value) int64 { + otherType := other.Type() + + if otherType == types.Int { i := other.(Int) if t == i { @@ -86,7 +88,9 @@ func (t Int) Compare(other core.Value) int { } return +1 - case core.FloatType: + } + + if otherType == types.Float { f := other.(Float) f2 := Float(t) @@ -99,11 +103,9 @@ func (t Int) Compare(other core.Value) int { } return +1 - case core.BooleanType, core.NoneType: - return 1 - default: - return -1 } + + return types.Compare(types.Int, otherType) } func (t Int) Unwrap() interface{} { diff --git a/pkg/runtime/values/none.go b/pkg/runtime/values/none.go index 746434a0..4e2f3fc1 100644 --- a/pkg/runtime/values/none.go +++ b/pkg/runtime/values/none.go @@ -2,6 +2,7 @@ package values import ( "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type none struct{} @@ -13,20 +14,19 @@ func (t *none) MarshalJSON() ([]byte, error) { } func (t *none) Type() core.Type { - return core.NoneType + return types.None } func (t *none) String() string { return "" } -func (t *none) Compare(other core.Value) int { - switch other.Type() { - case core.NoneType: +func (t *none) Compare(other core.Value) int64 { + if other.Type() == types.None { return 0 - default: - return -1 } + + return -1 } func (t *none) Unwrap() interface{} { diff --git a/pkg/runtime/values/object.go b/pkg/runtime/values/object.go index f54f19e1..af8ef86d 100644 --- a/pkg/runtime/values/object.go +++ b/pkg/runtime/values/object.go @@ -7,14 +7,17 @@ import ( "sort" "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type ( ObjectPredicate = func(value core.Value, key string) bool - ObjectProperty struct { + + ObjectProperty struct { key string value core.Value } + Object struct { value map[string]core.Value } @@ -43,7 +46,7 @@ func (t *Object) MarshalJSON() ([]byte, error) { } func (t *Object) Type() core.Type { - return core.ObjectType + return types.Object } func (t *Object) String() string { @@ -59,22 +62,23 @@ func (t *Object) String() string { // Compare compares the source object with other core.Value // The behavior of the Compare is similar // to the comparison of objects in ArangoDB -func (t *Object) Compare(other core.Value) int { - switch other.Type() { - case core.ObjectType: +func (t *Object) Compare(other core.Value) int64 { + if other.Type() == t.Type() { other := other.(*Object) if t.Length() == 0 && other.Length() == 0 { return 0 } + if t.Length() < other.Length() { return -1 } + if t.Length() > other.Length() { return 1 } - var res = 0 + var res int64 sortedT := sort.StringSlice(t.Keys()) sortedT.Sort() @@ -92,6 +96,7 @@ func (t *Object) Compare(other core.Value) int { tVal, _ = t.Get(NewString(tKey)) otherVal, _ = other.Get(NewString(tKey)) res = tVal.Compare(otherVal) + continue } @@ -105,9 +110,9 @@ func (t *Object) Compare(other core.Value) int { } return res - default: - return 1 } + + return types.Compare(types.Object, other.Type()) } func (t *Object) Unwrap() interface{} { @@ -201,10 +206,6 @@ func (t *Object) Get(key String) (core.Value, Boolean) { return None, NewBoolean(found) } -func (t *Object) GetIn(path []core.Value) (core.Value, error) { - return GetIn(t, path) -} - func (t *Object) Set(key String, value core.Value) { if value != nil { t.value[string(key)] = value @@ -217,20 +218,20 @@ func (t *Object) Remove(key String) { delete(t.value, string(key)) } -func (t *Object) SetIn(path []core.Value, value core.Value) error { - return SetIn(t, path, value) -} - func (t *Object) Clone() core.Cloneable { cloned := NewObject() var value core.Value var keyString String + for key := range t.value { keyString = NewString(key) value, _ = t.Get(keyString) - if IsCloneable(value) { - value = value.(core.Cloneable).Clone() + + cloneable, ok := value.(core.Cloneable) + + if ok { + value = cloneable.Clone() } cloned.Set(keyString, value) } diff --git a/pkg/runtime/values/object_test.go b/pkg/runtime/values/object_test.go index 4911b01e..5769c042 100644 --- a/pkg/runtime/values/object_test.go +++ b/pkg/runtime/values/object_test.go @@ -1,6 +1,7 @@ package values_test import ( + "github.com/MontFerret/ferret/pkg/runtime/values/types" "testing" "github.com/MontFerret/ferret/pkg/runtime/core" @@ -63,7 +64,7 @@ func TestObject(t *testing.T) { Convey("Should return type", func() { obj := values.NewObject() - So(obj.Type(), ShouldEqual, core.ObjectType) + So(obj.Type().Equals(types.Object), ShouldBeTrue) }) }) diff --git a/pkg/runtime/values/string.go b/pkg/runtime/values/string.go index a3eeca23..6f9479eb 100644 --- a/pkg/runtime/values/string.go +++ b/pkg/runtime/values/string.go @@ -7,12 +7,15 @@ import ( "strings" "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type String string -var EmptyString = String("") -var SpaceString = String(" ") +const ( + EmptyString = String("") + SpaceString = String(" ") +) func NewString(input string) String { if input == "" { @@ -69,24 +72,19 @@ func (t String) MarshalJSON() ([]byte, error) { } func (t String) Type() core.Type { - return core.StringType + return types.String } func (t String) String() string { return string(t) } -func (t String) Compare(other core.Value) int { - switch other.Type() { - case core.StringType: - return strings.Compare(string(t), other.Unwrap().(string)) - default: - if other.Type() > core.DateTimeType { - return -1 - } - - return 1 +func (t String) Compare(other core.Value) int64 { + if other.Type() == types.String { + return int64(strings.Compare(string(t), other.Unwrap().(string))) } + + return types.Compare(types.String, other.Type()) } func (t String) Unwrap() interface{} { diff --git a/pkg/runtime/values/types/helpers.go b/pkg/runtime/values/types/helpers.go new file mode 100644 index 00000000..c1be00af --- /dev/null +++ b/pkg/runtime/values/types/helpers.go @@ -0,0 +1,44 @@ +package types + +import "github.com/MontFerret/ferret/pkg/runtime/core" + +// Comparison table of builtin types +var typeComparisonTable = map[core.Type]uint64{ + None: 0, + Boolean: 1, + Int: 2, + Float: 3, + String: 4, + DateTime: 5, + Array: 6, + Object: 7, + HTMLElement: 8, + HTMLDocument: 9, + Binary: 10, +} + +func Compare(first, second core.Type) int64 { + f, ok := typeComparisonTable[first] + + // custom type + if !ok { + return -1 + } + + s, ok := typeComparisonTable[second] + + // custom type + if !ok { + return 1 + } + + if f == s { + return 0 + } + + if f > s { + return 1 + } + + return -1 +} diff --git a/pkg/runtime/values/types/helpers_test.go b/pkg/runtime/values/types/helpers_test.go new file mode 100644 index 00000000..a160f38a --- /dev/null +++ b/pkg/runtime/values/types/helpers_test.go @@ -0,0 +1,176 @@ +package types_test + +import ( + "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" + . "github.com/smartystreets/goconvey/convey" + "testing" +) + +func TestHelpers(t *testing.T) { + Convey("Compare", t, func() { + typesList := []core.Type{ + types.None, + types.Boolean, + types.Int, + types.Float, + types.String, + types.DateTime, + types.Array, + types.Object, + types.Binary, + } + + Convey("None", func() { + So(types.Compare(types.None, types.None), ShouldEqual, 0) + + for _, t := range typesList[1:] { + So(types.Compare(types.None, t), ShouldEqual, -1) + } + }) + + Convey("Boolean", func() { + for _, t := range typesList { + switch t.ID() { + case types.None.ID(): + So(types.Compare(types.Boolean, t), ShouldEqual, 1) + case types.Boolean.ID(): + So(types.Compare(types.Boolean, t), ShouldEqual, 0) + default: + So(types.Compare(types.Boolean, t), ShouldEqual, -1) + } + } + }) + + Convey("Int", func() { + for _, t := range typesList { + switch t.ID() { + case types.None.ID(): + So(types.Compare(types.Int, t), ShouldEqual, 1) + case types.Boolean.ID(): + So(types.Compare(types.Int, t), ShouldEqual, 1) + case types.Int.ID(): + So(types.Compare(types.Int, t), ShouldEqual, 0) + default: + So(types.Compare(types.Int, t), ShouldEqual, -1) + } + } + }) + + Convey("Float", func() { + for _, t := range typesList { + switch t.ID() { + case types.None.ID(): + So(types.Compare(types.Float, t), ShouldEqual, 1) + case types.Boolean.ID(): + So(types.Compare(types.Float, t), ShouldEqual, 1) + case types.Int.ID(): + So(types.Compare(types.Float, t), ShouldEqual, 1) + case types.Float.ID(): + So(types.Compare(types.Float, t), ShouldEqual, 0) + default: + So(types.Compare(types.Float, t), ShouldEqual, -1) + } + } + }) + + Convey("String", func() { + for _, t := range typesList { + switch t.ID() { + case types.None.ID(): + So(types.Compare(types.String, t), ShouldEqual, 1) + case types.Boolean.ID(): + So(types.Compare(types.String, t), ShouldEqual, 1) + case types.Int.ID(): + So(types.Compare(types.String, t), ShouldEqual, 1) + case types.Float.ID(): + So(types.Compare(types.String, t), ShouldEqual, 1) + case types.String.ID(): + So(types.Compare(types.String, t), ShouldEqual, 0) + default: + So(types.Compare(types.String, t), ShouldEqual, -1) + } + } + }) + + Convey("DateTime", func() { + for _, t := range typesList { + switch t.ID() { + case types.None.ID(): + So(types.Compare(types.DateTime, t), ShouldEqual, 1) + case types.Boolean.ID(): + So(types.Compare(types.DateTime, t), ShouldEqual, 1) + case types.Int.ID(): + So(types.Compare(types.DateTime, t), ShouldEqual, 1) + case types.Float.ID(): + So(types.Compare(types.DateTime, t), ShouldEqual, 1) + case types.String.ID(): + So(types.Compare(types.DateTime, t), ShouldEqual, 1) + case types.DateTime.ID(): + So(types.Compare(types.DateTime, t), ShouldEqual, 0) + default: + So(types.Compare(types.DateTime, t), ShouldEqual, -1) + } + } + }) + + Convey("Array", func() { + for _, t := range typesList { + switch t.ID() { + case types.None.ID(): + So(types.Compare(types.Array, t), ShouldEqual, 1) + case types.Boolean.ID(): + So(types.Compare(types.Array, t), ShouldEqual, 1) + case types.Int.ID(): + So(types.Compare(types.Array, t), ShouldEqual, 1) + case types.Float.ID(): + So(types.Compare(types.Array, t), ShouldEqual, 1) + case types.String.ID(): + So(types.Compare(types.Array, t), ShouldEqual, 1) + case types.DateTime.ID(): + So(types.Compare(types.Array, t), ShouldEqual, 1) + case types.Array.ID(): + So(types.Compare(types.Array, t), ShouldEqual, 0) + default: + So(types.Compare(types.Array, t), ShouldEqual, -1) + } + } + }) + + Convey("Object", func() { + for _, t := range typesList { + switch t.ID() { + case types.None.ID(): + So(types.Compare(types.Object, t), ShouldEqual, 1) + case types.Boolean.ID(): + So(types.Compare(types.Object, t), ShouldEqual, 1) + case types.Int.ID(): + So(types.Compare(types.Object, t), ShouldEqual, 1) + case types.Float.ID(): + So(types.Compare(types.Object, t), ShouldEqual, 1) + case types.String.ID(): + So(types.Compare(types.Object, t), ShouldEqual, 1) + case types.DateTime.ID(): + So(types.Compare(types.Object, t), ShouldEqual, 1) + case types.Array.ID(): + So(types.Compare(types.Object, t), ShouldEqual, 1) + case types.Object.ID(): + So(types.Compare(types.Object, t), ShouldEqual, 0) + default: + So(types.Compare(types.Object, t), ShouldEqual, -1) + } + } + }) + + Convey("Binary", func() { + for _, t := range typesList { + switch t.ID() { + case types.Binary.ID(): + So(types.Compare(types.Binary, t), ShouldEqual, 0) + default: + So(types.Compare(types.Binary, t), ShouldEqual, 1) + } + } + }) + }) +} diff --git a/pkg/runtime/values/types/types.go b/pkg/runtime/values/types/types.go new file mode 100644 index 00000000..863ac6f2 --- /dev/null +++ b/pkg/runtime/values/types/types.go @@ -0,0 +1,17 @@ +package types + +import "github.com/MontFerret/ferret/pkg/runtime/core" + +var ( + None = core.NewType("none") + Boolean = core.NewType("boolean") + Int = core.NewType("int") + Float = core.NewType("float") + String = core.NewType("string") + DateTime = core.NewType("date_time") + Array = core.NewType("array") + Object = core.NewType("object") + Binary = core.NewType("binary") + HTMLElement = core.NewType("HTMLElement") + HTMLDocument = core.NewType("HTMLDocument") +) diff --git a/pkg/runtime/values/types/types_test.go b/pkg/runtime/values/types/types_test.go new file mode 100644 index 00000000..f41c4000 --- /dev/null +++ b/pkg/runtime/values/types/types_test.go @@ -0,0 +1,84 @@ +package types_test + +import ( + "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values/types" + . "github.com/smartystreets/goconvey/convey" + "testing" +) + +type TestValue struct { + t core.Type +} + +func (v TestValue) MarshalJSON() ([]byte, error) { + return nil, nil +} + +func (v TestValue) Type() core.Type { + return v.t +} + +func (v TestValue) String() string { + return "" +} + +func (v TestValue) Compare(other core.Value) int64 { + return 0 +} + +func (v TestValue) Unwrap() interface{} { + return nil +} + +func (v TestValue) Hash() uint64 { + return 0 +} + +func (v TestValue) Copy() core.Value { + return v +} + +func TestType(t *testing.T) { + Convey(".Name", t, func() { + So(types.None.String(), ShouldEqual, "none") + So(types.Boolean.String(), ShouldEqual, "boolean") + So(types.Int.String(), ShouldEqual, "int") + So(types.Float.String(), ShouldEqual, "float") + So(types.String.String(), ShouldEqual, "string") + So(types.DateTime.String(), ShouldEqual, "date_time") + So(types.Array.String(), ShouldEqual, "array") + So(types.Object.String(), ShouldEqual, "object") + So(types.Binary.String(), ShouldEqual, "binary") + }) + + Convey("==", t, func() { + typesList := []core.Type{ + types.None, + types.Boolean, + types.Int, + types.Float, + types.String, + types.DateTime, + types.Array, + types.Object, + types.Binary, + } + + valuesList := []core.Value{ + TestValue{types.None}, + TestValue{types.Boolean}, + TestValue{types.Int}, + TestValue{types.Float}, + TestValue{types.String}, + TestValue{types.DateTime}, + TestValue{types.Array}, + TestValue{types.Object}, + TestValue{types.Binary}, + } + + for i, t := range typesList { + So(t == valuesList[i].Type(), ShouldBeTrue) + } + }) +} diff --git a/pkg/stdlib/arrays/append.go b/pkg/stdlib/arrays/append.go index a26b9086..6d60b4a5 100644 --- a/pkg/stdlib/arrays/append.go +++ b/pkg/stdlib/arrays/append.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Append appends a new item to an array and returns a new array with a given element. @@ -19,7 +20,7 @@ func Append(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err @@ -30,7 +31,7 @@ func Append(_ context.Context, args ...core.Value) (core.Value, error) { unique := values.False if len(args) > 2 { - err = core.ValidateType(args[2], core.BooleanType) + err = core.ValidateType(args[2], types.Boolean) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/first.go b/pkg/stdlib/arrays/first.go index 9028676f..38977ef4 100644 --- a/pkg/stdlib/arrays/first.go +++ b/pkg/stdlib/arrays/first.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // First returns a first element from a given array. @@ -17,7 +18,7 @@ func First(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, nil diff --git a/pkg/stdlib/arrays/flatten.go b/pkg/stdlib/arrays/flatten.go index 267a8ef0..fdc13fc3 100644 --- a/pkg/stdlib/arrays/flatten.go +++ b/pkg/stdlib/arrays/flatten.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Flatten turn an array of arrays into a flat array. @@ -22,7 +23,7 @@ func Flatten(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err @@ -32,7 +33,7 @@ func Flatten(_ context.Context, args ...core.Value) (core.Value, error) { level := 1 if len(args) > 1 { - err = core.ValidateType(args[1], core.IntType) + err = core.ValidateType(args[1], types.Int) if err != nil { return values.None, err @@ -49,7 +50,7 @@ func Flatten(_ context.Context, args ...core.Value) (core.Value, error) { currentLevel++ input.ForEach(func(value core.Value, idx int) bool { - if value.Type() != core.ArrayType || currentLevel > level { + if value.Type() != types.Array || currentLevel > level { result.Push(value) } else { unwrap(value.(*values.Array)) diff --git a/pkg/stdlib/arrays/intersection.go b/pkg/stdlib/arrays/intersection.go index afe06826..0b8cb112 100644 --- a/pkg/stdlib/arrays/intersection.go +++ b/pkg/stdlib/arrays/intersection.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Intersection return the intersection of all arrays specified. @@ -27,7 +28,7 @@ func sections(args []core.Value, count int) (core.Value, error) { capacity := len(args) for _, i := range args { - err := core.ValidateType(i, core.ArrayType) + err := core.ValidateType(i, types.Array) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/last.go b/pkg/stdlib/arrays/last.go index 3b7dbc21..78fbef5c 100644 --- a/pkg/stdlib/arrays/last.go +++ b/pkg/stdlib/arrays/last.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Last returns the last element of an array. @@ -17,7 +18,7 @@ func Last(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, nil diff --git a/pkg/stdlib/arrays/minus.go b/pkg/stdlib/arrays/minus.go index 5344825b..953c51ab 100644 --- a/pkg/stdlib/arrays/minus.go +++ b/pkg/stdlib/arrays/minus.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Minus return the difference of all arrays specified. @@ -22,7 +23,7 @@ func Minus(_ context.Context, args ...core.Value) (core.Value, error) { capacity := values.NewInt(0) for idx, i := range args { - err := core.ValidateType(i, core.ArrayType) + err := core.ValidateType(i, types.Array) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/nth.go b/pkg/stdlib/arrays/nth.go index 381856e8..24679eec 100644 --- a/pkg/stdlib/arrays/nth.go +++ b/pkg/stdlib/arrays/nth.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Nth returns the element of an array at a given position. @@ -20,13 +21,13 @@ func Nth(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err } - err = core.ValidateType(args[1], core.IntType) + err = core.ValidateType(args[1], types.Int) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/pop.go b/pkg/stdlib/arrays/pop.go index 19d598e5..8230bdfe 100644 --- a/pkg/stdlib/arrays/pop.go +++ b/pkg/stdlib/arrays/pop.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Pop returns a new array without last element. @@ -17,7 +18,7 @@ func Pop(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/position.go b/pkg/stdlib/arrays/position.go index f63fa50f..01f1a3e9 100644 --- a/pkg/stdlib/arrays/position.go +++ b/pkg/stdlib/arrays/position.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Position returns a value indicating whether an element is contained in array. Optionally returns its position. @@ -18,7 +19,7 @@ func Position(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err @@ -29,7 +30,7 @@ func Position(_ context.Context, args ...core.Value) (core.Value, error) { retIdx := false if len(args) > 2 { - err = core.ValidateType(args[2], core.BooleanType) + err = core.ValidateType(args[2], types.Boolean) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/push.go b/pkg/stdlib/arrays/push.go index 965b5d3c..a3d3c9e1 100644 --- a/pkg/stdlib/arrays/push.go +++ b/pkg/stdlib/arrays/push.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Push create a new array with appended value. @@ -19,7 +20,7 @@ func Push(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err @@ -30,7 +31,7 @@ func Push(_ context.Context, args ...core.Value) (core.Value, error) { uniq := false if len(args) > 2 { - err = core.ValidateType(args[2], core.BooleanType) + err = core.ValidateType(args[2], types.Boolean) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/remove_nth.go b/pkg/stdlib/arrays/remove_nth.go index 8ffcda22..c559ee82 100644 --- a/pkg/stdlib/arrays/remove_nth.go +++ b/pkg/stdlib/arrays/remove_nth.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // RemoveNth returns a new array without an element by a given position. @@ -18,13 +19,13 @@ func RemoveNth(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err } - err = core.ValidateType(args[1], core.IntType) + err = core.ValidateType(args[1], types.Int) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/remove_value.go b/pkg/stdlib/arrays/remove_value.go index 753593c8..5ede00d1 100644 --- a/pkg/stdlib/arrays/remove_value.go +++ b/pkg/stdlib/arrays/remove_value.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // RemoveValue returns a new array with removed all occurrences of value in a given array. @@ -20,7 +21,7 @@ func RemoveValue(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err @@ -31,7 +32,7 @@ func RemoveValue(_ context.Context, args ...core.Value) (core.Value, error) { limit := -1 if len(args) > 2 { - err = core.ValidateType(args[2], core.IntType) + err = core.ValidateType(args[2], types.Int) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/remove_values.go b/pkg/stdlib/arrays/remove_values.go index 6e6b46b9..c89a8e99 100644 --- a/pkg/stdlib/arrays/remove_values.go +++ b/pkg/stdlib/arrays/remove_values.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // RemoveValues returns a new array with removed all occurrences of values in a given array. @@ -18,13 +19,13 @@ func RemoveValues(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err } - err = core.ValidateType(args[1], core.ArrayType) + err = core.ValidateType(args[1], types.Array) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/reverse.go b/pkg/stdlib/arrays/reverse.go index 22554094..db078cf2 100644 --- a/pkg/stdlib/arrays/reverse.go +++ b/pkg/stdlib/arrays/reverse.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Reverse return a new array with its elements reversed. @@ -17,7 +18,7 @@ func Reverse(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/shift.go b/pkg/stdlib/arrays/shift.go index fb1fd262..56593928 100644 --- a/pkg/stdlib/arrays/shift.go +++ b/pkg/stdlib/arrays/shift.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Shift returns a new array without the first element. @@ -17,7 +18,7 @@ func Shift(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/slice.go b/pkg/stdlib/arrays/slice.go index 26e4ab6b..945a33bd 100644 --- a/pkg/stdlib/arrays/slice.go +++ b/pkg/stdlib/arrays/slice.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Slice returns a new sliced array. @@ -19,13 +20,13 @@ func Slice(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err } - err = core.ValidateType(args[1], core.IntType) + err = core.ValidateType(args[1], types.Int) if err != nil { return values.None, err @@ -36,7 +37,7 @@ func Slice(_ context.Context, args ...core.Value) (core.Value, error) { length := values.NewInt(int(arr.Length())) if len(args) > 2 { - if args[2].Type() == core.IntType { + if args[2].Type() == types.Int { arg2 := args[2].(values.Int) if arg2 > 0 { diff --git a/pkg/stdlib/arrays/sorted.go b/pkg/stdlib/arrays/sorted.go index 17637cfc..a769956c 100644 --- a/pkg/stdlib/arrays/sorted.go +++ b/pkg/stdlib/arrays/sorted.go @@ -2,8 +2,10 @@ package arrays import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Sorted sorts all elements in anyArray. @@ -17,7 +19,7 @@ func Sorted(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/sorted_unique.go b/pkg/stdlib/arrays/sorted_unique.go index e98857e1..cb7645f6 100644 --- a/pkg/stdlib/arrays/sorted_unique.go +++ b/pkg/stdlib/arrays/sorted_unique.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // SortedUnique sorts all elements in anyArray. @@ -19,7 +20,7 @@ func SortedUnique(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/union.go b/pkg/stdlib/arrays/union.go index 25ecc7b8..393ffb53 100644 --- a/pkg/stdlib/arrays/union.go +++ b/pkg/stdlib/arrays/union.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Union returns the union of all passed arrays. @@ -17,7 +18,7 @@ func Union(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err @@ -27,7 +28,7 @@ func Union(_ context.Context, args ...core.Value) (core.Value, error) { result := values.NewArray(len(args) * int(firstArrLen)) for _, arg := range args { - err := core.ValidateType(arg, core.ArrayType) + err := core.ValidateType(arg, types.Array) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/union_distinct.go b/pkg/stdlib/arrays/union_distinct.go index b4c159a0..a1634aed 100644 --- a/pkg/stdlib/arrays/union_distinct.go +++ b/pkg/stdlib/arrays/union_distinct.go @@ -2,8 +2,10 @@ package arrays import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) func UnionDistinct(_ context.Context, args ...core.Value) (core.Value, error) { @@ -13,7 +15,7 @@ func UnionDistinct(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err @@ -24,7 +26,7 @@ func UnionDistinct(_ context.Context, args ...core.Value) (core.Value, error) { hashes := make(map[uint64]bool) for _, arg := range args { - err := core.ValidateType(arg, core.ArrayType) + err := core.ValidateType(arg, types.Array) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/unique.go b/pkg/stdlib/arrays/unique.go index 821ccf2d..32018fc5 100644 --- a/pkg/stdlib/arrays/unique.go +++ b/pkg/stdlib/arrays/unique.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Unique returns all unique elements from a given array. @@ -17,7 +18,7 @@ func Unique(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err diff --git a/pkg/stdlib/arrays/unshift.go b/pkg/stdlib/arrays/unshift.go index 51c8ade8..b4d59db9 100644 --- a/pkg/stdlib/arrays/unshift.go +++ b/pkg/stdlib/arrays/unshift.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Unshift prepends value to a given array. @@ -20,7 +21,7 @@ func Unshift(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err @@ -31,7 +32,7 @@ func Unshift(_ context.Context, args ...core.Value) (core.Value, error) { uniq := values.False if len(args) > 2 { - err = core.ValidateType(args[2], core.BooleanType) + err = core.ValidateType(args[2], types.Boolean) if err != nil { return values.None, err diff --git a/pkg/stdlib/collections/length.go b/pkg/stdlib/collections/length.go index 55f1a834..1d8eb22a 100644 --- a/pkg/stdlib/collections/length.go +++ b/pkg/stdlib/collections/length.go @@ -2,9 +2,11 @@ package collections import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/collections" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) func Length(_ context.Context, inputs ...core.Value) (core.Value, error) { @@ -15,19 +17,20 @@ func Length(_ context.Context, inputs ...core.Value) (core.Value, error) { } value := inputs[0] - err = core.ValidateType( - value, - core.StringType, - core.ArrayType, - core.ObjectType, - core.HTMLElementType, - core.HTMLDocumentType, - core.BinaryType, - ) - if err != nil { - return values.None, err + c, ok := value.(collections.Collection) + + if !ok { + return values.None, core.TypeError(value.Type(), + types.String, + types.Array, + types.Object, + types.HTMLElement, + types.HTMLDocument, + types.Binary, + core.NewType("Collection"), + ) } - return value.(collections.Collection).Length(), nil + return c.Length(), nil } diff --git a/pkg/stdlib/datetime/add_subtract.go b/pkg/stdlib/datetime/add_subtract.go index 7131455e..92abda1c 100644 --- a/pkg/stdlib/datetime/add_subtract.go +++ b/pkg/stdlib/datetime/add_subtract.go @@ -5,12 +5,13 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) var ( - sliceDateTime = []core.Type{core.DateTimeType} - sliceIntType = []core.Type{core.IntType} - sliceStringType = []core.Type{core.StringType} + sliceDateTime = []core.Type{types.DateTime} + sliceIntType = []core.Type{types.Int} + sliceStringType = []core.Type{types.String} emptyDateTime values.DateTime emptyInt values.Int diff --git a/pkg/stdlib/datetime/compare.go b/pkg/stdlib/datetime/compare.go index 7519b1e5..c6ae0c24 100644 --- a/pkg/stdlib/datetime/compare.go +++ b/pkg/stdlib/datetime/compare.go @@ -1,12 +1,12 @@ package datetime import ( - "github.com/pkg/errors" - "context" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" + "github.com/pkg/errors" ) // DateCompare check if two partial dates match. @@ -36,7 +36,7 @@ func DateCompare(_ context.Context, args ...core.Value) (core.Value, error) { rangeEnd := values.NewString("millisecond") if len(args) == 4 { - if err = core.ValidateType(args[3], core.StringType); err != nil { + if err = core.ValidateType(args[3], types.String); err != nil { return values.None, err } rangeEnd = args[3].(values.String) diff --git a/pkg/stdlib/datetime/date.go b/pkg/stdlib/datetime/date.go index ce7a8ae4..c4b5537b 100644 --- a/pkg/stdlib/datetime/date.go +++ b/pkg/stdlib/datetime/date.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Date convert RFC3339 date time string to DateTime object. @@ -17,7 +18,7 @@ func Date(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.StringType) + err = core.ValidateType(args[0], types.String) if err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/day.go b/pkg/stdlib/datetime/day.go index fe246d00..e3249391 100644 --- a/pkg/stdlib/datetime/day.go +++ b/pkg/stdlib/datetime/day.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DateDay returns the day of date as a number. @@ -16,7 +17,7 @@ func DateDay(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.DateTimeType) + err = core.ValidateType(args[0], types.DateTime) if err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/dayofweek.go b/pkg/stdlib/datetime/dayofweek.go index 64b363c4..df72c177 100644 --- a/pkg/stdlib/datetime/dayofweek.go +++ b/pkg/stdlib/datetime/dayofweek.go @@ -3,9 +3,9 @@ package datetime import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DateDayOfWeek returns number of the weekday from the date. Sunday is the 0th day of week. @@ -17,7 +17,7 @@ func DateDayOfWeek(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.DateTimeType) + err = core.ValidateType(args[0], types.DateTime) if err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/dayofyear.go b/pkg/stdlib/datetime/dayofyear.go index 61218a3e..e88a8bb5 100644 --- a/pkg/stdlib/datetime/dayofyear.go +++ b/pkg/stdlib/datetime/dayofyear.go @@ -3,9 +3,9 @@ package datetime import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DateDayOfYear returns the day of year number of date. @@ -18,7 +18,7 @@ func DateDayOfYear(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.DateTimeType) + err = core.ValidateType(args[0], types.DateTime) if err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/daysinmonth.go b/pkg/stdlib/datetime/daysinmonth.go index 1a1f7429..ff4ed98e 100644 --- a/pkg/stdlib/datetime/daysinmonth.go +++ b/pkg/stdlib/datetime/daysinmonth.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) var daysCount = map[time.Month]int{ @@ -32,7 +33,7 @@ func DateDaysInMonth(_ context.Context, args ...core.Value) (core.Value, error) return values.None, err } - err = core.ValidateType(args[0], core.DateTimeType) + err = core.ValidateType(args[0], types.DateTime) if err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/diff.go b/pkg/stdlib/datetime/diff.go index d40bd8e4..ee41a0cb 100644 --- a/pkg/stdlib/datetime/diff.go +++ b/pkg/stdlib/datetime/diff.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DateDiff returns the difference between two dates in given time unit. @@ -34,7 +35,7 @@ func DateDiff(_ context.Context, args ...core.Value) (core.Value, error) { isFloat := values.NewBoolean(false) if len(args) == 4 { - err = core.ValidateType(args[3], core.BooleanType) + err = core.ValidateType(args[3], types.Boolean) if err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/format.go b/pkg/stdlib/datetime/format.go index a54afe33..c23bc515 100644 --- a/pkg/stdlib/datetime/format.go +++ b/pkg/stdlib/datetime/format.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DateFormat format date according to the given format string. @@ -16,12 +17,12 @@ func DateFormat(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.DateTimeType) + err = core.ValidateType(args[0], types.DateTime) if err != nil { return values.None, err } - err = core.ValidateType(args[1], core.StringType) + err = core.ValidateType(args[1], types.String) if err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/helpers_test.go b/pkg/stdlib/datetime/helpers_test.go index e69fd124..fcf45a20 100644 --- a/pkg/stdlib/datetime/helpers_test.go +++ b/pkg/stdlib/datetime/helpers_test.go @@ -31,24 +31,28 @@ func (tc *testCase) Do(t *testing.T, fn core.Function) { So(err, ShouldBeNil) } - So(actual.Type(), ShouldEqual, expected.Type()) + So(actual.Type().Equals(expected.Type()), ShouldBeTrue) So(actual.Compare(expected), ShouldEqual, 0) }) } func mustDefaultLayoutDt(timeString string) values.DateTime { dt, err := defaultLayoutDt(timeString) + if err != nil { panic(err) } + return dt } func mustLayoutDt(layout, value string) values.DateTime { dt, err := layoutDt(layout, value) + if err != nil { panic(err) } + return dt } @@ -58,8 +62,10 @@ func defaultLayoutDt(timeString string) (values.DateTime, error) { func layoutDt(layout, value string) (values.DateTime, error) { t, err := time.Parse(layout, value) + if err != nil { return values.DateTime{}, err } + return values.NewDateTime(t), nil } diff --git a/pkg/stdlib/datetime/hour.go b/pkg/stdlib/datetime/hour.go index bb56e924..a6d48f2f 100644 --- a/pkg/stdlib/datetime/hour.go +++ b/pkg/stdlib/datetime/hour.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DateHour returns the hour of date as a number. @@ -16,7 +17,7 @@ func DateHour(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.DateTimeType) + err = core.ValidateType(args[0], types.DateTime) if err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/leapyear.go b/pkg/stdlib/datetime/leapyear.go index 0bca5a24..3788c23f 100644 --- a/pkg/stdlib/datetime/leapyear.go +++ b/pkg/stdlib/datetime/leapyear.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DateLeapYear returns true if date is in a leap year else false. @@ -16,7 +17,7 @@ func DateLeapYear(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.DateTimeType) + err = core.ValidateType(args[0], types.DateTime) if err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/millisecond.go b/pkg/stdlib/datetime/millisecond.go index 78aa679c..187f175a 100644 --- a/pkg/stdlib/datetime/millisecond.go +++ b/pkg/stdlib/datetime/millisecond.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DateMillisecond returns the millisecond of date as a number. @@ -16,7 +17,7 @@ func DateMillisecond(_ context.Context, args ...core.Value) (core.Value, error) return values.None, err } - err = core.ValidateType(args[0], core.DateTimeType) + err = core.ValidateType(args[0], types.DateTime) if err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/minute.go b/pkg/stdlib/datetime/minute.go index c5f9fe5f..e3118e7b 100644 --- a/pkg/stdlib/datetime/minute.go +++ b/pkg/stdlib/datetime/minute.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DateMinute returns the minute of date as a number. @@ -16,7 +17,7 @@ func DateMinute(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.DateTimeType) + err = core.ValidateType(args[0], types.DateTime) if err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/month.go b/pkg/stdlib/datetime/month.go index 3633a87f..38193e0a 100644 --- a/pkg/stdlib/datetime/month.go +++ b/pkg/stdlib/datetime/month.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DateMonth returns the month of date as a number. @@ -16,7 +17,7 @@ func DateMonth(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.DateTimeType) + err = core.ValidateType(args[0], types.DateTime) if err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/quarter.go b/pkg/stdlib/datetime/quarter.go index 9d3fa520..5cdf6968 100644 --- a/pkg/stdlib/datetime/quarter.go +++ b/pkg/stdlib/datetime/quarter.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DateQuarter returns which quarter date belongs to. @@ -17,7 +18,7 @@ func DateQuarter(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.DateTimeType) + err = core.ValidateType(args[0], types.DateTime) if err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/second.go b/pkg/stdlib/datetime/second.go index ca3e2d18..ba8d7773 100644 --- a/pkg/stdlib/datetime/second.go +++ b/pkg/stdlib/datetime/second.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DateSecond returns the second of date as a number. @@ -16,7 +17,7 @@ func DateSecond(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.DateTimeType) + err = core.ValidateType(args[0], types.DateTime) if err != nil { return values.None, err } diff --git a/pkg/stdlib/datetime/year.go b/pkg/stdlib/datetime/year.go index 41b66dc6..0bd592a2 100644 --- a/pkg/stdlib/datetime/year.go +++ b/pkg/stdlib/datetime/year.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // DateYear returns the year extracted from the given date. @@ -16,7 +17,7 @@ func DateYear(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.DateTimeType) + err = core.ValidateType(args[0], types.DateTime) if err != nil { return values.None, err } diff --git a/pkg/stdlib/html/click.go b/pkg/stdlib/html/click.go index eb976bd5..eb5f162a 100644 --- a/pkg/stdlib/html/click.go +++ b/pkg/stdlib/html/click.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Click dispatches click event on a given element @@ -21,7 +22,7 @@ func Click(_ context.Context, args ...core.Value) (core.Value, error) { if len(args) == 1 { arg1 := args[0] - err := core.ValidateType(arg1, core.HTMLElementType) + err := core.ValidateType(arg1, types.HTMLElement) if err != nil { return values.False, err @@ -40,7 +41,7 @@ func Click(_ context.Context, args ...core.Value) (core.Value, error) { arg1 := args[0] selector := args[1].String() - err = core.ValidateType(arg1, core.HTMLDocumentType) + err = core.ValidateType(arg1, types.HTMLDocument) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/click_all.go b/pkg/stdlib/html/click_all.go index 80b2c668..c44c7d6c 100644 --- a/pkg/stdlib/html/click_all.go +++ b/pkg/stdlib/html/click_all.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // ClickAll dispatches click event on all matched element @@ -21,7 +22,7 @@ func ClickAll(_ context.Context, args ...core.Value) (core.Value, error) { arg1 := args[0] selector := args[1].String() - err = core.ValidateType(arg1, core.HTMLDocumentType) + err = core.ValidateType(arg1, types.HTMLDocument) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/document.go b/pkg/stdlib/html/document.go index 97980d0f..fa41c313 100644 --- a/pkg/stdlib/html/document.go +++ b/pkg/stdlib/html/document.go @@ -2,10 +2,12 @@ package html import ( "context" + "time" + "github.com/MontFerret/ferret/pkg/drivers" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "time" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) type DocumentLoadParams struct { @@ -29,7 +31,7 @@ func Document(ctx context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.StringType) + err = core.ValidateType(args[0], types.String) if err != nil { return values.None, err @@ -83,11 +85,11 @@ func newDefaultDocLoadParams() DocumentLoadParams { func newDocLoadParams(arg core.Value) (DocumentLoadParams, error) { res := newDefaultDocLoadParams() - if err := core.ValidateType(arg, core.BooleanType, core.ObjectType); err != nil { + if err := core.ValidateType(arg, types.Boolean, types.Object); err != nil { return res, err } - if arg.Type() == core.BooleanType { + if arg.Type() == types.Boolean { res.Dynamic = arg.(values.Boolean) return res, nil @@ -98,7 +100,7 @@ func newDocLoadParams(arg core.Value) (DocumentLoadParams, error) { isDynamic, exists := obj.Get(values.NewString("dynamic")) if exists { - if err := core.ValidateType(isDynamic, core.BooleanType); err != nil { + if err := core.ValidateType(isDynamic, types.Boolean); err != nil { return res, err } @@ -108,7 +110,7 @@ func newDocLoadParams(arg core.Value) (DocumentLoadParams, error) { timeout, exists := obj.Get(values.NewString("timeout")) if exists { - if err := core.ValidateType(timeout, core.IntType); err != nil { + if err := core.ValidateType(timeout, types.Int); err != nil { return res, err } diff --git a/pkg/stdlib/html/download.go b/pkg/stdlib/html/download.go index 0a991f55..fbc4094f 100644 --- a/pkg/stdlib/html/download.go +++ b/pkg/stdlib/html/download.go @@ -7,6 +7,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Download a resource from the given URL. @@ -20,7 +21,7 @@ func Download(_ context.Context, args ...core.Value) (core.Value, error) { } arg1 := args[0] - err = core.ValidateType(arg1, core.StringType) + err = core.ValidateType(arg1, types.String) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/element.go b/pkg/stdlib/html/element.go index e548609f..85919b63 100644 --- a/pkg/stdlib/html/element.go +++ b/pkg/stdlib/html/element.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Element finds an element by a given CSS selector. @@ -29,13 +30,13 @@ func queryArgs(args []core.Value) (values.HTMLNode, values.String, error) { return nil, values.EmptyString, err } - err = core.ValidateType(args[0], core.HTMLDocumentType, core.HTMLElementType) + err = core.ValidateType(args[0], types.HTMLDocument, types.HTMLElement) if err != nil { return nil, values.EmptyString, err } - err = core.ValidateType(args[1], core.StringType) + err = core.ValidateType(args[1], types.String) if err != nil { return nil, values.EmptyString, err diff --git a/pkg/stdlib/html/hover.go b/pkg/stdlib/html/hover.go index 23a387f4..768a812b 100644 --- a/pkg/stdlib/html/hover.go +++ b/pkg/stdlib/html/hover.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Hover fetches an element with selector, scrolls it into view if needed, and then uses page.mouse to hover over the center of the element. @@ -19,14 +20,14 @@ func Hover(_ context.Context, args ...core.Value) (core.Value, error) { } // document or element - err = core.ValidateType(args[0], core.HTMLDocumentType, core.HTMLElementType) + err = core.ValidateType(args[0], types.HTMLDocument, types.HTMLElement) if err != nil { return values.None, err } if len(args) == 2 { - err = core.ValidateType(args[1], core.StringType) + err = core.ValidateType(args[1], types.String) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/inner_html.go b/pkg/stdlib/html/inner_html.go index c3b431f2..3fdac78c 100644 --- a/pkg/stdlib/html/inner_html.go +++ b/pkg/stdlib/html/inner_html.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // InnerHTML Returns inner HTML string of a given or matched by CSS selector element @@ -18,7 +19,7 @@ func InnerHTML(_ context.Context, args ...core.Value) (core.Value, error) { return values.EmptyString, err } - err = core.ValidateType(args[0], core.HTMLDocumentType, core.HTMLElementType) + err = core.ValidateType(args[0], types.HTMLDocument, types.HTMLElement) if err != nil { return values.None, err @@ -30,7 +31,7 @@ func InnerHTML(_ context.Context, args ...core.Value) (core.Value, error) { return node.InnerHTML(), nil } - err = core.ValidateType(args[1], core.StringType) + err = core.ValidateType(args[1], types.String) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/inner_html_all.go b/pkg/stdlib/html/inner_html_all.go index 11ccaf28..d0f520d2 100644 --- a/pkg/stdlib/html/inner_html_all.go +++ b/pkg/stdlib/html/inner_html_all.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // InnerHTMLAll returns an array of inner HTML strings of matched elements. @@ -18,13 +19,13 @@ func InnerHTMLAll(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.HTMLDocumentType, core.HTMLElementType) + err = core.ValidateType(args[0], types.HTMLDocument, types.HTMLElement) if err != nil { return values.None, err } - err = core.ValidateType(args[1], core.StringType) + err = core.ValidateType(args[1], types.String) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/inner_text.go b/pkg/stdlib/html/inner_text.go index 7ec76963..8994e1f1 100644 --- a/pkg/stdlib/html/inner_text.go +++ b/pkg/stdlib/html/inner_text.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // InnerText returns inner text string of a given or matched by CSS selector element @@ -18,7 +19,7 @@ func InnerText(_ context.Context, args ...core.Value) (core.Value, error) { return values.EmptyString, err } - err = core.ValidateType(args[0], core.HTMLDocumentType, core.HTMLElementType) + err = core.ValidateType(args[0], types.HTMLDocument, types.HTMLElement) if err != nil { return values.None, err @@ -30,7 +31,7 @@ func InnerText(_ context.Context, args ...core.Value) (core.Value, error) { return node.InnerText(), nil } - err = core.ValidateType(args[1], core.StringType) + err = core.ValidateType(args[1], types.String) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/inner_text_all.go b/pkg/stdlib/html/inner_text_all.go index 2d8bea91..cd4ea6f3 100644 --- a/pkg/stdlib/html/inner_text_all.go +++ b/pkg/stdlib/html/inner_text_all.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // InnerTextAll returns an array of inner text of matched elements. @@ -18,13 +19,13 @@ func InnerTextAll(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.HTMLDocumentType, core.HTMLElementType) + err = core.ValidateType(args[0], types.HTMLDocument, types.HTMLElement) if err != nil { return values.None, err } - err = core.ValidateType(args[1], core.StringType) + err = core.ValidateType(args[1], types.String) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/input.go b/pkg/stdlib/html/input.go index fb0b2a63..87d79af9 100644 --- a/pkg/stdlib/html/input.go +++ b/pkg/stdlib/html/input.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Input types a value to an underlying input element. @@ -21,7 +22,7 @@ func Input(_ context.Context, args ...core.Value) (core.Value, error) { } arg1 := args[0] - err = core.ValidateType(arg1, core.HTMLDocumentType, core.HTMLElementType) + err = core.ValidateType(arg1, types.HTMLDocument, types.HTMLElement) if err != nil { return values.False, err @@ -37,7 +38,7 @@ func Input(_ context.Context, args ...core.Value) (core.Value, error) { // selector arg2 := args[1] - err = core.ValidateType(arg2, core.StringType) + err = core.ValidateType(arg2, types.String) if err != nil { return values.False, err @@ -48,7 +49,7 @@ func Input(_ context.Context, args ...core.Value) (core.Value, error) { if len(args) == 4 { arg4 := args[3] - err = core.ValidateType(arg4, core.IntType) + err = core.ValidateType(arg4, types.Int) if err != nil { return values.False, err @@ -70,7 +71,7 @@ func Input(_ context.Context, args ...core.Value) (core.Value, error) { if len(args) == 3 { arg3 := args[2] - err = core.ValidateType(arg3, core.IntType) + err = core.ValidateType(arg3, types.Int) if err != nil { return values.False, err diff --git a/pkg/stdlib/html/lib.go b/pkg/stdlib/html/lib.go index ab48da3e..260cb1e6 100644 --- a/pkg/stdlib/html/lib.go +++ b/pkg/stdlib/html/lib.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" "github.com/pkg/errors" ) @@ -49,7 +50,8 @@ func NewLib() map[string]core.Function { } func ValidateDocument(ctx context.Context, value core.Value) (core.Value, error) { - err := core.ValidateType(value, core.HTMLDocumentType, core.StringType) + err := core.ValidateType(value, types.HTMLDocument, types.String) + if err != nil { return values.None, err } @@ -57,7 +59,7 @@ func ValidateDocument(ctx context.Context, value core.Value) (core.Value, error) var doc values.DHTMLDocument var ok bool - if value.Type() == core.StringType { + if value.Type() == types.String { buf, err := Document(ctx, value, values.NewBoolean(true)) if err != nil { diff --git a/pkg/stdlib/html/navigate.go b/pkg/stdlib/html/navigate.go index 1ab2b892..062e5976 100644 --- a/pkg/stdlib/html/navigate.go +++ b/pkg/stdlib/html/navigate.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Navigate navigates a document to a new resource. @@ -20,13 +21,13 @@ func Navigate(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.HTMLDocumentType) + err = core.ValidateType(args[0], types.HTMLDocument) if err != nil { return values.None, err } - err = core.ValidateType(args[1], core.StringType) + err = core.ValidateType(args[1], types.String) if err != nil { return values.None, err @@ -41,7 +42,7 @@ func Navigate(_ context.Context, args ...core.Value) (core.Value, error) { timeout := values.NewInt(defaultTimeout) if len(args) > 2 { - err = core.ValidateType(args[2], core.IntType) + err = core.ValidateType(args[2], types.Int) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/navigate_back.go b/pkg/stdlib/html/navigate_back.go index d67e59da..41b6a926 100644 --- a/pkg/stdlib/html/navigate_back.go +++ b/pkg/stdlib/html/navigate_back.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // NavigateBack navigates a document back within its navigation history. @@ -21,7 +22,7 @@ func NavigateBack(_ context.Context, args ...core.Value) (core.Value, error) { return values.False, err } - err = core.ValidateType(args[0], core.HTMLDocumentType) + err = core.ValidateType(args[0], types.HTMLDocument) if err != nil { return values.None, err @@ -37,7 +38,7 @@ func NavigateBack(_ context.Context, args ...core.Value) (core.Value, error) { timeout := values.NewInt(defaultTimeout) if len(args) > 1 { - err = core.ValidateType(args[1], core.IntType) + err = core.ValidateType(args[1], types.Int) if err != nil { return values.None, err @@ -47,7 +48,7 @@ func NavigateBack(_ context.Context, args ...core.Value) (core.Value, error) { } if len(args) > 2 { - err = core.ValidateType(args[2], core.IntType) + err = core.ValidateType(args[2], types.Int) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/navigate_forward.go b/pkg/stdlib/html/navigate_forward.go index 5c53f671..1925193a 100644 --- a/pkg/stdlib/html/navigate_forward.go +++ b/pkg/stdlib/html/navigate_forward.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // NavigateForward navigates a document forward within its navigation history. @@ -21,7 +22,7 @@ func NavigateForward(_ context.Context, args ...core.Value) (core.Value, error) return values.False, err } - err = core.ValidateType(args[0], core.HTMLDocumentType) + err = core.ValidateType(args[0], types.HTMLDocument) if err != nil { return values.None, err @@ -37,7 +38,7 @@ func NavigateForward(_ context.Context, args ...core.Value) (core.Value, error) timeout := values.NewInt(defaultTimeout) if len(args) > 1 { - err = core.ValidateType(args[1], core.IntType) + err = core.ValidateType(args[1], types.Int) if err != nil { return values.None, err @@ -47,7 +48,7 @@ func NavigateForward(_ context.Context, args ...core.Value) (core.Value, error) } if len(args) > 2 { - err = core.ValidateType(args[2], core.IntType) + err = core.ValidateType(args[2], types.Int) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/pagination.go b/pkg/stdlib/html/pagination.go index 44cbafce..77f60527 100644 --- a/pkg/stdlib/html/pagination.go +++ b/pkg/stdlib/html/pagination.go @@ -2,9 +2,11 @@ package html import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/collections" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Pagination creates an iterator that goes through pages using CSS selector. @@ -25,7 +27,7 @@ func Pagination(_ context.Context, args ...core.Value) (core.Value, error) { return values.False, core.Errors(core.ErrInvalidType, ErrNotDynamic) } - err = core.ValidateType(args[1], core.StringType) + err = core.ValidateType(args[1], types.String) if err != nil { return values.None, err @@ -36,6 +38,8 @@ func Pagination(_ context.Context, args ...core.Value) (core.Value, error) { return &Paging{doc, selector}, nil } +var PagingType = core.NewType("Paging") + type ( Paging struct { document values.DHTMLDocument @@ -54,14 +58,14 @@ func (p *Paging) MarshalJSON() ([]byte, error) { } func (p *Paging) Type() core.Type { - return core.CustomType + return PagingType } func (p *Paging) String() string { - return core.CustomType.String() + return PagingType.String() } -func (p *Paging) Compare(_ core.Value) int { +func (p *Paging) Compare(_ core.Value) int64 { return 1 } diff --git a/pkg/stdlib/html/parse.go b/pkg/stdlib/html/parse.go index d8828802..efadafe8 100644 --- a/pkg/stdlib/html/parse.go +++ b/pkg/stdlib/html/parse.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/drivers" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Parse parses a given HTML string and returns a HTML document. @@ -19,7 +20,7 @@ func Parse(ctx context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.StringType) + err = core.ValidateType(args[0], types.String) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/pdf.go b/pkg/stdlib/html/pdf.go index 1a8df97a..d651a9d7 100644 --- a/pkg/stdlib/html/pdf.go +++ b/pkg/stdlib/html/pdf.go @@ -7,6 +7,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) func ValidatePageRanges(pageRanges string) (bool, error) { @@ -59,7 +60,7 @@ func PDF(ctx context.Context, args ...core.Value) (core.Value, error) { if len(args) == 2 { arg2 := args[1] - err = core.ValidateType(arg2, core.ObjectType) + err = core.ValidateType(arg2, types.Object) if err != nil { return values.None, err @@ -74,7 +75,7 @@ func PDF(ctx context.Context, args ...core.Value) (core.Value, error) { landscape, found := params.Get("landscape") if found { - err = core.ValidateType(landscape, core.BooleanType) + err = core.ValidateType(landscape, types.Boolean) if err != nil { return values.None, err @@ -86,7 +87,7 @@ func PDF(ctx context.Context, args ...core.Value) (core.Value, error) { displayHeaderFooter, found := params.Get("displayHeaderFooter") if found { - err = core.ValidateType(displayHeaderFooter, core.BooleanType) + err = core.ValidateType(displayHeaderFooter, types.Boolean) if err != nil { return values.None, err @@ -98,7 +99,7 @@ func PDF(ctx context.Context, args ...core.Value) (core.Value, error) { printBackground, found := params.Get("printBackground") if found { - err = core.ValidateType(printBackground, core.BooleanType) + err = core.ValidateType(printBackground, types.Boolean) if err != nil { return values.None, err @@ -110,13 +111,13 @@ func PDF(ctx context.Context, args ...core.Value) (core.Value, error) { scale, found := params.Get("scale") if found { - err = core.ValidateType(scale, core.FloatType, core.IntType) + err = core.ValidateType(scale, types.Float, types.Int) if err != nil { return values.None, err } - if scale.Type() == core.IntType { + if scale.Type() == types.Int { pdfParams.Scale = values.Float(scale.(values.Int)) } else { pdfParams.Scale = scale.(values.Float) @@ -126,13 +127,13 @@ func PDF(ctx context.Context, args ...core.Value) (core.Value, error) { paperWidth, found := params.Get("paperWidth") if found { - err = core.ValidateType(paperWidth, core.FloatType, core.IntType) + err = core.ValidateType(paperWidth, types.Float, types.Int) if err != nil { return values.None, err } - if paperWidth.Type() == core.IntType { + if paperWidth.Type() == types.Int { pdfParams.PaperWidth = values.Float(paperWidth.(values.Int)) } else { pdfParams.PaperWidth = paperWidth.(values.Float) @@ -142,13 +143,13 @@ func PDF(ctx context.Context, args ...core.Value) (core.Value, error) { paperHeight, found := params.Get("paperHeight") if found { - err = core.ValidateType(paperHeight, core.FloatType, core.IntType) + err = core.ValidateType(paperHeight, types.Float, types.Int) if err != nil { return values.None, err } - if paperHeight.Type() == core.IntType { + if paperHeight.Type() == types.Int { pdfParams.PaperHeight = values.Float(paperHeight.(values.Int)) } else { pdfParams.PaperHeight = paperHeight.(values.Float) @@ -158,13 +159,13 @@ func PDF(ctx context.Context, args ...core.Value) (core.Value, error) { marginTop, found := params.Get("marginTop") if found { - err = core.ValidateType(marginTop, core.FloatType, core.IntType) + err = core.ValidateType(marginTop, types.Float, types.Int) if err != nil { return values.None, err } - if marginTop.Type() == core.IntType { + if marginTop.Type() == types.Int { pdfParams.MarginTop = values.Float(marginTop.(values.Int)) } else { pdfParams.MarginTop = marginTop.(values.Float) @@ -174,13 +175,13 @@ func PDF(ctx context.Context, args ...core.Value) (core.Value, error) { marginBottom, found := params.Get("marginBottom") if found { - err = core.ValidateType(marginBottom, core.FloatType, core.IntType) + err = core.ValidateType(marginBottom, types.Float, types.Int) if err != nil { return values.None, err } - if marginBottom.Type() == core.IntType { + if marginBottom.Type() == types.Int { pdfParams.MarginBottom = values.Float(marginBottom.(values.Int)) } else { pdfParams.MarginBottom = marginBottom.(values.Float) @@ -190,13 +191,13 @@ func PDF(ctx context.Context, args ...core.Value) (core.Value, error) { marginLeft, found := params.Get("marginLeft") if found { - err = core.ValidateType(marginLeft, core.FloatType, core.IntType) + err = core.ValidateType(marginLeft, types.Float, types.Int) if err != nil { return values.None, err } - if marginLeft.Type() == core.IntType { + if marginLeft.Type() == types.Int { pdfParams.MarginLeft = values.Float(marginLeft.(values.Int)) } else { pdfParams.MarginLeft = marginLeft.(values.Float) @@ -206,13 +207,13 @@ func PDF(ctx context.Context, args ...core.Value) (core.Value, error) { marginRight, found := params.Get("marginRight") if found { - err = core.ValidateType(marginRight, core.FloatType, core.IntType) + err = core.ValidateType(marginRight, types.Float, types.Int) if err != nil { return values.None, err } - if marginRight.Type() == core.IntType { + if marginRight.Type() == types.Int { pdfParams.MarginRight = values.Float(marginRight.(values.Int)) } else { pdfParams.MarginRight = marginRight.(values.Float) @@ -222,7 +223,7 @@ func PDF(ctx context.Context, args ...core.Value) (core.Value, error) { pageRanges, found := params.Get("pageRanges") if found { - err = core.ValidateType(pageRanges, core.StringType) + err = core.ValidateType(pageRanges, types.String) if err != nil { return values.None, err @@ -244,7 +245,7 @@ func PDF(ctx context.Context, args ...core.Value) (core.Value, error) { ignoreInvalidPageRanges, found := params.Get("ignoreInvalidPageRanges") if found { - err = core.ValidateType(ignoreInvalidPageRanges, core.BooleanType) + err = core.ValidateType(ignoreInvalidPageRanges, types.Boolean) if err != nil { return values.None, err @@ -256,7 +257,7 @@ func PDF(ctx context.Context, args ...core.Value) (core.Value, error) { headerTemplate, found := params.Get("headerTemplate") if found { - err = core.ValidateType(headerTemplate, core.StringType) + err = core.ValidateType(headerTemplate, types.String) if err != nil { return values.None, err @@ -268,7 +269,7 @@ func PDF(ctx context.Context, args ...core.Value) (core.Value, error) { footerTemplate, found := params.Get("footerTemplate") if found { - err = core.ValidateType(footerTemplate, core.StringType) + err = core.ValidateType(footerTemplate, types.String) if err != nil { return values.None, err @@ -280,7 +281,7 @@ func PDF(ctx context.Context, args ...core.Value) (core.Value, error) { preferCSSPageSize, found := params.Get("preferCSSPageSize") if found { - err = core.ValidateType(preferCSSPageSize, core.BooleanType) + err = core.ValidateType(preferCSSPageSize, types.Boolean) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/screenshot.go b/pkg/stdlib/html/screenshot.go index 7ae8add2..8dd01830 100644 --- a/pkg/stdlib/html/screenshot.go +++ b/pkg/stdlib/html/screenshot.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Screenshot takes a screenshot of the current page. @@ -27,7 +28,7 @@ func Screenshot(ctx context.Context, args ...core.Value) (core.Value, error) { arg1 := args[0] - err = core.ValidateType(arg1, core.HTMLDocumentType, core.StringType) + err = core.ValidateType(arg1, types.HTMLDocument, types.String) if err != nil { return values.None, err @@ -54,7 +55,7 @@ func Screenshot(ctx context.Context, args ...core.Value) (core.Value, error) { if len(args) == 2 { arg2 := args[1] - err = core.ValidateType(arg2, core.ObjectType) + err = core.ValidateType(arg2, types.Object) if err != nil { return values.None, err @@ -69,7 +70,7 @@ func Screenshot(ctx context.Context, args ...core.Value) (core.Value, error) { format, found := params.Get("format") if found { - err = core.ValidateType(format, core.StringType) + err = core.ValidateType(format, types.String) if err != nil { return values.None, err @@ -87,13 +88,13 @@ func Screenshot(ctx context.Context, args ...core.Value) (core.Value, error) { x, found := params.Get("x") if found { - err = core.ValidateType(x, core.FloatType, core.IntType) + err = core.ValidateType(x, types.Float, types.Int) if err != nil { return values.None, err } - if x.Type() == core.IntType { + if x.Type() == types.Int { screenshotParams.X = values.Float(x.(values.Int)) } } @@ -101,13 +102,13 @@ func Screenshot(ctx context.Context, args ...core.Value) (core.Value, error) { y, found := params.Get("y") if found { - err = core.ValidateType(y, core.FloatType, core.IntType) + err = core.ValidateType(y, types.Float, types.Int) if err != nil { return values.None, err } - if y.Type() == core.IntType { + if y.Type() == types.Int { screenshotParams.Y = values.Float(y.(values.Int)) } } @@ -115,13 +116,13 @@ func Screenshot(ctx context.Context, args ...core.Value) (core.Value, error) { width, found := params.Get("width") if found { - err = core.ValidateType(width, core.FloatType, core.IntType) + err = core.ValidateType(width, types.Float, types.Int) if err != nil { return values.None, err } - if width.Type() == core.IntType { + if width.Type() == types.Int { screenshotParams.Width = values.Float(width.(values.Int)) } } @@ -129,13 +130,13 @@ func Screenshot(ctx context.Context, args ...core.Value) (core.Value, error) { height, found := params.Get("height") if found { - err = core.ValidateType(height, core.FloatType, core.IntType) + err = core.ValidateType(height, types.Float, types.Int) if err != nil { return values.None, err } - if height.Type() == core.IntType { + if height.Type() == types.Int { screenshotParams.Height = values.Float(height.(values.Int)) } } @@ -143,7 +144,7 @@ func Screenshot(ctx context.Context, args ...core.Value) (core.Value, error) { quality, found := params.Get("quality") if found { - err = core.ValidateType(quality, core.IntType) + err = core.ValidateType(quality, types.Int) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/scroll_bottom.go b/pkg/stdlib/html/scroll_bottom.go index 76721b0a..7109410e 100644 --- a/pkg/stdlib/html/scroll_bottom.go +++ b/pkg/stdlib/html/scroll_bottom.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // ScrollTop scrolls the document's window to its bottom. @@ -16,7 +17,7 @@ func ScrollBottom(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.HTMLDocumentType) + err = core.ValidateType(args[0], types.HTMLDocument) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/scroll_element.go b/pkg/stdlib/html/scroll_element.go index 44e460d0..d863ff89 100644 --- a/pkg/stdlib/html/scroll_element.go +++ b/pkg/stdlib/html/scroll_element.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // ScrollInto scrolls an element on. @@ -18,14 +19,14 @@ func ScrollInto(_ context.Context, args ...core.Value) (core.Value, error) { } // document or element - err = core.ValidateType(args[0], core.HTMLDocumentType, core.HTMLElementType) + err = core.ValidateType(args[0], types.HTMLDocument, types.HTMLElement) if err != nil { return values.None, err } if len(args) == 2 { - err = core.ValidateType(args[1], core.StringType) + err = core.ValidateType(args[1], types.String) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/scroll_top.go b/pkg/stdlib/html/scroll_top.go index d06eb6f6..c153eab2 100644 --- a/pkg/stdlib/html/scroll_top.go +++ b/pkg/stdlib/html/scroll_top.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // ScrollTop scrolls the document's window to its top. @@ -16,7 +17,7 @@ func ScrollTop(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.HTMLDocumentType) + err = core.ValidateType(args[0], types.HTMLDocument) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/select.go b/pkg/stdlib/html/select.go index a4db6444..c682e58d 100644 --- a/pkg/stdlib/html/select.go +++ b/pkg/stdlib/html/select.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Select selects a value from an underlying select element. @@ -20,7 +21,7 @@ func Select(_ context.Context, args ...core.Value) (core.Value, error) { } arg1 := args[0] - err = core.ValidateType(arg1, core.HTMLDocumentType, core.HTMLElementType) + err = core.ValidateType(arg1, types.HTMLDocument, types.HTMLElement) if err != nil { return values.False, err @@ -36,14 +37,14 @@ func Select(_ context.Context, args ...core.Value) (core.Value, error) { // selector arg2 := args[1] - err = core.ValidateType(arg2, core.StringType) + err = core.ValidateType(arg2, types.String) if err != nil { return values.False, err } arg3 := args[2] - err = core.ValidateType(arg3, core.ArrayType) + err = core.ValidateType(arg3, types.Array) if err != nil { return values.False, err @@ -59,7 +60,7 @@ func Select(_ context.Context, args ...core.Value) (core.Value, error) { arg2 := args[1] - err = core.ValidateType(arg2, core.ArrayType) + err = core.ValidateType(arg2, types.Array) if err != nil { return values.False, err diff --git a/pkg/stdlib/html/wait_class.go b/pkg/stdlib/html/wait_class.go index 8ff829b6..f2640091 100644 --- a/pkg/stdlib/html/wait_class.go +++ b/pkg/stdlib/html/wait_class.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // WaitClass waits for a class to appear on a given element. @@ -24,14 +25,14 @@ func WaitClass(_ context.Context, args ...core.Value) (core.Value, error) { } // document or element - err = core.ValidateType(args[0], core.HTMLDocumentType, core.HTMLElementType) + err = core.ValidateType(args[0], types.HTMLDocument, types.HTMLElement) if err != nil { return values.None, err } // selector or class - err = core.ValidateType(args[1], core.StringType) + err = core.ValidateType(args[1], types.String) if err != nil { return values.None, err @@ -50,7 +51,7 @@ func WaitClass(_ context.Context, args ...core.Value) (core.Value, error) { } // class - err = core.ValidateType(args[2], core.StringType) + err = core.ValidateType(args[2], types.String) if err != nil { return values.None, err @@ -66,7 +67,7 @@ func WaitClass(_ context.Context, args ...core.Value) (core.Value, error) { class := args[2].(values.String) if len(args) == 4 { - err = core.ValidateType(args[3], core.IntType) + err = core.ValidateType(args[3], types.Int) if err != nil { return values.None, err @@ -86,7 +87,7 @@ func WaitClass(_ context.Context, args ...core.Value) (core.Value, error) { class := args[1].(values.String) if len(args) == 3 { - err = core.ValidateType(args[2], core.IntType) + err = core.ValidateType(args[2], types.Int) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/wait_class_all.go b/pkg/stdlib/html/wait_class_all.go index 8b86edb3..bce44df7 100644 --- a/pkg/stdlib/html/wait_class_all.go +++ b/pkg/stdlib/html/wait_class_all.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // WaitClassAll waits for a class to appear on all matched elements. @@ -21,21 +22,21 @@ func WaitClassAll(_ context.Context, args ...core.Value) (core.Value, error) { } // document only - err = core.ValidateType(args[0], core.HTMLDocumentType) + err = core.ValidateType(args[0], types.HTMLDocument) if err != nil { return values.None, err } // selector - err = core.ValidateType(args[1], core.StringType) + err = core.ValidateType(args[1], types.String) if err != nil { return values.None, err } // class - err = core.ValidateType(args[2], core.StringType) + err = core.ValidateType(args[2], types.String) if err != nil { return values.None, err @@ -52,7 +53,7 @@ func WaitClassAll(_ context.Context, args ...core.Value) (core.Value, error) { timeout := values.NewInt(defaultTimeout) if len(args) == 4 { - err = core.ValidateType(args[3], core.IntType) + err = core.ValidateType(args[3], types.Int) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/wait_element.go b/pkg/stdlib/html/wait_element.go index e84a11ae..05b85525 100644 --- a/pkg/stdlib/html/wait_element.go +++ b/pkg/stdlib/html/wait_element.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // WaitElement waits for element to appear in the DOM. @@ -24,7 +25,7 @@ func WaitElement(_ context.Context, args ...core.Value) (core.Value, error) { timeout := values.NewInt(defaultTimeout) if len(args) > 2 { - err = core.ValidateType(args[2], core.IntType) + err = core.ValidateType(args[2], types.Int) if err != nil { return values.None, err @@ -33,7 +34,7 @@ func WaitElement(_ context.Context, args ...core.Value) (core.Value, error) { timeout = args[2].(values.Int) } - err = core.ValidateType(arg, core.HTMLDocumentType) + err = core.ValidateType(arg, types.HTMLDocument) if err != nil { return values.None, err diff --git a/pkg/stdlib/html/wait_navigation.go b/pkg/stdlib/html/wait_navigation.go index 55389a7b..b70c7b06 100644 --- a/pkg/stdlib/html/wait_navigation.go +++ b/pkg/stdlib/html/wait_navigation.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // WaitNavigation waits for document to navigate to a new url. @@ -18,7 +19,7 @@ func WaitNavigation(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.HTMLDocumentType) + err = core.ValidateType(args[0], types.HTMLDocument) if err != nil { return values.None, err @@ -33,7 +34,7 @@ func WaitNavigation(_ context.Context, args ...core.Value) (core.Value, error) { timeout := values.NewInt(defaultTimeout) if len(args) > 1 { - err = core.ValidateType(args[1], core.IntType) + err = core.ValidateType(args[1], types.Int) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/abs.go b/pkg/stdlib/math/abs.go index fda5d74c..f886e327 100644 --- a/pkg/stdlib/math/abs.go +++ b/pkg/stdlib/math/abs.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Abs returns the absolute value of a given number. @@ -18,7 +19,7 @@ func Abs(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/acos.go b/pkg/stdlib/math/acos.go index 30d2deb2..e0884391 100644 --- a/pkg/stdlib/math/acos.go +++ b/pkg/stdlib/math/acos.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Acos returns the arccosine, in radians, of a given number. @@ -18,7 +19,7 @@ func Acos(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/asin.go b/pkg/stdlib/math/asin.go index 5498f5ba..a98153de 100644 --- a/pkg/stdlib/math/asin.go +++ b/pkg/stdlib/math/asin.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Asin returns the arcsine, in radians, of a given number. @@ -18,7 +19,7 @@ func Asin(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/atan.go b/pkg/stdlib/math/atan.go index 6db5ad73..edf222c5 100644 --- a/pkg/stdlib/math/atan.go +++ b/pkg/stdlib/math/atan.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Atan returns the arctangent, in radians, of a given number. @@ -18,7 +19,7 @@ func Atan(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/atan2.go b/pkg/stdlib/math/atan2.go index 5475ae4f..348a9a46 100644 --- a/pkg/stdlib/math/atan2.go +++ b/pkg/stdlib/math/atan2.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Atan2 returns the arc tangent of y/x, using the signs of the two to determine the quadrant of the return value. @@ -19,13 +20,13 @@ func Atan2(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err } - err = core.ValidateType(args[1], core.IntType, core.FloatType) + err = core.ValidateType(args[1], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/average.go b/pkg/stdlib/math/average.go index 2034bdd8..d8584596 100644 --- a/pkg/stdlib/math/average.go +++ b/pkg/stdlib/math/average.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Average Returns the average (arithmetic mean) of the values in array. @@ -18,7 +19,7 @@ func Average(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err @@ -33,7 +34,7 @@ func Average(_ context.Context, args ...core.Value) (core.Value, error) { var sum float64 arr.ForEach(func(value core.Value, idx int) bool { - err = core.ValidateType(value, core.FloatType, core.IntType) + err = core.ValidateType(value, types.Float, types.Int) if err != nil { return false diff --git a/pkg/stdlib/math/ceil.go b/pkg/stdlib/math/ceil.go index 3d0cac0a..0370cece 100644 --- a/pkg/stdlib/math/ceil.go +++ b/pkg/stdlib/math/ceil.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Ceil returns the least integer value greater than or equal to a given value. @@ -18,7 +19,7 @@ func Ceil(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/cos.go b/pkg/stdlib/math/cos.go index 1f000aa0..e8471464 100644 --- a/pkg/stdlib/math/cos.go +++ b/pkg/stdlib/math/cos.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Cos returns the cosine of a given number. @@ -18,7 +19,7 @@ func Cos(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/degrees.go b/pkg/stdlib/math/degrees.go index 99debe6d..330aa90b 100644 --- a/pkg/stdlib/math/degrees.go +++ b/pkg/stdlib/math/degrees.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Degrees returns the angle converted from radians to degrees. @@ -17,7 +18,7 @@ func Degrees(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/exp.go b/pkg/stdlib/math/exp.go index fac9a05a..43999270 100644 --- a/pkg/stdlib/math/exp.go +++ b/pkg/stdlib/math/exp.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Exp returns Euler's constant (2.71828...) raised to the power of value. @@ -18,7 +19,7 @@ func Exp(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/exp2.go b/pkg/stdlib/math/exp2.go index 85fff327..6fec8de6 100644 --- a/pkg/stdlib/math/exp2.go +++ b/pkg/stdlib/math/exp2.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Exp2 returns 2 raised to the power of value. @@ -18,7 +19,7 @@ func Exp2(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/floor.go b/pkg/stdlib/math/floor.go index 28dc34e9..f821c758 100644 --- a/pkg/stdlib/math/floor.go +++ b/pkg/stdlib/math/floor.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Floor returns the greatest integer value less than or equal to a given value. @@ -18,7 +19,7 @@ func Floor(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/lib.go b/pkg/stdlib/math/lib.go index 1302c4b6..f67d0d9f 100644 --- a/pkg/stdlib/math/lib.go +++ b/pkg/stdlib/math/lib.go @@ -1,9 +1,11 @@ package math import ( + "math" + "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "math" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) const ( @@ -52,7 +54,7 @@ func NewLib() map[string]core.Function { } func toFloat(arg core.Value) float64 { - if arg.Type() == core.IntType { + if arg.Type() == types.Int { return float64(arg.(values.Int)) } diff --git a/pkg/stdlib/math/log.go b/pkg/stdlib/math/log.go index c37bff77..5058717b 100644 --- a/pkg/stdlib/math/log.go +++ b/pkg/stdlib/math/log.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Log returns the natural logarithm of a given value. @@ -18,7 +19,7 @@ func Log(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/log10.go b/pkg/stdlib/math/log10.go index dba695df..f2ffc3b1 100644 --- a/pkg/stdlib/math/log10.go +++ b/pkg/stdlib/math/log10.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Log10 returns the decimal logarithm of a given value. @@ -18,7 +19,7 @@ func Log10(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/log2.go b/pkg/stdlib/math/log2.go index bdca6f14..3caa9f1c 100644 --- a/pkg/stdlib/math/log2.go +++ b/pkg/stdlib/math/log2.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Log2 returns the binary logarithm of a given value. @@ -18,7 +19,7 @@ func Log2(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/max.go b/pkg/stdlib/math/max.go index 77ed55a9..ba19c09c 100644 --- a/pkg/stdlib/math/max.go +++ b/pkg/stdlib/math/max.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Max returns the greatest (arithmetic mean) of the values in array. @@ -18,7 +19,7 @@ func Max(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err @@ -33,7 +34,7 @@ func Max(_ context.Context, args ...core.Value) (core.Value, error) { var max float64 arr.ForEach(func(value core.Value, idx int) bool { - err = core.ValidateType(value, core.FloatType, core.IntType) + err = core.ValidateType(value, types.Int, types.Float) if err != nil { return false diff --git a/pkg/stdlib/math/mean.go b/pkg/stdlib/math/mean.go index 9418a5b9..b24f9311 100644 --- a/pkg/stdlib/math/mean.go +++ b/pkg/stdlib/math/mean.go @@ -1,9 +1,11 @@ package math import ( + "math" + "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "math" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) func mean(input *values.Array) (values.Float, error) { @@ -15,7 +17,7 @@ func mean(input *values.Array) (values.Float, error) { var sum float64 input.ForEach(func(value core.Value, idx int) bool { - err = core.ValidateType(value, core.FloatType, core.IntType) + err = core.ValidateType(value, types.Int, types.Float) if err != nil { return false diff --git a/pkg/stdlib/math/median.go b/pkg/stdlib/math/median.go index da2bb7f9..dcac91e2 100644 --- a/pkg/stdlib/math/median.go +++ b/pkg/stdlib/math/median.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Median returns the median of the values in array. @@ -19,7 +20,7 @@ func Median(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/min.go b/pkg/stdlib/math/min.go index ba3980c4..5546e69a 100644 --- a/pkg/stdlib/math/min.go +++ b/pkg/stdlib/math/min.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Min returns the smallest (arithmetic mean) of the values in array. @@ -18,7 +19,7 @@ func Min(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err @@ -33,7 +34,7 @@ func Min(_ context.Context, args ...core.Value) (core.Value, error) { var min float64 arr.ForEach(func(value core.Value, idx int) bool { - err = core.ValidateType(value, core.FloatType, core.IntType) + err = core.ValidateType(value, types.Int, types.Float) if err != nil { return false diff --git a/pkg/stdlib/math/percentile.go b/pkg/stdlib/math/percentile.go index 4b047bb9..04a15bc1 100644 --- a/pkg/stdlib/math/percentile.go +++ b/pkg/stdlib/math/percentile.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" "github.com/pkg/errors" ) @@ -21,13 +22,13 @@ func Percentile(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err } - err = core.ValidateType(args[1], core.IntType) + err = core.ValidateType(args[1], types.Int) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/pow.go b/pkg/stdlib/math/pow.go index 588daf5f..043c8922 100644 --- a/pkg/stdlib/math/pow.go +++ b/pkg/stdlib/math/pow.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Pow returns the base to the exponent value. @@ -19,13 +20,13 @@ func Pow(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err } - err = core.ValidateType(args[1], core.IntType, core.FloatType) + err = core.ValidateType(args[1], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/radians.go b/pkg/stdlib/math/radians.go index 058392a2..c56c57dc 100644 --- a/pkg/stdlib/math/radians.go +++ b/pkg/stdlib/math/radians.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Radians returns the angle converted from degrees to radians. @@ -17,7 +18,7 @@ func Radians(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/range.go b/pkg/stdlib/math/range.go index a895f53a..9f65c2fe 100644 --- a/pkg/stdlib/math/range.go +++ b/pkg/stdlib/math/range.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Range returns an array of numbers in the specified range, optionally with increments other than 1. @@ -18,13 +19,13 @@ func Range(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err } - err = core.ValidateType(args[1], core.IntType, core.FloatType) + err = core.ValidateType(args[1], types.Int, types.Float) if err != nil { return values.None, err @@ -33,7 +34,7 @@ func Range(_ context.Context, args ...core.Value) (core.Value, error) { var step float64 = 1 if len(args) > 2 { - err = core.ValidateType(args[2], core.IntType, core.FloatType) + err = core.ValidateType(args[2], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/round.go b/pkg/stdlib/math/round.go index b7bfbebb..5a6a6dd7 100644 --- a/pkg/stdlib/math/round.go +++ b/pkg/stdlib/math/round.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Round returns the nearest integer, rounding half away from zero. @@ -18,7 +19,7 @@ func Round(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/sin.go b/pkg/stdlib/math/sin.go index 577803fe..6fb74db2 100644 --- a/pkg/stdlib/math/sin.go +++ b/pkg/stdlib/math/sin.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Sin returns the sine of the radian argument. @@ -18,7 +19,7 @@ func Sin(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/sqrt.go b/pkg/stdlib/math/sqrt.go index f7bf3559..7762a7d3 100644 --- a/pkg/stdlib/math/sqrt.go +++ b/pkg/stdlib/math/sqrt.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Sqrt returns the square root of a given number. @@ -18,7 +19,7 @@ func Sqrt(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/stddev_population.go b/pkg/stdlib/math/stddev_population.go index 51904d5c..aef53fee 100644 --- a/pkg/stdlib/math/stddev_population.go +++ b/pkg/stdlib/math/stddev_population.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // StandardDeviationPopulation returns the population standard deviation of the values in a given array. @@ -19,7 +20,7 @@ func StandardDeviationPopulation(_ context.Context, args ...core.Value) (core.Va return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/stddev_sample.go b/pkg/stdlib/math/stddev_sample.go index 4436f241..1932cf1f 100644 --- a/pkg/stdlib/math/stddev_sample.go +++ b/pkg/stdlib/math/stddev_sample.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // StandardDeviationSample returns the sample standard deviation of the values in a given array. @@ -19,7 +20,7 @@ func StandardDeviationSample(_ context.Context, args ...core.Value) (core.Value, return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/sum.go b/pkg/stdlib/math/sum.go index 2df47a67..21ce645f 100644 --- a/pkg/stdlib/math/sum.go +++ b/pkg/stdlib/math/sum.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Sum returns the sum of the values in a given array. @@ -18,7 +19,7 @@ func Sum(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err @@ -33,7 +34,7 @@ func Sum(_ context.Context, args ...core.Value) (core.Value, error) { var sum float64 arr.ForEach(func(value core.Value, idx int) bool { - err = core.ValidateType(value, core.FloatType, core.IntType) + err = core.ValidateType(value, types.Int, types.Float) if err != nil { return false diff --git a/pkg/stdlib/math/tan.go b/pkg/stdlib/math/tan.go index e5e7258b..731a2c57 100644 --- a/pkg/stdlib/math/tan.go +++ b/pkg/stdlib/math/tan.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Tan returns the tangent of a given number. @@ -18,7 +19,7 @@ func Tan(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.IntType, core.FloatType) + err = core.ValidateType(args[0], types.Int, types.Float) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/variance.go b/pkg/stdlib/math/variance.go index 4016fe9b..74d80973 100644 --- a/pkg/stdlib/math/variance.go +++ b/pkg/stdlib/math/variance.go @@ -1,9 +1,11 @@ package math import ( + "math" + "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" - "math" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) func variance(input *values.Array, sample values.Int) (values.Float, error) { @@ -17,7 +19,7 @@ func variance(input *values.Array, sample values.Int) (values.Float, error) { var variance values.Float input.ForEach(func(value core.Value, idx int) bool { - err = core.ValidateType(value, core.IntType, core.FloatType) + err = core.ValidateType(value, types.Int, types.Float) if err != nil { return false diff --git a/pkg/stdlib/math/variance_population.go b/pkg/stdlib/math/variance_population.go index 5c60065d..01355bb8 100644 --- a/pkg/stdlib/math/variance_population.go +++ b/pkg/stdlib/math/variance_population.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // PopulationVariance returns the population variance of the values in a given array. @@ -19,7 +20,7 @@ func PopulationVariance(_ context.Context, args ...core.Value) (core.Value, erro return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err diff --git a/pkg/stdlib/math/variance_sample.go b/pkg/stdlib/math/variance_sample.go index e764df42..d7bcd93a 100644 --- a/pkg/stdlib/math/variance_sample.go +++ b/pkg/stdlib/math/variance_sample.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // SampleVariance returns the sample variance of the values in a given array. @@ -19,7 +20,7 @@ func SampleVariance(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ArrayType) + err = core.ValidateType(args[0], types.Array) if err != nil { return values.None, err diff --git a/pkg/stdlib/objects/has.go b/pkg/stdlib/objects/has.go index 39c09f34..5084a5b5 100644 --- a/pkg/stdlib/objects/has.go +++ b/pkg/stdlib/objects/has.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Has returns the value stored by the given key. @@ -17,13 +18,13 @@ func Has(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ObjectType) + err = core.ValidateType(args[0], types.Object) if err != nil { return values.None, err } - err = core.ValidateType(args[1], core.StringType) + err = core.ValidateType(args[1], types.String) if err != nil { return values.None, err diff --git a/pkg/stdlib/objects/keep_keys.go b/pkg/stdlib/objects/keep_keys.go index c39fc122..5d0f300f 100644 --- a/pkg/stdlib/objects/keep_keys.go +++ b/pkg/stdlib/objects/keep_keys.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // KeepKeys returns a new object with only given keys. @@ -18,7 +19,7 @@ func KeepKeys(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ObjectType) + err = core.ValidateType(args[0], types.Object) if err != nil { return values.None, err @@ -26,11 +27,11 @@ func KeepKeys(_ context.Context, args ...core.Value) (core.Value, error) { keys := values.NewArrayWith(args[1:]...) - if len(args) == 2 && args[1].Type() == core.ArrayType { + if len(args) == 2 && args[1].Type().Equals(types.Array) { keys = args[1].(*values.Array) } - err = validateArrayOf(core.StringType, keys) + err = validateArrayOf(types.String, keys) if err != nil { return values.None, err @@ -47,9 +48,12 @@ func KeepKeys(_ context.Context, args ...core.Value) (core.Value, error) { key = keyVal.(values.String) if val, exists = obj.Get(key); exists { - if values.IsCloneable(val) { - val = val.(core.Cloneable).Clone() + cloneable, ok := val.(core.Cloneable) + + if ok { + val = cloneable.Clone() } + resultObj.Set(key, val) } diff --git a/pkg/stdlib/objects/keys.go b/pkg/stdlib/objects/keys.go index b304e6b9..b0c4f3f8 100644 --- a/pkg/stdlib/objects/keys.go +++ b/pkg/stdlib/objects/keys.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Keys returns string array of object's keys @@ -18,7 +19,7 @@ func Keys(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.ObjectType) + err = core.ValidateType(args[0], types.Object) if err != nil { return values.None, err } @@ -27,7 +28,7 @@ func Keys(_ context.Context, args ...core.Value) (core.Value, error) { needSort := false if len(args) == 2 { - err = core.ValidateType(args[1], core.BooleanType) + err = core.ValidateType(args[1], types.Boolean) if err != nil { return values.None, err } diff --git a/pkg/stdlib/objects/keys_test.go b/pkg/stdlib/objects/keys_test.go index 05453ec6..432b5dee 100644 --- a/pkg/stdlib/objects/keys_test.go +++ b/pkg/stdlib/objects/keys_test.go @@ -2,10 +2,9 @@ package objects_test import ( "context" + "github.com/MontFerret/ferret/pkg/runtime/values/types" "testing" - "github.com/MontFerret/ferret/pkg/runtime/core" - "github.com/MontFerret/ferret/pkg/runtime/values" "github.com/MontFerret/ferret/pkg/stdlib/objects" @@ -24,7 +23,7 @@ func TestKeys(t *testing.T) { keysArray := keys.(*values.Array) So(err, ShouldEqual, nil) - So(keysArray.Type(), ShouldEqual, core.ArrayType) + So(keysArray.Type().Equals(types.Array), ShouldBeTrue) So(keysArray.Length(), ShouldEqual, 3) for _, k := range []string{"b", "a", "c"} { diff --git a/pkg/stdlib/objects/merge.go b/pkg/stdlib/objects/merge.go index 2dc8dca0..3ee42708 100644 --- a/pkg/stdlib/objects/merge.go +++ b/pkg/stdlib/objects/merge.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Merge merge the given objects into a single object. @@ -19,11 +20,11 @@ func Merge(_ context.Context, args ...core.Value) (core.Value, error) { objs := values.NewArrayWith(args...) - if len(args) == 1 && args[0].Type() == core.ArrayType { + if len(args) == 1 && args[0].Type().Equals(types.Array) { objs = args[0].(*values.Array) } - err = validateArrayOf(core.ObjectType, objs) + err = validateArrayOf(types.Object, objs) if err != nil { return values.None, err @@ -38,10 +39,14 @@ func mergeArray(arr *values.Array) *values.Object { arr.ForEach(func(arrValue core.Value, arrIdx int) bool { obj = arrValue.(*values.Object) obj.ForEach(func(objValue core.Value, objKey string) bool { - if values.IsCloneable(objValue) { - objValue = objValue.(core.Cloneable).Clone() + cloneable, ok := objValue.(core.Cloneable) + + if ok { + objValue = cloneable.Clone() } + merged.Set(values.NewString(objKey), objValue) + return true }) return true diff --git a/pkg/stdlib/objects/merge_recursive.go b/pkg/stdlib/objects/merge_recursive.go index 5b10b6e8..a5e7a7ba 100644 --- a/pkg/stdlib/objects/merge_recursive.go +++ b/pkg/stdlib/objects/merge_recursive.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // MergeRecursive recursively merge the given objects into a single object. @@ -17,7 +18,7 @@ func MergeRecursive(_ context.Context, args ...core.Value) (core.Value, error) { } for _, arg := range args { - if err = core.ValidateType(arg, core.ObjectType); err != nil { + if err = core.ValidateType(arg, types.Object); err != nil { return values.None, err } } @@ -36,7 +37,7 @@ func merge(src, dst core.Value) core.Value { return dst } - if src.Type() != core.ObjectType { + if src.Type() != types.Object { return dst } diff --git a/pkg/stdlib/objects/values.go b/pkg/stdlib/objects/values.go index 89f5d1da..e31654b4 100644 --- a/pkg/stdlib/objects/values.go +++ b/pkg/stdlib/objects/values.go @@ -3,9 +3,9 @@ package objects import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/values" - "github.com/MontFerret/ferret/pkg/runtime/core" + "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Values return the attribute values of the object as an array. @@ -13,11 +13,13 @@ import ( // @returns (Array of Value) - the values of document returned in any order. func Values(_ context.Context, args ...core.Value) (core.Value, error) { err := core.ValidateArgs(args, 1, 1) + if err != nil { return values.None, err } - err = core.ValidateType(args[0], core.ObjectType) + err = core.ValidateType(args[0], types.Object) + if err != nil { return values.None, err } @@ -26,10 +28,14 @@ func Values(_ context.Context, args ...core.Value) (core.Value, error) { vals := values.NewArray(0) obj.ForEach(func(val core.Value, key string) bool { - if values.IsCloneable(val) { - val = val.(core.Cloneable).Clone() + cloneable, ok := val.(core.Cloneable) + + if ok { + val = cloneable.Clone() } + vals.Push(val) + return true }) diff --git a/pkg/stdlib/objects/zip.go b/pkg/stdlib/objects/zip.go index c39de632..33a98b77 100644 --- a/pkg/stdlib/objects/zip.go +++ b/pkg/stdlib/objects/zip.go @@ -1,12 +1,12 @@ package objects import ( - "fmt" - "context" + "fmt" "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Zip returns an object assembled from the separate parameters keys and values. @@ -16,12 +16,13 @@ import ( // @returns (Object) - an object with the keys and values assembled. func Zip(_ context.Context, args ...core.Value) (core.Value, error) { err := core.ValidateArgs(args, 2, 2) + if err != nil { return values.None, err } for _, arg := range args { - if err = core.ValidateType(arg, core.ArrayType); err != nil { + if err = core.ValidateType(arg, types.Array); err != nil { return values.None, err } } @@ -38,7 +39,8 @@ func Zip(_ context.Context, args ...core.Value) (core.Value, error) { ) } - err = validateArrayOf(core.StringType, keys) + err = validateArrayOf(types.String, keys) + if err != nil { return values.None, err } @@ -68,12 +70,14 @@ func Zip(_ context.Context, args ...core.Value) (core.Value, error) { keyExists[k] = true val = vals.Get(values.NewInt(idx)) + cloneable, ok := val.(core.Cloneable) - if values.IsCloneable(val) { - val = val.(core.Cloneable).Clone() + if ok { + val = cloneable.Clone() } zipped.Set(k, val) + return true }) diff --git a/pkg/stdlib/strings/concat.go b/pkg/stdlib/strings/concat.go index 170708e2..0b326bbb 100644 --- a/pkg/stdlib/strings/concat.go +++ b/pkg/stdlib/strings/concat.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Concat concatenates one or more instances of Read, or an Array. @@ -21,7 +22,7 @@ func Concat(_ context.Context, args ...core.Value) (core.Value, error) { res := values.EmptyString - if argsCount == 1 && args[0].Type() == core.ArrayType { + if argsCount == 1 && args[0].Type() == types.Array { arr := args[0].(*values.Array) arr.ForEach(func(value core.Value, _ int) bool { @@ -53,15 +54,15 @@ func ConcatWithSeparator(_ context.Context, args ...core.Value) (core.Value, err separator := args[0] - if separator.Type() != core.StringType { + if separator.Type() != types.String { separator = values.NewString(separator.String()) } res := values.EmptyString for idx, arg := range args[1:] { - if arg.Type() != core.ArrayType { - if arg.Type() != core.NoneType { + if arg.Type() != types.Array { + if arg.Type() != types.None { if idx > 0 { res = res.Concat(separator) } @@ -72,7 +73,7 @@ func ConcatWithSeparator(_ context.Context, args ...core.Value) (core.Value, err arr := arg.(*values.Array) arr.ForEach(func(value core.Value, idx int) bool { - if value.Type() != core.NoneType { + if value.Type() != types.None { if idx > 0 { res = res.Concat(separator) } diff --git a/pkg/stdlib/strings/contains.go b/pkg/stdlib/strings/contains.go index 2e100fb0..c82c88b7 100644 --- a/pkg/stdlib/strings/contains.go +++ b/pkg/stdlib/strings/contains.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Contains returns a value indicating whether a specified substring occurs within a string. @@ -27,13 +28,13 @@ func Contains(_ context.Context, args ...core.Value) (core.Value, error) { arg1 := args[0] arg2 := args[1] - if arg1.Type() == core.StringType { + if arg1.Type() == types.String { text = arg1.(values.String) } else { text = values.NewString(arg1.String()) } - if arg2.Type() == core.StringType { + if arg2.Type() == types.String { search = arg2.(values.String) } else { search = values.NewString(arg2.String()) @@ -42,7 +43,7 @@ func Contains(_ context.Context, args ...core.Value) (core.Value, error) { if len(args) > 2 { arg3 := args[2] - if arg3.Type() == core.BooleanType { + if arg3.Type() == types.Boolean { returnIndex = arg3.(values.Boolean) } } diff --git a/pkg/stdlib/strings/find.go b/pkg/stdlib/strings/find.go index aa495dd3..a5108933 100644 --- a/pkg/stdlib/strings/find.go +++ b/pkg/stdlib/strings/find.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // FindFirst returns the position of the first occurrence of the string search inside the string text. Positions start at 0. @@ -33,7 +34,7 @@ func FindFirst(_ context.Context, args ...core.Value) (core.Value, error) { if argsCount == 3 { arg3 := args[2] - if arg3.Type() == core.IntType { + if arg3.Type() == types.Int { start = arg3.(values.Int) } } @@ -41,7 +42,7 @@ func FindFirst(_ context.Context, args ...core.Value) (core.Value, error) { if argsCount == 4 { arg4 := args[3] - if arg4.Type() == core.IntType { + if arg4.Type() == types.Int { end = arg4.(values.Int) } } @@ -80,7 +81,7 @@ func FindLast(_ context.Context, args ...core.Value) (core.Value, error) { if argsCount == 3 { arg3 := args[2] - if arg3.Type() == core.IntType { + if arg3.Type() == types.Int { start = arg3.(values.Int) } } @@ -88,7 +89,7 @@ func FindLast(_ context.Context, args ...core.Value) (core.Value, error) { if argsCount == 4 { arg4 := args[3] - if arg4.Type() == core.IntType { + if arg4.Type() == types.Int { end = arg4.(values.Int) } } diff --git a/pkg/stdlib/strings/fmt.go b/pkg/stdlib/strings/fmt.go index 094aaf1e..65ce8b93 100644 --- a/pkg/stdlib/strings/fmt.go +++ b/pkg/stdlib/strings/fmt.go @@ -8,6 +8,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" "github.com/pkg/errors" ) @@ -21,7 +22,7 @@ func Fmt(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - err = core.ValidateType(args[0], core.StringType) + err = core.ValidateType(args[0], types.String) if err != nil { return values.None, err } diff --git a/pkg/stdlib/strings/json_test.go b/pkg/stdlib/strings/json_test.go index 45aaafc2..114f62c5 100644 --- a/pkg/stdlib/strings/json_test.go +++ b/pkg/stdlib/strings/json_test.go @@ -2,11 +2,12 @@ package strings_test import ( "context" - "github.com/MontFerret/ferret/pkg/runtime/core" + "testing" + "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" "github.com/MontFerret/ferret/pkg/stdlib/strings" . "github.com/smartystreets/goconvey/convey" - "testing" ) func TestJSONParse(t *testing.T) { @@ -32,7 +33,7 @@ func TestJSONParse(t *testing.T) { ) So(err, ShouldBeNil) - So(out.Type(), ShouldEqual, core.NoneType) + So(out.Type().Equals(types.None), ShouldBeTrue) }) Convey("It should parse a string", t, func() { @@ -48,7 +49,7 @@ func TestJSONParse(t *testing.T) { ) So(err, ShouldBeNil) - So(out.Type(), ShouldEqual, core.StringType) + So(out.Type().Equals(types.String), ShouldBeTrue) }) Convey("It should parse an int", t, func() { @@ -64,7 +65,7 @@ func TestJSONParse(t *testing.T) { ) So(err, ShouldBeNil) - So(out.Type(), ShouldEqual, core.FloatType) + So(out.Type().Equals(types.Float), ShouldBeTrue) }) Convey("It should parse a float", t, func() { @@ -80,7 +81,7 @@ func TestJSONParse(t *testing.T) { ) So(err, ShouldBeNil) - So(out.Type(), ShouldEqual, core.FloatType) + So(out.Type().Equals(types.Float), ShouldBeTrue) }) Convey("It should parse a boolean", t, func() { @@ -96,7 +97,7 @@ func TestJSONParse(t *testing.T) { ) So(err, ShouldBeNil) - So(out.Type(), ShouldEqual, core.BooleanType) + So(out.Type().Equals(types.Boolean), ShouldBeTrue) }) Convey("It should parse an array", t, func() { @@ -116,7 +117,7 @@ func TestJSONParse(t *testing.T) { ) So(err, ShouldBeNil) - So(out.Type(), ShouldEqual, core.ArrayType) + So(out.Type().Equals(types.Array), ShouldBeTrue) So(out.String(), ShouldEqual, "[1,2,3]") }) @@ -134,7 +135,7 @@ func TestJSONParse(t *testing.T) { ) So(err, ShouldBeNil) - So(out.Type(), ShouldEqual, core.ObjectType) + So(out.Type().Equals(types.Object), ShouldBeTrue) So(out.String(), ShouldEqual, `{"foo":"bar"}`) }) } diff --git a/pkg/stdlib/strings/random.go b/pkg/stdlib/strings/random.go index 9c6bf9f3..2648839d 100644 --- a/pkg/stdlib/strings/random.go +++ b/pkg/stdlib/strings/random.go @@ -7,6 +7,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) const ( @@ -26,7 +27,7 @@ func RandomToken(_ context.Context, args ...core.Value) (core.Value, error) { return values.EmptyString, err } - err = core.ValidateType(args[0], core.IntType) + err = core.ValidateType(args[0], types.Int) if err != nil { return values.EmptyString, err diff --git a/pkg/stdlib/strings/regex.go b/pkg/stdlib/strings/regex.go index e161b7b2..1b0fc714 100644 --- a/pkg/stdlib/strings/regex.go +++ b/pkg/stdlib/strings/regex.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // RegexMatch returns the matches in the given string text, using the regex. @@ -67,7 +68,7 @@ func RegexSplit(_ context.Context, args ...core.Value) (core.Value, error) { limit := -1 if len(args) > 2 { - if args[2].Type() == core.IntType { + if args[2].Type() == types.Int { limit = int(args[2].(values.Int)) } } diff --git a/pkg/stdlib/strings/split.go b/pkg/stdlib/strings/split.go index bfedd270..030fab79 100644 --- a/pkg/stdlib/strings/split.go +++ b/pkg/stdlib/strings/split.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Split splits the given string value into a list of strings, using the separator. @@ -25,7 +26,7 @@ func Split(_ context.Context, args ...core.Value) (core.Value, error) { limit := -1 if len(args) > 2 { - if args[2].Type() == core.IntType { + if args[2].Type() == types.Int { limit = int(args[2].(values.Int)) } } diff --git a/pkg/stdlib/strings/substitute.go b/pkg/stdlib/strings/substitute.go index aa2b0a93..1bd1be91 100644 --- a/pkg/stdlib/strings/substitute.go +++ b/pkg/stdlib/strings/substitute.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Substitute replaces search values in the string value. @@ -31,7 +32,7 @@ func Substitute(_ context.Context, args ...core.Value) (core.Value, error) { } if len(args) > 3 { - if args[3].Type() == core.IntType { + if args[3].Type() == types.Int { limit = int(args[3].(values.Int)) } } diff --git a/pkg/stdlib/strings/substr.go b/pkg/stdlib/strings/substr.go index d229f350..884f33fc 100644 --- a/pkg/stdlib/strings/substr.go +++ b/pkg/stdlib/strings/substr.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Substring returns a substring of value. @@ -19,7 +20,7 @@ func Substring(_ context.Context, args ...core.Value) (core.Value, error) { return values.EmptyString, err } - err = core.ValidateType(args[1], core.IntType) + err = core.ValidateType(args[1], types.Int) if err != nil { return values.EmptyString, err @@ -32,7 +33,7 @@ func Substring(_ context.Context, args ...core.Value) (core.Value, error) { length := size if len(args) > 2 { - if args[2].Type() == core.IntType { + if args[2].Type() == types.Int { length = int(args[2].(values.Int)) } } @@ -70,7 +71,7 @@ func Left(_ context.Context, args ...core.Value) (core.Value, error) { var pos int - if args[1].Type() == core.IntType { + if args[1].Type() == types.Int { pos = int(args[1].(values.Int)) } @@ -97,7 +98,7 @@ func Right(_ context.Context, args ...core.Value) (core.Value, error) { size := len(runes) pos := size - if args[1].Type() == core.IntType { + if args[1].Type() == types.Int { pos = int(args[1].(values.Int)) } diff --git a/pkg/stdlib/types/is_array.go b/pkg/stdlib/types/is_array.go index 66ea3a28..1ebd480c 100644 --- a/pkg/stdlib/types/is_array.go +++ b/pkg/stdlib/types/is_array.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // IsArray checks whether value is an array value. @@ -17,5 +18,5 @@ func IsArray(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - return isTypeof(args[0], core.ArrayType), nil + return isTypeof(args[0], types.Array), nil } diff --git a/pkg/stdlib/types/is_binary.go b/pkg/stdlib/types/is_binary.go index fcc0b11d..05b63d69 100644 --- a/pkg/stdlib/types/is_binary.go +++ b/pkg/stdlib/types/is_binary.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // IsBinary checks whether value is a binary value. @@ -17,5 +18,5 @@ func IsBinary(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - return isTypeof(args[0], core.BinaryType), nil + return isTypeof(args[0], types.Binary), nil } diff --git a/pkg/stdlib/types/is_boolean.go b/pkg/stdlib/types/is_boolean.go index 81f2e87e..d9cdede5 100644 --- a/pkg/stdlib/types/is_boolean.go +++ b/pkg/stdlib/types/is_boolean.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // IsBool checks whether value is a boolean value. @@ -17,5 +18,5 @@ func IsBool(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - return isTypeof(args[0], core.BooleanType), nil + return isTypeof(args[0], types.Boolean), nil } diff --git a/pkg/stdlib/types/is_date_time.go b/pkg/stdlib/types/is_date_time.go index 23e45330..87302c91 100644 --- a/pkg/stdlib/types/is_date_time.go +++ b/pkg/stdlib/types/is_date_time.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // IsDateTime checks whether value is a date time value. @@ -17,5 +18,5 @@ func IsDateTime(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - return isTypeof(args[0], core.DateTimeType), nil + return isTypeof(args[0], types.DateTime), nil } diff --git a/pkg/stdlib/types/is_float.go b/pkg/stdlib/types/is_float.go index 08c5355c..e1d09977 100644 --- a/pkg/stdlib/types/is_float.go +++ b/pkg/stdlib/types/is_float.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // IsFloat checks whether value is a float value. @@ -17,5 +18,5 @@ func IsFloat(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - return isTypeof(args[0], core.FloatType), nil + return isTypeof(args[0], types.Float), nil } diff --git a/pkg/stdlib/types/is_html_document.go b/pkg/stdlib/types/is_html_document.go index 6b6f764a..d7387b15 100644 --- a/pkg/stdlib/types/is_html_document.go +++ b/pkg/stdlib/types/is_html_document.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // IsHTMLDocument checks whether value is a HTMLDocument value. @@ -17,5 +18,5 @@ func IsHTMLDocument(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - return isTypeof(args[0], core.HTMLDocumentType), nil + return isTypeof(args[0], types.HTMLDocument), nil } diff --git a/pkg/stdlib/types/is_html_element.go b/pkg/stdlib/types/is_html_element.go index d2e6e82c..d007b6a2 100644 --- a/pkg/stdlib/types/is_html_element.go +++ b/pkg/stdlib/types/is_html_element.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // IsHTMLElement checks whether value is a HTMLElement value. @@ -17,5 +18,5 @@ func IsHTMLElement(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - return isTypeof(args[0], core.HTMLElementType), nil + return isTypeof(args[0], types.HTMLElement), nil } diff --git a/pkg/stdlib/types/is_int.go b/pkg/stdlib/types/is_int.go index 7b9420cb..2d2265d1 100644 --- a/pkg/stdlib/types/is_int.go +++ b/pkg/stdlib/types/is_int.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // IsInt checks whether value is a int value. @@ -17,5 +18,5 @@ func IsInt(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - return isTypeof(args[0], core.IntType), nil + return isTypeof(args[0], types.Int), nil } diff --git a/pkg/stdlib/types/is_nan.go b/pkg/stdlib/types/is_nan.go index e8582b2a..a7cf11f6 100644 --- a/pkg/stdlib/types/is_nan.go +++ b/pkg/stdlib/types/is_nan.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // IsNaN checks whether value is NaN. @@ -17,7 +18,7 @@ func IsNaN(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - if args[0].Type() != core.FloatType { + if args[0].Type() != types.Float { return values.False, nil } diff --git a/pkg/stdlib/types/is_none.go b/pkg/stdlib/types/is_none.go index fa04bf97..55062fbb 100644 --- a/pkg/stdlib/types/is_none.go +++ b/pkg/stdlib/types/is_none.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // IsNone checks whether value is a none value. @@ -17,5 +18,5 @@ func IsNone(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - return isTypeof(args[0], core.NoneType), nil + return isTypeof(args[0], types.None), nil } diff --git a/pkg/stdlib/types/is_object.go b/pkg/stdlib/types/is_object.go index de13cc8e..fc96840e 100644 --- a/pkg/stdlib/types/is_object.go +++ b/pkg/stdlib/types/is_object.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // IsObject checks whether value is an object value. @@ -17,5 +18,5 @@ func IsObject(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - return isTypeof(args[0], core.ObjectType), nil + return isTypeof(args[0], types.Object), nil } diff --git a/pkg/stdlib/types/is_string.go b/pkg/stdlib/types/is_string.go index b5be6091..944d67b3 100644 --- a/pkg/stdlib/types/is_string.go +++ b/pkg/stdlib/types/is_string.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // IsString checks whether value is a string value. @@ -17,5 +18,5 @@ func IsString(_ context.Context, args ...core.Value) (core.Value, error) { return values.None, err } - return isTypeof(args[0], core.StringType), nil + return isTypeof(args[0], types.String), nil } diff --git a/pkg/stdlib/types/to_boolean.go b/pkg/stdlib/types/to_boolean.go index e706eecc..4463ecde 100644 --- a/pkg/stdlib/types/to_boolean.go +++ b/pkg/stdlib/types/to_boolean.go @@ -5,6 +5,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // ToBool takes an input value of any type and converts it into the appropriate boolean value. @@ -26,9 +27,9 @@ func ToBool(_ context.Context, args ...core.Value) (core.Value, error) { arg := args[0] switch arg.Type() { - case core.BooleanType: + case types.Boolean: return arg, nil - case core.IntType: + case types.Int: val := arg.(values.Int) if val != 0 { @@ -36,7 +37,7 @@ func ToBool(_ context.Context, args ...core.Value) (core.Value, error) { } return values.False, nil - case core.FloatType: + case types.Float: val := arg.(values.Float) if val != 0 { @@ -44,13 +45,13 @@ func ToBool(_ context.Context, args ...core.Value) (core.Value, error) { } return values.False, nil - case core.StringType: + case types.String: if arg.String() != "" { return values.True, nil } return values.False, nil - case core.DateTimeType: + case types.DateTime: val := arg.(values.DateTime) if !val.IsZero() { @@ -58,7 +59,7 @@ func ToBool(_ context.Context, args ...core.Value) (core.Value, error) { } return values.False, nil - case core.NoneType: + case types.None: return values.False, nil default: return values.True, nil diff --git a/pkg/stdlib/types/to_float.go b/pkg/stdlib/types/to_float.go index 9f1b72b6..28f609b0 100644 --- a/pkg/stdlib/types/to_float.go +++ b/pkg/stdlib/types/to_float.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // ToFloat takes an input value of any type and convert it into a float value. @@ -29,7 +30,7 @@ func ToFloat(ctx context.Context, args ...core.Value) (core.Value, error) { arg := args[0] switch arg.Type() { - case core.BooleanType: + case types.Boolean: val := arg.(values.Boolean) if val { @@ -37,13 +38,13 @@ func ToFloat(ctx context.Context, args ...core.Value) (core.Value, error) { } return values.ZeroFloat, nil - case core.IntType: + case types.Int: val := arg.(values.Int) return values.Float(val), nil - case core.FloatType: + case types.Float: return arg, nil - case core.StringType: + case types.String: str := arg.String() if str == "" { @@ -57,7 +58,7 @@ func ToFloat(ctx context.Context, args ...core.Value) (core.Value, error) { } return values.NewFloat(num), nil - case core.DateTimeType: + case types.DateTime: val := arg.(values.DateTime) if val.IsZero() { @@ -65,9 +66,9 @@ func ToFloat(ctx context.Context, args ...core.Value) (core.Value, error) { } return values.NewFloat(float64(val.Unix())), nil - case core.NoneType: + case types.None: return values.ZeroFloat, nil - case core.ArrayType: + case types.Array: val := arg.(*values.Array) if val.Length() == 0 { diff --git a/pkg/stdlib/types/to_int.go b/pkg/stdlib/types/to_int.go index e0857fde..1903340c 100644 --- a/pkg/stdlib/types/to_int.go +++ b/pkg/stdlib/types/to_int.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // ToInt takes an input value of any type and convert it into an integer value. @@ -29,7 +30,7 @@ func ToInt(ctx context.Context, args ...core.Value) (core.Value, error) { arg := args[0] switch arg.Type() { - case core.BooleanType: + case types.Boolean: val := arg.(values.Boolean) if val { @@ -37,13 +38,13 @@ func ToInt(ctx context.Context, args ...core.Value) (core.Value, error) { } return values.ZeroInt, nil - case core.IntType: + case types.Int: return arg, nil - case core.FloatType: + case types.Float: val := arg.(values.Float) return values.Int(val), nil - case core.StringType: + case types.String: str := arg.String() if str == "" { @@ -57,7 +58,7 @@ func ToInt(ctx context.Context, args ...core.Value) (core.Value, error) { } return values.NewInt(num), nil - case core.DateTimeType: + case types.DateTime: val := arg.(values.DateTime) if val.IsZero() { @@ -65,9 +66,9 @@ func ToInt(ctx context.Context, args ...core.Value) (core.Value, error) { } return values.NewInt(int(val.Unix())), nil - case core.NoneType: + case types.None: return values.ZeroInt, nil - case core.ArrayType: + case types.Array: val := arg.(*values.Array) if val.Length() == 0 { diff --git a/pkg/stdlib/utils/wait.go b/pkg/stdlib/utils/wait.go index f007516e..1459f97d 100644 --- a/pkg/stdlib/utils/wait.go +++ b/pkg/stdlib/utils/wait.go @@ -6,6 +6,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/core" "github.com/MontFerret/ferret/pkg/runtime/values" + "github.com/MontFerret/ferret/pkg/runtime/values/types" ) // Wait pauses the execution for a given period. @@ -19,7 +20,7 @@ func Wait(_ context.Context, inputs ...core.Value) (core.Value, error) { arg := values.ZeroInt - err = core.ValidateType(inputs[0], core.IntType) + err = core.ValidateType(inputs[0], types.Int) if err != nil { return values.None, err