marty 2.5.6 → 2.5.7
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/.rubocop.yml +6 -0
- data/Gemfile.lock +1 -1
- data/app/components/marty/base_rule_view.rb +68 -37
- data/app/models/marty/promise.rb +11 -0
- data/delorean/promises.dl +5 -0
- data/lib/marty/rule_script_set.rb +20 -10
- data/lib/marty/version.rb +1 -1
- data/spec/controllers/rpc_controller_spec.rb +35 -0
- data/spec/dummy/lib/gemini/xyz_rule_script_set.rb +10 -4
- data/spec/features/rule_spec.rb +43 -31
- data/spec/fixtures/csv/rule/MyRule.csv +1 -1
- data/spec/models/rule_spec.rb +36 -22
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e21e7788214cabe5b48e33e15fbefcdbc30ba526f1a8870a3c5c7ab240b48b4d
|
4
|
+
data.tar.gz: 285129ffcd5648deeaa816a7923efc6b146adc01ba2a75624f0a5944063c7372
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 16931641ca8a4478ee399f24fe50398989d35aae7353efebd550e371ad76d45de9faf465f4e139cf4bbb28ae5502fb734f0be49de1f9e054d2d85369c059b190
|
7
|
+
data.tar.gz: de0f280f2a9d0077134e8d717d2e5882c0e35cb3909b9049b4127435b9cb34040bdc8de5081946be80e5085325aee769e48fe8906a919f07fcdc217486e2cf3e
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -51,50 +51,81 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
|
54
|
+
# FSM to parse rule text into json
|
55
|
+
def self.ruletext_to_hash(s)
|
56
|
+
# states are
|
57
|
+
# :start - before any attr is defined
|
58
|
+
# :in_attr - defining an attr
|
59
|
+
# :end - end of input
|
60
|
+
state = :start
|
55
61
|
result = {}
|
56
|
-
|
57
|
-
|
58
|
-
s.lines
|
59
|
-
|
62
|
+
cur_attr = nil
|
63
|
+
idx = 0
|
64
|
+
input = s.lines
|
65
|
+
|
66
|
+
# events are
|
67
|
+
# :attr - starting with <identifier>\s*=
|
68
|
+
# :normal - line not starting with ident =
|
69
|
+
# :end - no more lines
|
70
|
+
# get_event returns [event, data]
|
71
|
+
get_event = lambda {
|
72
|
+
line = input.try(&:shift)
|
73
|
+
next [:end] unless line
|
60
74
|
|
61
75
|
line.chomp!
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
76
|
+
idx += 1
|
77
|
+
m = /\A\s*([a-z][a-z0-9_]*)\s* = (.*)\z/.match(line)
|
78
|
+
next [:attr, m[1..-1]] if m
|
79
|
+
|
80
|
+
[:normal, line]
|
81
|
+
}
|
82
|
+
|
83
|
+
# start a new attribute
|
84
|
+
# data is [ attr_name, everything after = ]
|
85
|
+
new_attr = lambda { |data|
|
86
|
+
cur_attr = data.shift
|
87
|
+
raise DupKeyError.new(cur_attr, idx) if result[cur_attr]
|
73
88
|
|
74
|
-
|
89
|
+
result[cur_attr] = data[0]
|
90
|
+
}
|
91
|
+
|
92
|
+
begin
|
93
|
+
while state != :end
|
94
|
+
event, extra = get_event.call
|
95
|
+
case state
|
96
|
+
when :start
|
97
|
+
case event
|
98
|
+
when :attr
|
99
|
+
new_attr.call(extra)
|
100
|
+
state = :in_attr
|
101
|
+
when :normal
|
102
|
+
raise
|
103
|
+
when :end
|
104
|
+
state = :end
|
105
|
+
end
|
106
|
+
when :in_attr
|
107
|
+
case event
|
108
|
+
when :attr
|
109
|
+
new_attr.call(extra)
|
110
|
+
when :normal
|
111
|
+
result[cur_attr] += "\n" + extra
|
112
|
+
when :end
|
113
|
+
state = :end
|
114
|
+
end
|
75
115
|
end
|
76
|
-
rescue DupKeyError => e
|
77
|
-
raise
|
78
|
-
rescue StandardError => e
|
79
|
-
raise "syntax error on line #{idx}"
|
80
116
|
end
|
117
|
+
rescue DupKeyError => e
|
118
|
+
raise
|
119
|
+
rescue StandardError => e
|
120
|
+
raise "syntax error on line #{idx}"
|
81
121
|
end
|
82
122
|
result
|
83
123
|
end
|
84
124
|
|
85
|
-
def self.
|
86
|
-
|
87
|
-
|
88
|
-
lhs_wid = h.keys.map(&:length).max
|
89
|
-
fmt = "%-#{lhs_wid}s = %s"
|
90
|
-
result = []
|
91
|
-
h.map do |k, vstr|
|
92
|
-
vlines = vstr.lines.map(&:chomp)
|
93
|
-
fst = vlines.shift
|
94
|
-
result << fmt % [k, fst]
|
95
|
-
vlines.each { |l| result << ' ' * (lhs_wid + 3) + l }
|
125
|
+
def self.hash_to_ruletext(h)
|
126
|
+
h.each_with_object('') do |(k, v), out|
|
127
|
+
out << k + ' = ' + v + "\n"
|
96
128
|
end
|
97
|
-
result.join("\n")
|
98
129
|
end
|
99
130
|
|
100
131
|
def jsonb_getter(c)
|
@@ -102,7 +133,7 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
102
133
|
end
|
103
134
|
|
104
135
|
def jsonb_simple_getter(c)
|
105
|
-
lambda { |r| Marty::BaseRuleView.
|
136
|
+
lambda { |r| Marty::BaseRuleView.hash_to_ruletext(r.send(c)) }
|
106
137
|
end
|
107
138
|
|
108
139
|
def jsonb_simple_setter(c)
|
@@ -111,7 +142,7 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
111
142
|
return r.send(msg, nil) if v.blank?
|
112
143
|
|
113
144
|
begin
|
114
|
-
final = Marty::BaseRuleView.
|
145
|
+
final = Marty::BaseRuleView.ruletext_to_hash(v)
|
115
146
|
rescue StandardError => e
|
116
147
|
final = { "~~ERROR~~": e.message }
|
117
148
|
end
|
@@ -205,14 +236,14 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
205
236
|
[jsonb_field(:computed_guards,
|
206
237
|
getter: jsonb_simple_getter(:computed_guards),
|
207
238
|
setter: jsonb_simple_setter(:computed_guards),
|
208
|
-
height:
|
239
|
+
height: 100)]
|
209
240
|
end
|
210
241
|
|
211
242
|
def form_items_results
|
212
243
|
[jsonb_field(:results,
|
213
244
|
getter: jsonb_simple_getter(:results),
|
214
245
|
setter: jsonb_simple_setter(:results),
|
215
|
-
height:
|
246
|
+
height: 225)]
|
216
247
|
end
|
217
248
|
|
218
249
|
def default_form_items
|
data/app/models/marty/promise.rb
CHANGED
@@ -200,4 +200,15 @@ class Marty::Promise < Marty::Base
|
|
200
200
|
raw_conn.exec("UNLISTEN promise_#{id}")
|
201
201
|
end
|
202
202
|
end
|
203
|
+
|
204
|
+
delorean_fn :result_and_status, sig: 1 do |promise_id|
|
205
|
+
promise = find_by(id: promise_id)
|
206
|
+
next { error: 'not found' } if promise.nil?
|
207
|
+
|
208
|
+
{
|
209
|
+
completed: !promise.status.nil?,
|
210
|
+
status: promise.status,
|
211
|
+
result: promise.result
|
212
|
+
}
|
213
|
+
end
|
203
214
|
end
|
@@ -34,7 +34,7 @@ class Marty::RuleScriptSet < Delorean::AbstractContainer
|
|
34
34
|
|
35
35
|
def write_attr(k, v)
|
36
36
|
equals, rhs = v == :parameter ? [' =?', ''] :
|
37
|
-
[' =',
|
37
|
+
[' =', v.lines.map { |l| ' ' * 8 + l }.join]
|
38
38
|
k + equals + rhs
|
39
39
|
end
|
40
40
|
|
@@ -129,14 +129,23 @@ class Marty::RuleScriptSet < Delorean::AbstractContainer
|
|
129
129
|
end
|
130
130
|
|
131
131
|
def get_parse_error_field(ruleh, exc)
|
132
|
-
line = exc.line
|
133
|
-
errs = code_section_counts(ruleh)
|
134
|
-
|
135
|
-
|
136
|
-
line_count += v
|
137
|
-
return k if line <= line_count
|
132
|
+
line = (exc.line || 1) - 1
|
133
|
+
errs = { class_body: self.class.body_lines } + code_section_counts(ruleh)
|
134
|
+
ranges0 = errs.values.reduce([0]) do |acc, len|
|
135
|
+
acc + [acc.last + len]
|
138
136
|
end
|
139
|
-
errs.keys.
|
137
|
+
ranges = errs.keys.zip(ranges0.each_cons(2).to_a)
|
138
|
+
secnm, (st, en) = ranges.detect do |sec, (st, en)|
|
139
|
+
line.between?(st, en - 1)
|
140
|
+
end
|
141
|
+
[secnm, line - st + 1]
|
142
|
+
rescue StandardError => e
|
143
|
+
Marty::Logger.error('RuleScriptSet#get_parse_error_field',
|
144
|
+
error: e.message,
|
145
|
+
backtrace: e.backtrace,
|
146
|
+
ruleh: ruleh,
|
147
|
+
line: line)
|
148
|
+
['Unknown', 0]
|
140
149
|
end
|
141
150
|
|
142
151
|
def get_engine(ruleh)
|
@@ -175,9 +184,10 @@ class Marty::RuleScriptSet < Delorean::AbstractContainer
|
|
175
184
|
@@engines[[pt, sname]] = sset.parse_check(sname, get_code(ruleh))
|
176
185
|
end
|
177
186
|
rescue Delorean::ParseError => e
|
178
|
-
|
187
|
+
secnm, line = get_parse_error_field(ruleh, e)
|
179
188
|
msg = e.message.capitalize
|
180
|
-
raise "Error in rule '#{ruleh['name']}' field '#{
|
189
|
+
raise "Error in rule '#{ruleh['name']}' field '#{secnm}' "\
|
190
|
+
"(line #{line}): #{msg}"
|
181
191
|
end
|
182
192
|
|
183
193
|
def self.indent(s)
|
data/lib/marty/version.rb
CHANGED
@@ -524,6 +524,41 @@ describe Marty::RpcController do
|
|
524
524
|
Delayed::Worker.delay_jobs = true
|
525
525
|
end
|
526
526
|
|
527
|
+
it 'should be able to get background job status' do
|
528
|
+
Delayed::Worker.delay_jobs = false
|
529
|
+
|
530
|
+
post 'evaluate', params: {
|
531
|
+
format: :json,
|
532
|
+
script: 'M1',
|
533
|
+
node: 'B',
|
534
|
+
attrs: 'e',
|
535
|
+
tag: t1.name,
|
536
|
+
params: { a: 333, d: 5 }.to_json,
|
537
|
+
background: true,
|
538
|
+
}
|
539
|
+
|
540
|
+
res = ActiveSupport::JSON.decode response.body
|
541
|
+
expect(res).to include('job_id')
|
542
|
+
job_id = res['job_id']
|
543
|
+
|
544
|
+
marty_whodunnit
|
545
|
+
Marty::Script.load_scripts(File.join(Rails.root, '../../delorean'), Date.today)
|
546
|
+
|
547
|
+
post 'evaluate', params: {
|
548
|
+
format: :json,
|
549
|
+
script: 'Promises',
|
550
|
+
node: 'Status',
|
551
|
+
attrs: 'result',
|
552
|
+
params: { promise_id: job_id }.to_json
|
553
|
+
}
|
554
|
+
|
555
|
+
res = ActiveSupport::JSON.decode response.body
|
556
|
+
expect(res['completed']).to be true
|
557
|
+
expect(res['result']).to eq('e' => 4)
|
558
|
+
|
559
|
+
Delayed::Worker.delay_jobs = true
|
560
|
+
end
|
561
|
+
|
527
562
|
it 'should be able to post background job with non-array attr' do
|
528
563
|
Delayed::Worker.delay_jobs = false
|
529
564
|
post 'evaluate', params: {
|
@@ -5,18 +5,24 @@ class Gemini::XyzRuleScriptSet < Marty::RuleScriptSet
|
|
5
5
|
def self.body_start
|
6
6
|
"import BaseCode\n#{node_name}: BaseCode::BaseCode\n"
|
7
7
|
end
|
8
|
+
def xyz_header
|
9
|
+
"XyzNode:\n xyz_param =? nil\n"
|
10
|
+
end
|
8
11
|
def xyz_code(ruleh)
|
9
|
-
write_code(ruleh["computed_guards"].select{|k,_|k.starts_with?("xyz_")})
|
12
|
+
c = write_code(ruleh["computed_guards"].select{|k,_|k.starts_with?("xyz_")})
|
13
|
+
c.blank? ? '' : self.class.indent(c)
|
10
14
|
end
|
11
15
|
def guard_code(ruleh)
|
12
16
|
write_code(ruleh["computed_guards"].reject{|k,_|k.starts_with?("xyz_")})
|
13
17
|
end
|
14
18
|
def get_code(ruleh)
|
15
19
|
x = xyz_code(ruleh)
|
16
|
-
super +
|
17
|
-
|
20
|
+
super +
|
21
|
+
xyz_header +
|
22
|
+
xyz_code(ruleh)
|
18
23
|
end
|
19
24
|
def code_section_counts(ruleh)
|
20
|
-
super + {
|
25
|
+
super + { xyz_header: xyz_header.count("\n"),
|
26
|
+
xyz: xyz_code(ruleh).count("\n") }
|
21
27
|
end
|
22
28
|
end
|
data/spec/features/rule_spec.rb
CHANGED
@@ -203,7 +203,8 @@ feature 'rule view', js: true do
|
|
203
203
|
fill_in(:computed_guards, with: 'sadf asdf ljsf')
|
204
204
|
press('OK')
|
205
205
|
wait_for_ajax
|
206
|
-
exp = "Computed - Error in rule 'abc' field 'computed_guards':
|
206
|
+
exp = "Computed - Error in rule 'abc' field 'computed_guards': "\
|
207
|
+
'Syntax error on line 1'
|
207
208
|
expect(page).to have_content(exp)
|
208
209
|
sleep 2 # sleep needed for message to clear, otherwise failing tests could
|
209
210
|
# pass due to prior messages
|
@@ -212,84 +213,94 @@ feature 'rule view', js: true do
|
|
212
213
|
fill_in(:computed_guards, with: '0sadf = 123j')
|
213
214
|
press('OK')
|
214
215
|
wait_for_ajax
|
215
|
-
exp = "Computed - Error in rule 'abc' field 'computed_guards':
|
216
|
+
exp = "Computed - Error in rule 'abc' field 'computed_guards': "\
|
217
|
+
'Syntax error on line 1'
|
216
218
|
expect(page).to have_content(exp)
|
217
219
|
sleep 2
|
218
220
|
|
219
221
|
# bad rhs - delorean compile will raise
|
220
|
-
fill_in(:computed_guards, with:
|
222
|
+
fill_in(:computed_guards, with: "x = true\ny = false\nvar = 123j\nz = true")
|
221
223
|
press('OK')
|
222
224
|
wait_for_ajax
|
223
|
-
exp = "Computed - Error in rule 'abc' field 'computed_guards':
|
225
|
+
exp = "Computed - Error in rule 'abc' field 'computed_guards' (line 3): "\
|
226
|
+
'Syntax error'
|
224
227
|
expect(page).to have_content(exp)
|
225
228
|
sleep 2
|
226
229
|
|
227
230
|
fill_in(:computed_guards, with: %Q(var1 = "good"\nvar2 = 123\nvar3 = 123j))
|
228
231
|
press('OK')
|
229
232
|
wait_for_ajax
|
230
|
-
exp = "Computed - Error in rule 'abc' field 'computed_guards':
|
233
|
+
exp = "Computed - Error in rule 'abc' field 'computed_guards' (line 3): "\
|
234
|
+
'Syntax error'
|
231
235
|
expect(page).to have_content(exp)
|
232
236
|
sleep 2
|
233
237
|
|
234
238
|
fill_in(:computed_guards, with: '')
|
235
|
-
fill_in(:results, with: %Q(
|
239
|
+
fill_in(:results, with: %Q(var3 = 123j\nvar1 = "good"\nvar2 = 123))
|
236
240
|
press('OK')
|
237
241
|
wait_for_ajax
|
238
|
-
exp = "Computed - Error in rule 'abc' field 'results':
|
242
|
+
exp = "Computed - Error in rule 'abc' field 'results' (line 1): "\
|
243
|
+
'Syntax error'
|
239
244
|
expect(page).to have_content(exp)
|
240
245
|
sleep 2
|
241
246
|
|
242
|
-
fill_in(:results, with: %Q(abc = "def"\ndef = 5\nxyz=def+10\nsadf asdf lsf))
|
247
|
+
fill_in(:results, with: %Q(abc = "def"\ndef = 5\nxyz = def+10\nsadf asdf lsf))
|
243
248
|
press('OK')
|
244
249
|
wait_for_ajax
|
245
|
-
exp = "Computed - Error in rule 'abc' field 'results': Syntax error"
|
250
|
+
exp = "Computed - Error in rule 'abc' field 'results' (line 4): Syntax error"
|
246
251
|
expect(page).to have_content(exp)
|
247
252
|
sleep 2
|
248
253
|
|
249
254
|
fill_in(:results,
|
250
255
|
with: %Q(abc = "def"\ndef = "abc"\nklm = "3"\nabc = "xyz"))
|
251
|
-
|
252
|
-
|
256
|
+
|
257
|
+
exp = "Computed - Error in rule 'abc' field 'results': Keyword 'abc' "\
|
258
|
+
'specified more than once (line 4)'
|
253
259
|
press('OK')
|
254
260
|
wait_for_ajax
|
255
261
|
expect(page).to have_content(exp)
|
256
262
|
sleep 2
|
257
263
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
if true then 5 else 0
|
264
|
+
klm = " 3 + \n\n# hi mom\n 4 +\n if true then 5 else 0\n\n"
|
265
|
+
bogus = <<-EOL
|
266
|
+
|
267
|
+
# comment line
|
268
|
+
|
264
269
|
EOL
|
265
|
-
|
270
|
+
|
271
|
+
multi_line = <<-EOL
|
266
272
|
abc = "def"
|
267
273
|
def = "abc"
|
268
|
-
klm =
|
269
|
-
4 +
|
270
|
-
if true then 5 else 0
|
274
|
+
klm = #{klm}
|
271
275
|
EOL
|
272
276
|
|
277
|
+
fill_in(:results, with: bogus + multi_line)
|
278
|
+
press('OK')
|
279
|
+
wait_for_ajax
|
280
|
+
exp = "Computed - Error in rule 'abc' field 'results': "\
|
281
|
+
'Syntax error on line 1'
|
282
|
+
expect(page).to have_content(exp)
|
283
|
+
|
273
284
|
fill_in(:results, with: multi_line)
|
274
285
|
press('OK')
|
275
286
|
wait_for_ajax
|
276
287
|
|
277
|
-
# re-edit twice to make sure
|
288
|
+
# re-edit twice to make sure identation and comments are preserved
|
278
289
|
press('Edit')
|
279
290
|
wait_for_ajax
|
280
|
-
expect(find_field(:results).value).to eq(
|
291
|
+
expect(find_field(:results).value).to eq(multi_line)
|
281
292
|
press('OK')
|
282
293
|
wait_for_ajax
|
283
294
|
|
284
295
|
press('Edit')
|
285
296
|
wait_for_ajax
|
286
|
-
expect(find_field(:results).value).to eq(
|
297
|
+
expect(find_field(:results).value).to eq(multi_line)
|
287
298
|
press('OK')
|
288
299
|
wait_for_ajax
|
289
300
|
|
290
301
|
# when stored in rule, all lines of a multi line value s/b stripped
|
291
302
|
r = Gemini::MyRule.where(name: 'abc', obsoleted_dt: 'infinity').first
|
292
|
-
expect(r.results['klm']).to eq(
|
303
|
+
expect(r.results['klm']).to eq(klm)
|
293
304
|
|
294
305
|
# make sure change of key/value order is recognized as a change
|
295
306
|
press('Edit')
|
@@ -302,22 +313,23 @@ EOL
|
|
302
313
|
wait_for_ajax
|
303
314
|
press('Edit')
|
304
315
|
wait_for_ajax
|
305
|
-
val = find_field(:results).value
|
316
|
+
val = find_field(:results).value
|
306
317
|
expect(val).to eq(newval)
|
307
318
|
press('OK')
|
308
319
|
wait_for_ajax
|
309
320
|
|
310
|
-
exp =
|
311
|
-
simple_result
|
321
|
+
exp = <<-EOL
|
322
|
+
simple_result = "c value"
|
312
323
|
computed_value = if paramb
|
313
|
-
|
314
|
-
|
324
|
+
then param1 / (grid1_grid_result||1)
|
325
|
+
else (grid2_grid_result||1) / param1
|
315
326
|
EOL
|
327
|
+
|
316
328
|
names = mrv.get_col_vals(:name, 9, 0)
|
317
329
|
idx = names.index { |n| n == 'Rule3' } + 1
|
318
330
|
mrv.select_row(idx)
|
319
331
|
press('Edit')
|
320
|
-
expect(find_field(:results).value).to eq(exp
|
332
|
+
expect(find_field(:results).value).to eq(exp)
|
321
333
|
press('OK')
|
322
334
|
wait_for_ajax
|
323
335
|
|
@@ -10,6 +10,6 @@ Rule2,SimpleRule,2017-2-1 14:00:00,2017-4-1,true,"{""g_array"":[""G1V2""],""g_si
|
|
10
10
|
Rule2a,SimpleRule,2017-2-1 14:00:00,2017-4-1,true,"{""g_array"":[""G1V2""],""g_single"":""G2V3"",""g_string"":""abc"",""g_bool"":true,""g_range"":""(,50]"",""g_integer"":99}",,,"{""simple_result"":""\""b value\"""", ""sr2"":""true"", ""sr3"": ""123""}"
|
11
11
|
Rule2b,SimpleRule,2017-2-1 14:00:00,2017-4-1,true,"{""g_array"":[""G1V2""],""g_single"":""G2V3"",""g_string"":""abc"",""g_bool"":true,""g_range"":""(,50]"",""g_integer"":999}",,"{""grid1"":""DataGrid1"",""grid2"":""DataGrid2""}",
|
12
12
|
Rule2c,SimpleRule,2017-2-1 14:00:00,2017-4-1,true,"{""g_array"":[""G1V2""],""g_single"":""G2V3"",""g_string"":""abc"",""g_bool"":false,""g_range"":""(,50]"",""g_integer"":10}",,"{""grid1"":""DataGrid1"",""grid2"":""DataGrid2""}",
|
13
|
-
Rule3,ComplexRule,2017-3-1 00:00:00,2017-4-1,false,"{""g_array"":[""G1V2"",""G1V3""],""g_string"":""def"",""g_integer"":11}","{""cguard1"":""1==1"",""cguard2"":""[param2 == 'abc', \""a string\""]""}","{""grid1"":""DataGrid1"",""grid2"":""DataGrid2""}","{""simple_result"":""\""c value\"""",""computed_value"":""if paramb\
|
13
|
+
Rule3,ComplexRule,2017-3-1 00:00:00,2017-4-1,false,"{""g_array"":[""G1V2"",""G1V3""],""g_string"":""def"",""g_integer"":11}","{""cguard1"":""1==1"",""cguard2"":""[param2 == 'abc', \""a string\""]""}","{""grid1"":""DataGrid1"",""grid2"":""DataGrid2""}","{""simple_result"":""\""c value\"""",""computed_value"":""if paramb\n then param1 / (grid1_grid_result||1)\n else (grid2_grid_result||1) / param1""}"
|
14
14
|
Rule4,ComplexRule,2017-4-1 15:00:01,2017-5-1,,"{""g_array"":[""G1V2"",""G1V3""],""g_string"":""Hi Mom"",""g_integer"":11}","{""cguard1"":""1==1"",""cguard2"":""param2 == \""abc\""""}","{""grid1"":""DataGrid1"",""grid2"":""DataGrid2""}","{""computed_name_grid"":""\""DataGrid\""+\""X\"""", ""simple_result"":""computed_name_grid"",""grid_sum"":""computed_name_grid_result + (grid1_grid_result||0)+(grid2_grid_result||0)""}"
|
15
15
|
Rule5,ComplexRule,2017-4-2 15:00:01,2017-5-1,,"{""g_string"":""zzz"",""g_integer"":3757,""g_has_default"":""foo""}","{""cguard1"":""[1==1, \""a string\""]""}",,"{""flavor"": ""[\""cherry\"",\""lemon\""][param2]"",""other_grid"": ""\""DataGrid4\"""",""final_value"": ""other_grid_result * 3""}"
|
data/spec/models/rule_spec.rb
CHANGED
@@ -73,33 +73,44 @@ module Marty::RuleSpec
|
|
73
73
|
it 'detects errors in computed guards' do
|
74
74
|
@rule_type = 'SimpleRule'
|
75
75
|
@computed_guards = { 'guard1' => 'zvjsdf12.z8*' }
|
76
|
-
exp =
|
76
|
+
exp = Regexp.new("Computed - Error in rule 'testrule' field "\
|
77
|
+
"'computed_guards' .line 1.: Syntax error")
|
77
78
|
expect { subject }.to raise_error(exp)
|
78
79
|
end
|
79
80
|
it 'detects errors in computed results' do
|
80
81
|
@rule_type = 'SimpleRule'
|
81
|
-
@results = { '
|
82
|
+
@results = { 'does_compute' => '1+2',
|
83
|
+
'does_not_compute' => 'zvjsdf12.z8*' }
|
82
84
|
@grids = { 'grid1' => 'DataGrid1', 'grid2' => 'DataGrid2' }
|
83
|
-
exp =
|
85
|
+
exp = Regexp.new("Computed - Error in rule 'testrule' field "\
|
86
|
+
"'results' .line 2.: Syntax error")
|
84
87
|
expect { subject }.to raise_error(exp)
|
85
88
|
end
|
86
89
|
it 'detects errors in computed results 2' do
|
87
90
|
@rule_type = 'SimpleRule'
|
88
91
|
@results = { 'does_not_compute' => 'zvjsdf12.z8*' }
|
89
|
-
@grids = { 'grid1' => 'DataGrid1', 'grid2' => 'DataGrid1',
|
90
|
-
|
92
|
+
@grids = { 'grid1' => 'DataGrid1', 'grid2' => 'DataGrid1',
|
93
|
+
'grid3' => 'DataGrid3' }
|
94
|
+
exp = Regexp.new("Computed - Error in rule 'testrule' field "\
|
95
|
+
"'results' .line 1.: Syntax error")
|
91
96
|
expect { subject }.to raise_error(exp)
|
92
97
|
end
|
93
98
|
it 'detects errors in computed results 3' do
|
94
99
|
@rule_type = 'SimpleRule'
|
95
|
-
@results = { '
|
96
|
-
|
97
|
-
|
100
|
+
@results = { 'does_compute' => '1+2',
|
101
|
+
'does_compute2' => '"string".length',
|
102
|
+
'does_not_compute' => 'zvjsdf12.z8*',
|
103
|
+
'does_compute3' => '[does_compute].sum' }
|
104
|
+
@grids = { 'grid1' => 'DataGrid1', 'grid2' => 'DataGrid1',
|
105
|
+
'grid3' => 'DataGrid1' }
|
106
|
+
exp = Regexp.new("Computed - Error in rule 'testrule' field "\
|
107
|
+
"'results' .line 3.: Syntax error")
|
98
108
|
expect { subject }.to raise_error(exp)
|
99
109
|
end
|
100
110
|
it 'reports bad grid names' do
|
101
111
|
@rule_type = 'SimpleRule'
|
102
|
-
@grids = { 'grid1' => 'xyz', 'grid2' => 'DataGrid2',
|
112
|
+
@grids = { 'grid1' => 'xyz', 'grid2' => 'DataGrid2',
|
113
|
+
'grid3' => 'DataGrid1' }
|
103
114
|
exp = /Grids - Bad grid name 'xyz' for 'grid1'/
|
104
115
|
expect { subject }.to raise_error(exp)
|
105
116
|
end
|
@@ -133,19 +144,22 @@ module Marty::RuleSpec
|
|
133
144
|
it 'detects script errors' do
|
134
145
|
@rule_type = 'XRule'
|
135
146
|
@results = { 'x' => 'zx sdf wer' }
|
136
|
-
exp =
|
147
|
+
exp = Regexp.new("Computed - Error in rule 'testrule' field "\
|
148
|
+
"'results' .line 1.: Syntax error")
|
137
149
|
expect { subject }.to raise_error(exp)
|
138
150
|
end
|
139
151
|
it 'rule script stuff overrides 1' do
|
140
152
|
@rule_type = 'XRule'
|
141
153
|
@computed_guards = { 'abc' => 'true', 'xyz_guard' => 'err err err' }
|
142
|
-
exp =
|
154
|
+
exp = Regexp.new("Computed - Error in rule 'testrule' field "\
|
155
|
+
"'xyz' .line 1.: Syntax error")
|
143
156
|
expect { subject }.to raise_error(exp)
|
144
157
|
end
|
145
158
|
it 'rule script stuff overrides 2' do
|
146
159
|
@rule_type = 'XRule'
|
147
160
|
@computed_guards = { 'abc' => 'err err err', 'xyz_guard' => 'xyz_param' }
|
148
|
-
exp =
|
161
|
+
exp = Regexp.new("Computed - Error in rule 'testrule' field "\
|
162
|
+
"'computed_guards' .line 1.: Syntax error")
|
149
163
|
expect { subject }.to raise_error(exp)
|
150
164
|
end
|
151
165
|
it 'rule script stuff overrides 3' do
|
@@ -376,9 +390,9 @@ module Marty::RuleSpec
|
|
376
390
|
rescue Marty::DeloreanRule::ComputeError => e
|
377
391
|
exp = 'no implicit conversion of Integer into String'
|
378
392
|
expect(e.message).to include(exp)
|
379
|
-
expres = [/DELOREAN__XyzRule_\d+_1483228800.0
|
380
|
-
/DELOREAN__XyzRule_\d+_1483228800.0
|
381
|
-
/DELOREAN__XyzRule_\d+_1483228800.0
|
393
|
+
expres = [/DELOREAN__XyzRule_\d+_1483228800.0:\d+:in .+'/,
|
394
|
+
/DELOREAN__XyzRule_\d+_1483228800.0:\d+:in .tmp_var4__D'/,
|
395
|
+
/DELOREAN__XyzRule_\d+_1483228800.0:\d+:in .bv__D'/]
|
382
396
|
expres.each_with_index do |expre, i|
|
383
397
|
expect(e.backtrace[i]).to match(expre)
|
384
398
|
end
|
@@ -390,8 +404,8 @@ module Marty::RuleSpec
|
|
390
404
|
rescue Marty::DeloreanRule::ComputeError => e
|
391
405
|
exp = 'divided by 0'
|
392
406
|
expect(e.message).to include(exp)
|
393
|
-
expres = [%r(DELOREAN__XyzRule_\d+_1483228800.0
|
394
|
-
/DELOREAN__XyzRule_\d+_1483228800.0
|
407
|
+
expres = [%r(DELOREAN__XyzRule_\d+_1483228800.0:\d+:in ./'),
|
408
|
+
/DELOREAN__XyzRule_\d+_1483228800.0:\d+:in .cg1__D'/]
|
395
409
|
expres.each_with_index do |expre, i|
|
396
410
|
expect(e.backtrace[i]).to match(expre)
|
397
411
|
end
|
@@ -429,9 +443,9 @@ module Marty::RuleSpec
|
|
429
443
|
'err_section' => 'results',
|
430
444
|
'err_message' => 'no implicit conversion of Integer into String' }
|
431
445
|
expect(log_ents[1].details.except('err_stack')).to eq(exp)
|
432
|
-
expres = [/DELOREAN__XyzRule_\d+_1483228800.0
|
433
|
-
/DELOREAN__XyzRule_\d+_1483228800.0
|
434
|
-
/DELOREAN__XyzRule_\d+_1483228800.0
|
446
|
+
expres = [/DELOREAN__XyzRule_\d+_1483228800.0:\d+:in .+'/,
|
447
|
+
/DELOREAN__XyzRule_\d+_1483228800.0:\d+:in .tmp_var4__D'/,
|
448
|
+
/DELOREAN__XyzRule_\d+_1483228800.0:\d+:in .bv__D'/]
|
435
449
|
expres.each_with_index do |expre, i|
|
436
450
|
expect(log_ents[1].details['err_stack'][i]).to match(expre)
|
437
451
|
end
|
@@ -445,8 +459,8 @@ module Marty::RuleSpec
|
|
445
459
|
'err_section' => 'computed_guards',
|
446
460
|
'err_message' => 'divided by 0' }
|
447
461
|
expect(log_ents[2].details.except('err_stack')).to eq(exp)
|
448
|
-
expres = [%r(DELOREAN__XyzRule_\d+_1483228800.0
|
449
|
-
/DELOREAN__XyzRule_\d+_1483228800.0
|
462
|
+
expres = [%r(DELOREAN__XyzRule_\d+_1483228800.0:\d+:in ./'),
|
463
|
+
/DELOREAN__XyzRule_\d+_1483228800.0:\d+:in .cg1__D'/]
|
450
464
|
expres.each_with_index do |expre, i|
|
451
465
|
expect(log_ents[2].details['err_stack'][i]).to match(expre)
|
452
466
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.5.
|
4
|
+
version: 2.5.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arman Bostani
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date: 2019-
|
17
|
+
date: 2019-03-05 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: pg
|
@@ -383,6 +383,7 @@ files:
|
|
383
383
|
- delorean/blame_report.dl
|
384
384
|
- delorean/diagnostics.dl
|
385
385
|
- delorean/marty_fields.dl
|
386
|
+
- delorean/promises.dl
|
386
387
|
- delorean/script_report.dl
|
387
388
|
- delorean/table_report.dl
|
388
389
|
- docker-compose.dummy.yml
|