marty 2.5.6 → 2.5.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|