feelin 4.3.1 → 7.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +5 -1
- data/CHANGELOG.md +30 -0
- data/README.md +91 -0
- data/feelin.gemspec +5 -1
- data/lib/feelin/js/dist/feelin.js +13703 -0
- data/lib/feelin/js/entry.js +93 -0
- data/lib/feelin/js/package-lock.json +526 -31
- data/lib/feelin/js/package.json +8 -1
- data/lib/feelin/version.rb +1 -1
- data/lib/feelin.rb +87 -43
- data/spec/feelin/feelin_spec.rb +140 -0
- metadata +11 -108
- data/lib/feelin/js/node_modules/.package-lock.json +0 -67
- data/lib/feelin/js/node_modules/@lezer/common/LICENSE +0 -21
- data/lib/feelin/js/node_modules/@lezer/common/README.md +0 -14
- data/lib/feelin/js/node_modules/@lezer/common/dist/index.cjs +0 -2181
- data/lib/feelin/js/node_modules/@lezer/common/dist/index.d.cts +0 -1137
- data/lib/feelin/js/node_modules/@lezer/common/dist/index.d.ts +0 -1137
- data/lib/feelin/js/node_modules/@lezer/common/dist/index.js +0 -2168
- data/lib/feelin/js/node_modules/@lezer/common/package.json +0 -32
- data/lib/feelin/js/node_modules/@lezer/highlight/LICENSE +0 -21
- data/lib/feelin/js/node_modules/@lezer/highlight/README.md +0 -14
- data/lib/feelin/js/node_modules/@lezer/highlight/dist/index.cjs +0 -915
- data/lib/feelin/js/node_modules/@lezer/highlight/dist/index.d.cts +0 -621
- data/lib/feelin/js/node_modules/@lezer/highlight/dist/index.d.ts +0 -623
- data/lib/feelin/js/node_modules/@lezer/highlight/dist/index.js +0 -904
- data/lib/feelin/js/node_modules/@lezer/highlight/package.json +0 -31
- data/lib/feelin/js/node_modules/@lezer/lr/LICENSE +0 -21
- data/lib/feelin/js/node_modules/@lezer/lr/README.md +0 -25
- data/lib/feelin/js/node_modules/@lezer/lr/dist/constants.d.ts +0 -45
- data/lib/feelin/js/node_modules/@lezer/lr/dist/constants.js +0 -5
- data/lib/feelin/js/node_modules/@lezer/lr/dist/index.cjs +0 -1890
- data/lib/feelin/js/node_modules/@lezer/lr/dist/index.d.cts +0 -303
- data/lib/feelin/js/node_modules/@lezer/lr/dist/index.d.ts +0 -303
- data/lib/feelin/js/node_modules/@lezer/lr/dist/index.js +0 -1883
- data/lib/feelin/js/node_modules/@lezer/lr/package.json +0 -32
- data/lib/feelin/js/node_modules/feelin/LICENSE +0 -21
- data/lib/feelin/js/node_modules/feelin/README.md +0 -65
- data/lib/feelin/js/node_modules/feelin/dist/builtins.d.ts +0 -355
- data/lib/feelin/js/node_modules/feelin/dist/index.cjs +0 -2072
- data/lib/feelin/js/node_modules/feelin/dist/index.cjs.map +0 -1
- data/lib/feelin/js/node_modules/feelin/dist/index.d.ts +0 -3
- data/lib/feelin/js/node_modules/feelin/dist/index.esm.js +0 -2063
- data/lib/feelin/js/node_modules/feelin/dist/index.esm.js.map +0 -1
- data/lib/feelin/js/node_modules/feelin/dist/interpreter.d.ts +0 -26
- data/lib/feelin/js/node_modules/feelin/dist/parser.d.ts +0 -4
- data/lib/feelin/js/node_modules/feelin/dist/temporal.d.ts +0 -6
- data/lib/feelin/js/node_modules/feelin/dist/types.d.ts +0 -35
- data/lib/feelin/js/node_modules/feelin/dist/utils.d.ts +0 -12
- data/lib/feelin/js/node_modules/feelin/package.json +0 -63
- data/lib/feelin/js/node_modules/lezer-feel/LICENSE +0 -21
- data/lib/feelin/js/node_modules/lezer-feel/README.md +0 -94
- data/lib/feelin/js/node_modules/lezer-feel/dist/index.cjs +0 -1328
- data/lib/feelin/js/node_modules/lezer-feel/dist/index.cjs.map +0 -1
- data/lib/feelin/js/node_modules/lezer-feel/dist/index.d.ts +0 -32
- data/lib/feelin/js/node_modules/lezer-feel/dist/index.js +0 -1323
- data/lib/feelin/js/node_modules/lezer-feel/dist/index.js.map +0 -1
- data/lib/feelin/js/node_modules/lezer-feel/package.json +0 -61
- data/lib/feelin/js/node_modules/luxon/LICENSE.md +0 -7
- data/lib/feelin/js/node_modules/luxon/README.md +0 -55
- data/lib/feelin/js/node_modules/luxon/build/amd/luxon.js +0 -8623
- data/lib/feelin/js/node_modules/luxon/build/amd/luxon.js.map +0 -1
- data/lib/feelin/js/node_modules/luxon/build/cjs-browser/luxon.js +0 -8621
- data/lib/feelin/js/node_modules/luxon/build/cjs-browser/luxon.js.map +0 -1
- data/lib/feelin/js/node_modules/luxon/build/es6/luxon.js +0 -8011
- data/lib/feelin/js/node_modules/luxon/build/es6/luxon.js.map +0 -1
- data/lib/feelin/js/node_modules/luxon/build/global/luxon.js +0 -8626
- data/lib/feelin/js/node_modules/luxon/build/global/luxon.js.map +0 -1
- data/lib/feelin/js/node_modules/luxon/build/global/luxon.min.js +0 -1
- data/lib/feelin/js/node_modules/luxon/build/global/luxon.min.js.map +0 -1
- data/lib/feelin/js/node_modules/luxon/build/node/luxon.js +0 -7679
- data/lib/feelin/js/node_modules/luxon/build/node/luxon.js.map +0 -1
- data/lib/feelin/js/node_modules/luxon/package.json +0 -87
- data/lib/feelin/js/node_modules/luxon/src/datetime.js +0 -2566
- data/lib/feelin/js/node_modules/luxon/src/duration.js +0 -990
- data/lib/feelin/js/node_modules/luxon/src/errors.js +0 -61
- data/lib/feelin/js/node_modules/luxon/src/impl/conversions.js +0 -206
- data/lib/feelin/js/node_modules/luxon/src/impl/diff.js +0 -95
- data/lib/feelin/js/node_modules/luxon/src/impl/digits.js +0 -90
- data/lib/feelin/js/node_modules/luxon/src/impl/english.js +0 -233
- data/lib/feelin/js/node_modules/luxon/src/impl/formats.js +0 -176
- data/lib/feelin/js/node_modules/luxon/src/impl/formatter.js +0 -409
- data/lib/feelin/js/node_modules/luxon/src/impl/invalid.js +0 -14
- data/lib/feelin/js/node_modules/luxon/src/impl/locale.js +0 -554
- data/lib/feelin/js/node_modules/luxon/src/impl/regexParser.js +0 -335
- data/lib/feelin/js/node_modules/luxon/src/impl/tokenParser.js +0 -505
- data/lib/feelin/js/node_modules/luxon/src/impl/util.js +0 -316
- data/lib/feelin/js/node_modules/luxon/src/impl/zoneUtil.js +0 -34
- data/lib/feelin/js/node_modules/luxon/src/info.js +0 -205
- data/lib/feelin/js/node_modules/luxon/src/interval.js +0 -665
- data/lib/feelin/js/node_modules/luxon/src/luxon.js +0 -26
- data/lib/feelin/js/node_modules/luxon/src/package.json +0 -4
- data/lib/feelin/js/node_modules/luxon/src/settings.js +0 -180
- data/lib/feelin/js/node_modules/luxon/src/zone.js +0 -97
- data/lib/feelin/js/node_modules/luxon/src/zones/IANAZone.js +0 -231
- data/lib/feelin/js/node_modules/luxon/src/zones/fixedOffsetZone.js +0 -150
- data/lib/feelin/js/node_modules/luxon/src/zones/invalidZone.js +0 -53
- data/lib/feelin/js/node_modules/luxon/src/zones/systemZone.js +0 -61
- data/lib/feelin/js/node_modules/min-dash/LICENSE +0 -21
- data/lib/feelin/js/node_modules/min-dash/README.md +0 -38
- data/lib/feelin/js/node_modules/min-dash/dist/array.d.ts +0 -12
- data/lib/feelin/js/node_modules/min-dash/dist/collection.d.ts +0 -174
- data/lib/feelin/js/node_modules/min-dash/dist/fn.d.ts +0 -37
- data/lib/feelin/js/node_modules/min-dash/dist/index.cjs +0 -910
- data/lib/feelin/js/node_modules/min-dash/dist/index.d.ts +0 -5
- data/lib/feelin/js/node_modules/min-dash/dist/index.esm.js +0 -872
- data/lib/feelin/js/node_modules/min-dash/dist/lang.d.ts +0 -29
- data/lib/feelin/js/node_modules/min-dash/dist/min-dash.js +0 -916
- data/lib/feelin/js/node_modules/min-dash/dist/min-dash.min.js +0 -1
- data/lib/feelin/js/node_modules/min-dash/dist/object.d.ts +0 -112
- data/lib/feelin/js/node_modules/min-dash/package.json +0 -72
data/lib/feelin/js/package.json
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
+
"private": true,
|
|
3
|
+
"scripts": {
|
|
4
|
+
"build": "esbuild entry.js --bundle --format=iife --global-name=feel --platform=browser --outfile=dist/feelin.js"
|
|
5
|
+
},
|
|
2
6
|
"dependencies": {
|
|
3
|
-
"feelin": "^
|
|
7
|
+
"feelin": "^7.0.2"
|
|
8
|
+
},
|
|
9
|
+
"devDependencies": {
|
|
10
|
+
"esbuild": "^0.28.1"
|
|
4
11
|
}
|
|
5
12
|
}
|
data/lib/feelin/version.rb
CHANGED
data/lib/feelin.rb
CHANGED
|
@@ -1,63 +1,107 @@
|
|
|
1
1
|
require "mini_racer"
|
|
2
|
+
require "json"
|
|
2
3
|
|
|
3
4
|
module FEELIN
|
|
4
|
-
|
|
5
|
+
# Pre-built single-file IIFE bundle (feelin + its dependencies), produced by
|
|
6
|
+
# `npm run build` in lib/feelin/js. It exposes the feelin API on the global
|
|
7
|
+
# `feel`, and under `feel.json` the functions this wrapper calls. feelin is
|
|
8
|
+
# distributed as an ES module, so it is bundled ahead of time rather than
|
|
9
|
+
# assembled at load time.
|
|
10
|
+
BUNDLE_PATH = File.expand_path("feelin/js/dist/feelin.js", __dir__)
|
|
5
11
|
|
|
6
|
-
|
|
7
|
-
|
|
12
|
+
# A V8 context with feelin loaded. The module-level methods below work on one
|
|
13
|
+
# shared context without limits; a context of one's own is for an expression
|
|
14
|
+
# that is not trusted to end or to stay small — `timeout` (ms) and `max_memory`
|
|
15
|
+
# (bytes) are MiniRacer's limits, and going over one raises
|
|
16
|
+
# MiniRacer::ScriptTerminatedError or MiniRacer::V8OutOfMemoryError — and for
|
|
17
|
+
# custom functions that the shared context should not see.
|
|
18
|
+
#
|
|
19
|
+
# Every context starts from one snapshot of the bundle, so creating one does
|
|
20
|
+
# not load and compile feelin again.
|
|
21
|
+
#
|
|
22
|
+
# The context goes into V8 as a JSON string and the result comes back as one
|
|
23
|
+
# (`feel.json.*` in js/entry.js). That keeps a call a function call with
|
|
24
|
+
# arguments: the data is never written into a script of its own, which V8 would
|
|
25
|
+
# compile and keep for every distinct context. And it is how a date, time or
|
|
26
|
+
# duration arrives as its ISO 8601 string, the form FEEL's `string()` gives
|
|
27
|
+
# it, instead of the internal fields of the object V8 holds.
|
|
28
|
+
class Context
|
|
29
|
+
class << self
|
|
30
|
+
def snapshot
|
|
31
|
+
@snapshot ||= MiniRacer::Snapshot.new(File.read(BUNDLE_PATH))
|
|
32
|
+
end
|
|
33
|
+
end
|
|
8
34
|
|
|
9
|
-
|
|
10
|
-
|
|
35
|
+
def initialize(timeout: nil, max_memory: nil)
|
|
36
|
+
limits = { timeout: timeout, max_memory: max_memory }.compact
|
|
37
|
+
@context = MiniRacer::Context.new(snapshot: self.class.snapshot, **limits)
|
|
38
|
+
end
|
|
11
39
|
|
|
12
|
-
|
|
13
|
-
|
|
40
|
+
def evaluate(expression, context = nil)
|
|
41
|
+
call("evaluate", expression, context)
|
|
42
|
+
end
|
|
14
43
|
|
|
15
|
-
|
|
16
|
-
|
|
44
|
+
def unary_test(expression, value, context = {})
|
|
45
|
+
call("unaryTest", expression, { **context, '?' => value })
|
|
46
|
+
end
|
|
17
47
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
48
|
+
# The syntax tree of an expression, without evaluating it: nested hashes of
|
|
49
|
+
# `type` (the grammar's node name), `from` / `to` (the span in the expression,
|
|
50
|
+
# counted in UTF-16 code units), `text` (that span) and `children`. Tokens are
|
|
51
|
+
# nodes too. The context only supplies the names of the variables, which is
|
|
52
|
+
# what lets a name with spaces in it be read as one. An expression that does
|
|
53
|
+
# not parse raises, as it does in `evaluate`.
|
|
54
|
+
def parse(expression, context = nil)
|
|
55
|
+
call("parseExpression", expression, context)
|
|
56
|
+
end
|
|
22
57
|
|
|
23
|
-
|
|
58
|
+
def parse_unary_tests(expression, context = nil)
|
|
59
|
+
call("parseUnaryTests", expression, context)
|
|
60
|
+
end
|
|
24
61
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
end.join(',')
|
|
62
|
+
def add_function(name, proc)
|
|
63
|
+
@context.attach(name, proc)
|
|
64
|
+
@context.call("feel.json.addFunction", name)
|
|
65
|
+
end
|
|
30
66
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
67
|
+
def dispose
|
|
68
|
+
@context.dispose
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
|
|
73
|
+
def call(function, expression, context)
|
|
74
|
+
JSON.parse(@context.call("feel.json.#{function}", expression, context.nil? ? nil : JSON.generate(context)))
|
|
38
75
|
end
|
|
39
76
|
end
|
|
40
77
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
78
|
+
class << self
|
|
79
|
+
def evaluate(expression, context = nil)
|
|
80
|
+
shared.evaluate(expression, context)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def unary_test(expression, value, context = {})
|
|
84
|
+
shared.unary_test(expression, value, context)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def parse(expression, context = nil)
|
|
88
|
+
shared.parse(expression, context)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def parse_unary_tests(expression, context = nil)
|
|
92
|
+
shared.parse_unary_tests(expression, context)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def add_function(name, proc)
|
|
96
|
+
shared.add_function(name, proc)
|
|
97
|
+
end
|
|
51
98
|
|
|
52
|
-
|
|
53
|
-
name = $1
|
|
54
|
-
data = process_module(File.read("#{File.dirname(__FILE__)}/feelin/js/node_modules/#{name}/#{file_map[name]}"))
|
|
99
|
+
private
|
|
55
100
|
|
|
56
|
-
|
|
101
|
+
def shared
|
|
102
|
+
@shared
|
|
57
103
|
end
|
|
58
104
|
end
|
|
59
105
|
|
|
60
|
-
|
|
61
|
-
@@context = MiniRacer::Context.new
|
|
62
|
-
@@context.eval(source)
|
|
106
|
+
@shared = Context.new
|
|
63
107
|
end
|
data/spec/feelin/feelin_spec.rb
CHANGED
|
@@ -20,6 +20,146 @@ RSpec.describe FEELIN do
|
|
|
20
20
|
expect(FEELIN.evaluate('every rate in rates() satisfies rate < 10')).to eq false
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
|
+
|
|
24
|
+
context "with a custom function and an empty context" do
|
|
25
|
+
it "does not build an invalid context literal" do
|
|
26
|
+
FEELIN.add_function('answer', proc { 42 })
|
|
27
|
+
expect(FEELIN.evaluate('answer()', {})).to eq 42
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context "with a custom function whose name contains spaces" do
|
|
32
|
+
it "forwards to the attached global" do
|
|
33
|
+
FEELIN.add_function('string join two', proc { |a, b| "#{a}#{b}" })
|
|
34
|
+
expect(FEELIN.evaluate('string join two("a", "b")')).to eq 'ab'
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
describe "temporal results" do
|
|
40
|
+
it "answers a date, a time and a duration in their ISO 8601 form" do
|
|
41
|
+
expect(FEELIN.evaluate('date("2020-01-02")')).to eq '2020-01-02'
|
|
42
|
+
expect(FEELIN.evaluate('time("10:00:00+03:00")')).to eq '10:00:00+03:00'
|
|
43
|
+
expect(FEELIN.evaluate('date and time("2020-01-02T03:04:05Z")')).to eq '2020-01-02T03:04:05Z'
|
|
44
|
+
expect(FEELIN.evaluate('duration("P1DT2H")')).to eq 'P1DT2H'
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "does so inside a list and a context too" do
|
|
48
|
+
expect(FEELIN.evaluate('{ on: date(day) + duration("P1D"), all: [ @"2020-01-02" ] }', { 'day' => '2020-05-06' }))
|
|
49
|
+
.to eq('on' => '2020-05-07', 'all' => [ '2020-01-02' ])
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "answers null for what has no value" do
|
|
53
|
+
expect(FEELIN.evaluate('missing')).to be_nil
|
|
54
|
+
expect(FEELIN.evaluate('{ a: missing }')).to eq('a' => nil)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe FEELIN::Context do
|
|
59
|
+
it "evaluates in a context of its own, with its own functions" do
|
|
60
|
+
context = FEELIN::Context.new
|
|
61
|
+
context.add_function('only here', proc { 7 })
|
|
62
|
+
|
|
63
|
+
expect(context.evaluate('only here() + n', { 'n' => 1 })).to eq 8
|
|
64
|
+
expect(FEELIN.evaluate('only here()')).to be_nil
|
|
65
|
+
ensure
|
|
66
|
+
context&.dispose
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "stops an expression that runs past its timeout" do
|
|
70
|
+
context = FEELIN::Context.new(timeout: 50)
|
|
71
|
+
|
|
72
|
+
expect { context.evaluate('count(for a in 1..3000, b in 1..3000 return a * b)') }
|
|
73
|
+
.to raise_error(MiniRacer::ScriptTerminatedError)
|
|
74
|
+
ensure
|
|
75
|
+
context&.dispose
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# the context reaches V8 as an argument, not as the text of a script: a script
|
|
79
|
+
# per distinct context is compiled and kept, and ran a limited context out of
|
|
80
|
+
# memory
|
|
81
|
+
it "evaluates over context after context without its memory growing" do
|
|
82
|
+
context = FEELIN::Context.new(max_memory: 8_000_000)
|
|
83
|
+
|
|
84
|
+
results = Array.new(10_000) { |index| context.evaluate('"L" + string(old.n)', { 'old' => { 'n' => index } }) }
|
|
85
|
+
|
|
86
|
+
expect(results.values_at(0, 9_999)).to eq %w[L0 L9999]
|
|
87
|
+
ensure
|
|
88
|
+
context&.dispose
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
describe "syntax errors" do
|
|
93
|
+
it "raises on an expression that does not parse" do
|
|
94
|
+
expect { FEELIN.evaluate('1 +') }.to raise_error(MiniRacer::RuntimeError, /Incomplete <ArithmeticExpression>/)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
describe "#parse" do
|
|
99
|
+
# the types of a tree, nested as the tree is, tokens left out
|
|
100
|
+
def shape(node)
|
|
101
|
+
children = node['children'].reject { |child| child['children'].empty? && child['type'] !~ /\A[A-Z]/ }
|
|
102
|
+
children.empty? ? node['type'] : { node['type'] => children.map { |child| shape(child) } }
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "answers the syntax tree without evaluating the expression" do
|
|
106
|
+
tree = FEELIN.parse('a.b + 1 > 2')
|
|
107
|
+
|
|
108
|
+
expect(shape(tree)).to eq(
|
|
109
|
+
'Expression' => [ {
|
|
110
|
+
'Comparison' => [
|
|
111
|
+
{ 'ArithmeticExpression' => [
|
|
112
|
+
{ 'PathExpression' => [ { 'VariableName' => [ 'Identifier' ] }, { 'PathName' => [ 'Identifier' ] } ] },
|
|
113
|
+
'ArithOp',
|
|
114
|
+
'NumericLiteral'
|
|
115
|
+
] },
|
|
116
|
+
'CompareOp',
|
|
117
|
+
'NumericLiteral'
|
|
118
|
+
]
|
|
119
|
+
} ]
|
|
120
|
+
)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "gives every node its span and its text" do
|
|
124
|
+
comparison = FEELIN.parse('a.b + 1 > 2')['children'].first
|
|
125
|
+
|
|
126
|
+
expect(comparison.slice('type', 'from', 'to', 'text')).to eq('type' => 'Comparison', 'from' => 0, 'to' => 11, 'text' => 'a.b + 1 > 2')
|
|
127
|
+
expect(comparison['children'].map { |child| child['text'] }).to eq [ 'a.b + 1', '>', '2' ]
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it "reads a name with spaces as one name when the context has it" do
|
|
131
|
+
tree = FEELIN.parse("Mike's daughter.name + 1", { "Mike's daughter.name" => 'Lisa' })
|
|
132
|
+
name = tree['children'].first['children'].first
|
|
133
|
+
|
|
134
|
+
expect(name.slice('type', 'text')).to eq('type' => 'VariableName', 'text' => "Mike's daughter.name")
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it "raises on an expression that does not parse, as evaluate does" do
|
|
138
|
+
expect { FEELIN.parse('1 +') }.to raise_error(MiniRacer::RuntimeError, /Incomplete <ArithmeticExpression>/)
|
|
139
|
+
expect { FEELIN.parse('1 + ) 2') }.to raise_error(MiniRacer::RuntimeError, /Unrecognized token/)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it "reports a syntax error as evaluate reports it" do
|
|
143
|
+
[ '1 +', '{ a: 1', 'if x then', '1 + ) 2', '1 2', '[1, 2' ].each do |expression|
|
|
144
|
+
expected = begin
|
|
145
|
+
FEELIN.evaluate(expression)
|
|
146
|
+
rescue MiniRacer::RuntimeError => e
|
|
147
|
+
e.message
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
expect { FEELIN.parse(expression) }.to raise_error(MiniRacer::RuntimeError, expected), expression
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
describe "#parse_unary_tests" do
|
|
156
|
+
it "answers the syntax tree of unary tests" do
|
|
157
|
+
tree = FEELIN.parse_unary_tests('[1..end], > 5')
|
|
158
|
+
tests = tree['children'].first['children'].select { |child| child['type'] == 'PositiveUnaryTest' }
|
|
159
|
+
|
|
160
|
+
expect(tree['type']).to eq 'UnaryTests'
|
|
161
|
+
expect(tests.map { |test| test['text'] }).to eq [ '[1..end]', '> 5' ]
|
|
162
|
+
end
|
|
23
163
|
end
|
|
24
164
|
|
|
25
165
|
describe "#unary_test" do
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: feelin
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 7.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dmitry Arkhipov
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: mini_racer
|
|
@@ -16,14 +15,14 @@ dependencies:
|
|
|
16
15
|
requirements:
|
|
17
16
|
- - "~>"
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '0.
|
|
18
|
+
version: '0.21'
|
|
20
19
|
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - "~>"
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '0.
|
|
25
|
+
version: '0.21'
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
27
|
name: rspec
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -68,105 +67,8 @@ files:
|
|
|
68
67
|
- README.md
|
|
69
68
|
- feelin.gemspec
|
|
70
69
|
- lib/feelin.rb
|
|
71
|
-
- lib/feelin/js/
|
|
72
|
-
- lib/feelin/js/
|
|
73
|
-
- lib/feelin/js/node_modules/@lezer/common/README.md
|
|
74
|
-
- lib/feelin/js/node_modules/@lezer/common/dist/index.cjs
|
|
75
|
-
- lib/feelin/js/node_modules/@lezer/common/dist/index.d.cts
|
|
76
|
-
- lib/feelin/js/node_modules/@lezer/common/dist/index.d.ts
|
|
77
|
-
- lib/feelin/js/node_modules/@lezer/common/dist/index.js
|
|
78
|
-
- lib/feelin/js/node_modules/@lezer/common/package.json
|
|
79
|
-
- lib/feelin/js/node_modules/@lezer/highlight/LICENSE
|
|
80
|
-
- lib/feelin/js/node_modules/@lezer/highlight/README.md
|
|
81
|
-
- lib/feelin/js/node_modules/@lezer/highlight/dist/index.cjs
|
|
82
|
-
- lib/feelin/js/node_modules/@lezer/highlight/dist/index.d.cts
|
|
83
|
-
- lib/feelin/js/node_modules/@lezer/highlight/dist/index.d.ts
|
|
84
|
-
- lib/feelin/js/node_modules/@lezer/highlight/dist/index.js
|
|
85
|
-
- lib/feelin/js/node_modules/@lezer/highlight/package.json
|
|
86
|
-
- lib/feelin/js/node_modules/@lezer/lr/LICENSE
|
|
87
|
-
- lib/feelin/js/node_modules/@lezer/lr/README.md
|
|
88
|
-
- lib/feelin/js/node_modules/@lezer/lr/dist/constants.d.ts
|
|
89
|
-
- lib/feelin/js/node_modules/@lezer/lr/dist/constants.js
|
|
90
|
-
- lib/feelin/js/node_modules/@lezer/lr/dist/index.cjs
|
|
91
|
-
- lib/feelin/js/node_modules/@lezer/lr/dist/index.d.cts
|
|
92
|
-
- lib/feelin/js/node_modules/@lezer/lr/dist/index.d.ts
|
|
93
|
-
- lib/feelin/js/node_modules/@lezer/lr/dist/index.js
|
|
94
|
-
- lib/feelin/js/node_modules/@lezer/lr/package.json
|
|
95
|
-
- lib/feelin/js/node_modules/feelin/LICENSE
|
|
96
|
-
- lib/feelin/js/node_modules/feelin/README.md
|
|
97
|
-
- lib/feelin/js/node_modules/feelin/dist/builtins.d.ts
|
|
98
|
-
- lib/feelin/js/node_modules/feelin/dist/index.cjs
|
|
99
|
-
- lib/feelin/js/node_modules/feelin/dist/index.cjs.map
|
|
100
|
-
- lib/feelin/js/node_modules/feelin/dist/index.d.ts
|
|
101
|
-
- lib/feelin/js/node_modules/feelin/dist/index.esm.js
|
|
102
|
-
- lib/feelin/js/node_modules/feelin/dist/index.esm.js.map
|
|
103
|
-
- lib/feelin/js/node_modules/feelin/dist/interpreter.d.ts
|
|
104
|
-
- lib/feelin/js/node_modules/feelin/dist/parser.d.ts
|
|
105
|
-
- lib/feelin/js/node_modules/feelin/dist/temporal.d.ts
|
|
106
|
-
- lib/feelin/js/node_modules/feelin/dist/types.d.ts
|
|
107
|
-
- lib/feelin/js/node_modules/feelin/dist/utils.d.ts
|
|
108
|
-
- lib/feelin/js/node_modules/feelin/package.json
|
|
109
|
-
- lib/feelin/js/node_modules/lezer-feel/LICENSE
|
|
110
|
-
- lib/feelin/js/node_modules/lezer-feel/README.md
|
|
111
|
-
- lib/feelin/js/node_modules/lezer-feel/dist/index.cjs
|
|
112
|
-
- lib/feelin/js/node_modules/lezer-feel/dist/index.cjs.map
|
|
113
|
-
- lib/feelin/js/node_modules/lezer-feel/dist/index.d.ts
|
|
114
|
-
- lib/feelin/js/node_modules/lezer-feel/dist/index.js
|
|
115
|
-
- lib/feelin/js/node_modules/lezer-feel/dist/index.js.map
|
|
116
|
-
- lib/feelin/js/node_modules/lezer-feel/package.json
|
|
117
|
-
- lib/feelin/js/node_modules/luxon/LICENSE.md
|
|
118
|
-
- lib/feelin/js/node_modules/luxon/README.md
|
|
119
|
-
- lib/feelin/js/node_modules/luxon/build/amd/luxon.js
|
|
120
|
-
- lib/feelin/js/node_modules/luxon/build/amd/luxon.js.map
|
|
121
|
-
- lib/feelin/js/node_modules/luxon/build/cjs-browser/luxon.js
|
|
122
|
-
- lib/feelin/js/node_modules/luxon/build/cjs-browser/luxon.js.map
|
|
123
|
-
- lib/feelin/js/node_modules/luxon/build/es6/luxon.js
|
|
124
|
-
- lib/feelin/js/node_modules/luxon/build/es6/luxon.js.map
|
|
125
|
-
- lib/feelin/js/node_modules/luxon/build/global/luxon.js
|
|
126
|
-
- lib/feelin/js/node_modules/luxon/build/global/luxon.js.map
|
|
127
|
-
- lib/feelin/js/node_modules/luxon/build/global/luxon.min.js
|
|
128
|
-
- lib/feelin/js/node_modules/luxon/build/global/luxon.min.js.map
|
|
129
|
-
- lib/feelin/js/node_modules/luxon/build/node/luxon.js
|
|
130
|
-
- lib/feelin/js/node_modules/luxon/build/node/luxon.js.map
|
|
131
|
-
- lib/feelin/js/node_modules/luxon/package.json
|
|
132
|
-
- lib/feelin/js/node_modules/luxon/src/datetime.js
|
|
133
|
-
- lib/feelin/js/node_modules/luxon/src/duration.js
|
|
134
|
-
- lib/feelin/js/node_modules/luxon/src/errors.js
|
|
135
|
-
- lib/feelin/js/node_modules/luxon/src/impl/conversions.js
|
|
136
|
-
- lib/feelin/js/node_modules/luxon/src/impl/diff.js
|
|
137
|
-
- lib/feelin/js/node_modules/luxon/src/impl/digits.js
|
|
138
|
-
- lib/feelin/js/node_modules/luxon/src/impl/english.js
|
|
139
|
-
- lib/feelin/js/node_modules/luxon/src/impl/formats.js
|
|
140
|
-
- lib/feelin/js/node_modules/luxon/src/impl/formatter.js
|
|
141
|
-
- lib/feelin/js/node_modules/luxon/src/impl/invalid.js
|
|
142
|
-
- lib/feelin/js/node_modules/luxon/src/impl/locale.js
|
|
143
|
-
- lib/feelin/js/node_modules/luxon/src/impl/regexParser.js
|
|
144
|
-
- lib/feelin/js/node_modules/luxon/src/impl/tokenParser.js
|
|
145
|
-
- lib/feelin/js/node_modules/luxon/src/impl/util.js
|
|
146
|
-
- lib/feelin/js/node_modules/luxon/src/impl/zoneUtil.js
|
|
147
|
-
- lib/feelin/js/node_modules/luxon/src/info.js
|
|
148
|
-
- lib/feelin/js/node_modules/luxon/src/interval.js
|
|
149
|
-
- lib/feelin/js/node_modules/luxon/src/luxon.js
|
|
150
|
-
- lib/feelin/js/node_modules/luxon/src/package.json
|
|
151
|
-
- lib/feelin/js/node_modules/luxon/src/settings.js
|
|
152
|
-
- lib/feelin/js/node_modules/luxon/src/zone.js
|
|
153
|
-
- lib/feelin/js/node_modules/luxon/src/zones/IANAZone.js
|
|
154
|
-
- lib/feelin/js/node_modules/luxon/src/zones/fixedOffsetZone.js
|
|
155
|
-
- lib/feelin/js/node_modules/luxon/src/zones/invalidZone.js
|
|
156
|
-
- lib/feelin/js/node_modules/luxon/src/zones/systemZone.js
|
|
157
|
-
- lib/feelin/js/node_modules/min-dash/LICENSE
|
|
158
|
-
- lib/feelin/js/node_modules/min-dash/README.md
|
|
159
|
-
- lib/feelin/js/node_modules/min-dash/dist/array.d.ts
|
|
160
|
-
- lib/feelin/js/node_modules/min-dash/dist/collection.d.ts
|
|
161
|
-
- lib/feelin/js/node_modules/min-dash/dist/fn.d.ts
|
|
162
|
-
- lib/feelin/js/node_modules/min-dash/dist/index.cjs
|
|
163
|
-
- lib/feelin/js/node_modules/min-dash/dist/index.d.ts
|
|
164
|
-
- lib/feelin/js/node_modules/min-dash/dist/index.esm.js
|
|
165
|
-
- lib/feelin/js/node_modules/min-dash/dist/lang.d.ts
|
|
166
|
-
- lib/feelin/js/node_modules/min-dash/dist/min-dash.js
|
|
167
|
-
- lib/feelin/js/node_modules/min-dash/dist/min-dash.min.js
|
|
168
|
-
- lib/feelin/js/node_modules/min-dash/dist/object.d.ts
|
|
169
|
-
- lib/feelin/js/node_modules/min-dash/package.json
|
|
70
|
+
- lib/feelin/js/dist/feelin.js
|
|
71
|
+
- lib/feelin/js/entry.js
|
|
170
72
|
- lib/feelin/js/package-lock.json
|
|
171
73
|
- lib/feelin/js/package.json
|
|
172
74
|
- lib/feelin/version.rb
|
|
@@ -175,8 +77,10 @@ files:
|
|
|
175
77
|
homepage: https://github.com/ekzo-dev/ruby-feelin
|
|
176
78
|
licenses:
|
|
177
79
|
- MIT
|
|
178
|
-
metadata:
|
|
179
|
-
|
|
80
|
+
metadata:
|
|
81
|
+
homepage_uri: https://github.com/ekzo-dev/ruby-feelin
|
|
82
|
+
source_code_uri: https://github.com/ekzo-dev/ruby-feelin
|
|
83
|
+
changelog_uri: https://github.com/ekzo-dev/ruby-feelin/CHANGELOG.md
|
|
180
84
|
rdoc_options: []
|
|
181
85
|
require_paths:
|
|
182
86
|
- lib
|
|
@@ -191,8 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
191
95
|
- !ruby/object:Gem::Version
|
|
192
96
|
version: '0'
|
|
193
97
|
requirements: []
|
|
194
|
-
rubygems_version: 3.
|
|
195
|
-
signing_key:
|
|
98
|
+
rubygems_version: 3.6.9
|
|
196
99
|
specification_version: 4
|
|
197
100
|
summary: feelin Ruby wrapper
|
|
198
101
|
test_files: []
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "js",
|
|
3
|
-
"lockfileVersion": 3,
|
|
4
|
-
"requires": true,
|
|
5
|
-
"packages": {
|
|
6
|
-
"node_modules/@lezer/common": {
|
|
7
|
-
"version": "1.2.3",
|
|
8
|
-
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz",
|
|
9
|
-
"integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA=="
|
|
10
|
-
},
|
|
11
|
-
"node_modules/@lezer/highlight": {
|
|
12
|
-
"version": "1.2.1",
|
|
13
|
-
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz",
|
|
14
|
-
"integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==",
|
|
15
|
-
"dependencies": {
|
|
16
|
-
"@lezer/common": "^1.0.0"
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"node_modules/@lezer/lr": {
|
|
20
|
-
"version": "1.4.2",
|
|
21
|
-
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz",
|
|
22
|
-
"integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==",
|
|
23
|
-
"dependencies": {
|
|
24
|
-
"@lezer/common": "^1.0.0"
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
"node_modules/feelin": {
|
|
28
|
-
"version": "4.3.0",
|
|
29
|
-
"resolved": "https://registry.npmjs.org/feelin/-/feelin-4.3.0.tgz",
|
|
30
|
-
"integrity": "sha512-Uv3YNCrmXSXgkCJSfa2jR7SL/acjPhfEHKNsaL///fRJxD7epUvUJyF1WXbh8oh9Myv+z3WVClGb+rIuT7LDow==",
|
|
31
|
-
"dependencies": {
|
|
32
|
-
"@lezer/lr": "^1.4.2",
|
|
33
|
-
"lezer-feel": "^1.6.0",
|
|
34
|
-
"luxon": "^3.5.0"
|
|
35
|
-
},
|
|
36
|
-
"engines": {
|
|
37
|
-
"node": "*"
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
"node_modules/lezer-feel": {
|
|
41
|
-
"version": "1.7.0",
|
|
42
|
-
"resolved": "https://registry.npmjs.org/lezer-feel/-/lezer-feel-1.7.0.tgz",
|
|
43
|
-
"integrity": "sha512-UC8h3Nu4llRPISEUhv+Ne7bNkdxjf4+/DcU4KfO8zKxycWxev8d2BoVnGlG17zbQDtQJBD39ZQvWtjCeTFm69g==",
|
|
44
|
-
"dependencies": {
|
|
45
|
-
"@lezer/highlight": "^1.2.1",
|
|
46
|
-
"@lezer/lr": "^1.4.2",
|
|
47
|
-
"min-dash": "^4.2.1"
|
|
48
|
-
},
|
|
49
|
-
"engines": {
|
|
50
|
-
"node": "*"
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
"node_modules/luxon": {
|
|
54
|
-
"version": "3.6.0",
|
|
55
|
-
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.6.0.tgz",
|
|
56
|
-
"integrity": "sha512-WE7p0p7W1xji9qxkLYsvcIxZyfP48GuFrWIBQZIsbjCyf65dG1rv4n83HcOyEyhvzxJCrUoObCRNFgRNIQ5KNA==",
|
|
57
|
-
"engines": {
|
|
58
|
-
"node": ">=12"
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
"node_modules/min-dash": {
|
|
62
|
-
"version": "4.2.3",
|
|
63
|
-
"resolved": "https://registry.npmjs.org/min-dash/-/min-dash-4.2.3.tgz",
|
|
64
|
-
"integrity": "sha512-VLMYQI5+FcD9Ad24VcB08uA83B07OhueAlZ88jBK6PyupTvEJwllTMUqMy0wPGYs7pZUEtEEMWdHB63m3LtEcg=="
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (C) 2018 by Marijn Haverbeke <marijn@haverbeke.berlin> and others
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in
|
|
13
|
-
all copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
-
THE SOFTWARE.
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# @lezer/common
|
|
2
|
-
|
|
3
|
-
[ [**WEBSITE**](http://lezer.codemirror.net) | [**ISSUES**](https://github.com/lezer-parser/lezer/issues) | [**FORUM**](https://discuss.codemirror.net/c/lezer) | [**CHANGELOG**](https://github.com/lezer-parser/common/blob/master/CHANGELOG.md) ]
|
|
4
|
-
|
|
5
|
-
[Lezer](https://lezer.codemirror.net/) is an incremental parser system
|
|
6
|
-
intended for use in an editor or similar system.
|
|
7
|
-
|
|
8
|
-
@lezer/common provides the syntax tree data structure and parser
|
|
9
|
-
abstractions for Lezer parsers.
|
|
10
|
-
|
|
11
|
-
Its programming interface is documented on [the
|
|
12
|
-
website](https://lezer.codemirror.net/docs/ref/#common).
|
|
13
|
-
|
|
14
|
-
This code is licensed under an MIT license.
|