marty 2.0.0 → 2.0.1
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/Gemfile.lock +2 -2
- data/app/models/marty/base.rb +56 -0
- data/app/models/marty/data_grid.rb +23 -10
- data/app/models/marty/delorean_rule.rb +19 -2
- data/app/models/marty/import_type.rb +0 -9
- data/app/models/marty/posting.rb +19 -24
- data/app/models/marty/posting_type.rb +0 -6
- data/app/models/marty/script.rb +2 -3
- data/app/models/marty/tag.rb +17 -29
- data/lib/marty/data_change.rb +2 -2
- data/lib/marty/mcfly_model.rb +44 -13
- data/lib/marty/monkey.rb +25 -0
- data/lib/marty/promise_job.rb +0 -1
- data/lib/marty/version.rb +1 -1
- data/marty.gemspec +1 -2
- data/spec/controllers/rpc_import_spec.rb +1 -1
- data/spec/dummy/app/models/gemini/helper.rb +7 -5
- data/spec/dummy/delorean/blame_report.dl +3 -1
- data/spec/dummy/delorean/data_report.dl +2 -5
- data/spec/dummy/delorean/fields.dl +3 -1
- data/spec/features/data_import_spec.rb +3 -1
- data/spec/features/reporting_spec.rb +3 -1
- data/spec/features/rule_spec.rb +6 -6
- data/spec/features/scripting_test_spec.rb +1 -1
- data/spec/lib/delorean_query_spec.rb +16 -0
- data/spec/models/api_auth_spec.rb +1 -1
- data/spec/models/data_grid_spec.rb +9 -8
- data/spec/models/posting_spec.rb +14 -7
- data/spec/models/rule_spec.rb +25 -21
- data/spec/models/script_spec.rb +4 -3
- metadata +4 -5
- data/script_id, +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31ab53bcb7bcc26bfa4bd1d400c5e0c7861558d3
|
4
|
+
data.tar.gz: c12dae6177787b1cd2eefb4416c11b15155a4395
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c435cd40922422b864e5dc5ed4d20536ca8a50317b917a4b53b299a9d949ef67594ceb8707c38c822efd3024264e7a1832f3707ed8d2ae039957848681cf627
|
7
|
+
data.tar.gz: 17a9348a816387d216a59739eac52b9cca47790ec8dd5cb469eaee93c660c83a29d40f8b9afac1ccc422d4ea6245386948732c5a87632fc612793b5a0677d4c0
|
data/Gemfile.lock
CHANGED
data/app/models/marty/base.rb
CHANGED
@@ -21,4 +21,60 @@ class Marty::Base < ActiveRecord::Base
|
|
21
21
|
PLUCK_SIG = [1, 100]
|
22
22
|
SELECT_SIG = [1, 100]
|
23
23
|
WHERE_SIG = [0, 100]
|
24
|
+
|
25
|
+
class << self
|
26
|
+
attr_accessor :struct_attrs
|
27
|
+
end
|
28
|
+
def self.get_struct_attrs
|
29
|
+
self.struct_attrs ||= self.attribute_names -
|
30
|
+
["id", "group_id", "created_dt", "obsoleted_dt", "user_id",
|
31
|
+
"o_user_id"] -
|
32
|
+
(self.const_defined?('MCFLY_UNIQUENESS') &&
|
33
|
+
self.const_get('MCFLY_UNIQUENESS') || []).map(&:to_s)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.get_final_attrs(opts)
|
37
|
+
return [] if opts["no_convert"] == true
|
38
|
+
include_attrs = [opts["include_attrs"] || []].flatten
|
39
|
+
final_attrs = get_struct_attrs + include_attrs
|
40
|
+
return final_attrs if final_attrs.present?
|
41
|
+
|
42
|
+
# otherwise raise with error line
|
43
|
+
raise "Marty::Base: no attributes for #{self}"
|
44
|
+
|
45
|
+
# for more detailed debugging use this code instead
|
46
|
+
# st = caller.detect{|s|s.starts_with?('DELOREAN__')}
|
47
|
+
# re = /DELOREAN__([A-Z][a-zA-Z0-9]*)[:]([0-9]+)[:]in `([a-z_0-9]+)__D'/
|
48
|
+
# m = re.match(st)
|
49
|
+
# if !m
|
50
|
+
# st = "No attributes #{st} #{self}"
|
51
|
+
# puts st unless File.readlines(Rails.root.join('tmp','dlchk')).
|
52
|
+
# map(&:chop).detect{|l|l==st}
|
53
|
+
# else
|
54
|
+
# loc = "#{m[1]}::#{self}::#{m[2]}"
|
55
|
+
# str = "*** No attributes %-40s %-20s %s" % [loc, m[3], attr]
|
56
|
+
# puts str unless File.readlines(Rails.root.join('tmp','dlchk')).
|
57
|
+
# map(&:chop).detect{|l|l==str}
|
58
|
+
# end
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.make_openstruct(inst, opts={})
|
62
|
+
return nil unless inst
|
63
|
+
return inst if opts["no_convert"] == true
|
64
|
+
fa = opts["fa"] || get_final_attrs(opts)
|
65
|
+
os = OpenStruct.new(inst.attributes.slice(*fa))
|
66
|
+
(opts['link_attrs'] || []).each do |col, attr|
|
67
|
+
os[col] ||= OpenStruct.new
|
68
|
+
attrs = [attr].flatten
|
69
|
+
attrs.map { |attr| os[col][attr] = inst.send(col).try(attr) }
|
70
|
+
end
|
71
|
+
if self == Marty::DataGrid
|
72
|
+
def os.lookup_grid_distinct_entry(pt, params)
|
73
|
+
dgh = self.to_h.stringify_keys.slice("id","group_id","created_dt",
|
74
|
+
"metadata", "data_type")
|
75
|
+
Marty::DataGrid.lookup_grid_distinct_entry_h(pt, params, dgh)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
os
|
79
|
+
end
|
24
80
|
end
|
@@ -89,10 +89,11 @@ class Marty::DataGrid < Marty::Base
|
|
89
89
|
|
90
90
|
def self.lookup_h(pt, name, fields = nil)
|
91
91
|
fields ||= %w(id group_id created_dt metadata data_type)
|
92
|
-
dga =
|
92
|
+
dga = mcfly_pt(pt).where(name: name).pluck(*fields).first
|
93
93
|
dga && Hash[fields.zip(dga)]
|
94
94
|
end
|
95
95
|
|
96
|
+
# deprecated - remove 2018-Oct
|
96
97
|
cached_mcfly_lookup :lookup_id, sig: 2 do
|
97
98
|
|pt, group_id|
|
98
99
|
find_by_group_id group_id
|
@@ -103,6 +104,10 @@ class Marty::DataGrid < Marty::Base
|
|
103
104
|
Marty::DataGrid.mcfly_pt(pt).where(name: name).exists?
|
104
105
|
end
|
105
106
|
|
107
|
+
def self.get_struct_attrs
|
108
|
+
self.struct_attrs ||= super + ["id", "group_id", "created_dt"]
|
109
|
+
end
|
110
|
+
|
106
111
|
def to_s
|
107
112
|
name
|
108
113
|
end
|
@@ -216,11 +221,15 @@ class Marty::DataGrid < Marty::Base
|
|
216
221
|
res
|
217
222
|
end
|
218
223
|
|
224
|
+
# deprecated - remove 2018-Oct
|
219
225
|
cached_delorean_fn :lookup_grid, sig: 4 do
|
220
226
|
|pt, dg, h, distinct|
|
221
|
-
|
227
|
+
dg_is_grid = Marty::DataGrid === dg
|
228
|
+
dg_is_os = dg.is_a?(OpenStruct)
|
229
|
+
raise "bad DataGrid #{dg}" unless dg_is_grid || dg_is_os
|
222
230
|
raise "non-hash arg #{h}" unless Hash === h
|
223
|
-
dgh = dg.
|
231
|
+
dgh = dg_is_os ? dg.to_h.stringify_keys :
|
232
|
+
dg.attributes.slice('id', 'group_id', 'created_dt', 'metadata')
|
224
233
|
res = plv_lookup_grid_distinct(h, dgh, false, distinct)
|
225
234
|
res["result"]
|
226
235
|
end
|
@@ -248,8 +257,8 @@ class Marty::DataGrid < Marty::Base
|
|
248
257
|
end
|
249
258
|
end
|
250
259
|
|
251
|
-
|
252
|
-
|
260
|
+
def self.lookup_grid_distinct_entry_h(pt, h, dgh, visited=nil, follow=true,
|
261
|
+
return_grid_data=false, distinct=true)
|
253
262
|
|
254
263
|
# Perform grid lookup, if result is another data_grid, and follow is true,
|
255
264
|
# then perform lookup on the resulting grid. Allows grids to be nested
|
@@ -263,11 +272,11 @@ class Marty::DataGrid < Marty::Base
|
|
263
272
|
# "metadata" => <grid's metadata (array of hashes)>
|
264
273
|
vhash = plv_lookup_grid_distinct(h, dgh, return_grid_data, distinct)
|
265
274
|
|
266
|
-
|
275
|
+
return vhash if vhash["result"].nil? || !dgh['data_type']
|
267
276
|
|
268
277
|
c_data_type = Marty::DataGrid.convert_data_type(dgh['data_type'])
|
269
278
|
|
270
|
-
|
279
|
+
return vhash if String === c_data_type
|
271
280
|
|
272
281
|
res = vhash["result"]
|
273
282
|
|
@@ -282,7 +291,7 @@ class Marty::DataGrid < Marty::Base
|
|
282
291
|
Marty::DataConversion.find_row(c_data_type, {"name" => res}, pt)
|
283
292
|
end
|
284
293
|
|
285
|
-
|
294
|
+
return vhash.merge({"result" => v}) unless (Marty::DataGrid == c_data_type &&
|
286
295
|
follow)
|
287
296
|
|
288
297
|
visited ||= []
|
@@ -378,7 +387,7 @@ class Marty::DataGrid < Marty::Base
|
|
378
387
|
|
379
388
|
def export
|
380
389
|
# return null string when called from Netzke on add_in_form
|
381
|
-
|
390
|
+
return "" if metadata.nil? && data.nil?
|
382
391
|
|
383
392
|
meta_rows, h_key_rows, data_rows = export_array
|
384
393
|
|
@@ -389,7 +398,11 @@ class Marty::DataGrid < Marty::Base
|
|
389
398
|
gsub(/\"\"/, '') # remove "" to beautify output
|
390
399
|
end
|
391
400
|
|
392
|
-
|
401
|
+
delorean_fn :export, sig: 1 do
|
402
|
+
|os|
|
403
|
+
dg = find(os.id)
|
404
|
+
dg.export
|
405
|
+
end
|
393
406
|
|
394
407
|
def self.parse_fvalue(pt, v, type, klass)
|
395
408
|
return unless v
|
@@ -19,7 +19,7 @@ class Marty::DeloreanRule < Marty::BaseRule
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def self_as_hash
|
22
|
-
self.
|
22
|
+
self.attributes + {"classname"=>self.class.name}
|
23
23
|
end
|
24
24
|
def self.find_fixed(results)
|
25
25
|
results.each_with_object({}) do |(k, v), h|
|
@@ -75,6 +75,7 @@ class Marty::DeloreanRule < Marty::BaseRule
|
|
75
75
|
return Hash[compg_keys(computed_guards).zip(res).select{|k,v| !v}] unless
|
76
76
|
res.all?
|
77
77
|
end
|
78
|
+
|
78
79
|
grids_computed = false
|
79
80
|
grid_results = {}
|
80
81
|
crkeys = comp_res_keys(results, grids, eclass)
|
@@ -94,6 +95,7 @@ class Marty::DeloreanRule < Marty::BaseRule
|
|
94
95
|
elsif fixed_results.keys.sort == results.keys.sort
|
95
96
|
result = fixed_results
|
96
97
|
end
|
98
|
+
|
97
99
|
if grids.present? && !grids_computed
|
98
100
|
pt = params['pt']
|
99
101
|
gres = {}
|
@@ -113,6 +115,22 @@ class Marty::DeloreanRule < Marty::BaseRule
|
|
113
115
|
kl = ruleh["classname"].constantize
|
114
116
|
kl.compute(ruleh, pt, params, grid_names_p)
|
115
117
|
end
|
118
|
+
delorean_fn :route_compute_rs, sig: 3 do
|
119
|
+
|ruleh, pt, features|
|
120
|
+
kl = ruleh["classname"].constantize
|
121
|
+
kl.compute_rs(ruleh, pt, features)
|
122
|
+
end
|
123
|
+
delorean_fn :route_validate_results, sig: [1, 2] do
|
124
|
+
|ruleh, reqchk=false|
|
125
|
+
kl = ruleh["classname"].constantize
|
126
|
+
kl.validate_results(ruleh, reqchk)
|
127
|
+
end
|
128
|
+
delorean_fn :route_validate_grid_attrs, sig: [2, 3] do
|
129
|
+
|ruleh, gridname, addl_attrs=nil|
|
130
|
+
kl = ruleh["classname"].constantize
|
131
|
+
kl.validate_grid_attrs(ruleh, gridname, addl_attrs)
|
132
|
+
end
|
133
|
+
|
116
134
|
def base_compute(params, dgparams=params)
|
117
135
|
self.class.base_compute(self_as_hash, params, dgparams)
|
118
136
|
end
|
@@ -140,5 +158,4 @@ class Marty::DeloreanRule < Marty::BaseRule
|
|
140
158
|
def self.init_dg_handler
|
141
159
|
Marty::DataGrid.register_rule_handler(get_grid_rename_handler(self))
|
142
160
|
end
|
143
|
-
|
144
161
|
end
|
@@ -40,13 +40,4 @@ class Marty::ImportType < Marty::Base
|
|
40
40
|
def allow_import?
|
41
41
|
Mcfly.whodunnit && Mcfly.whodunnit.roles.pluck(:id).include?(role_id)
|
42
42
|
end
|
43
|
-
|
44
|
-
delorean_fn :lookup, sig: 1 do
|
45
|
-
|name|
|
46
|
-
self.find_by_name(name)
|
47
|
-
end
|
48
|
-
|
49
|
-
delorean_fn :get_all, sig: 0 do
|
50
|
-
self.all
|
51
|
-
end
|
52
43
|
end
|
data/app/models/marty/posting.rb
CHANGED
@@ -40,19 +40,24 @@ class Marty::Posting < Marty::Base
|
|
40
40
|
o
|
41
41
|
end
|
42
42
|
|
43
|
+
def self.get_struct_attrs
|
44
|
+
self.struct_attrs ||= super + ["created_dt", "name"]
|
45
|
+
end
|
46
|
+
|
43
47
|
# Not using mcfly_lookup since we don't want these time-warp markers
|
44
48
|
# time-warped. FIXME: perhaps this should use mcfly_lookup since we
|
45
49
|
# may allow deletion of postings. i.e. a new one with same name
|
46
50
|
# might be created. Or, use regular validates_uniqueness_of instead
|
47
51
|
# of mcfly_validates_uniqueness_of.
|
48
|
-
delorean_fn :lookup, sig: 1 do
|
49
|
-
|name|
|
50
|
-
|
52
|
+
delorean_fn :lookup, sig: [1, 2] do
|
53
|
+
|name, opts={}|
|
54
|
+
p = select(get_struct_attrs).find_by_name(name)
|
55
|
+
make_openstruct(p, opts)
|
51
56
|
end
|
52
57
|
|
53
58
|
delorean_fn :lookup_dt, sig: 1 do
|
54
59
|
|name|
|
55
|
-
|
60
|
+
find_by_name(name).try(:created_dt)
|
56
61
|
end
|
57
62
|
|
58
63
|
delorean_fn :first_match, sig: [1, 2] do
|
@@ -62,35 +67,25 @@ class Marty::Posting < Marty::Base
|
|
62
67
|
|
63
68
|
q = where("created_dt <= ?", dt)
|
64
69
|
q = q.where(posting_type_id: posting_type.id) if posting_type
|
65
|
-
q.order("created_dt DESC").first
|
70
|
+
q.order("created_dt DESC").first.attributes
|
66
71
|
end
|
67
72
|
|
68
|
-
|
69
|
-
|limit, is_test=nil|
|
73
|
+
def self.get_latest(limit, is_test=nil)
|
70
74
|
# IMPORTANT: is_test arg is ignored (KEEP for backward compat.)
|
71
75
|
|
72
|
-
where("created_dt <> 'infinity'").
|
73
|
-
|
76
|
+
q=where("created_dt <> 'infinity'").
|
77
|
+
order("created_dt DESC").limit(limit)
|
74
78
|
end
|
75
79
|
|
76
|
-
delorean_fn :get_latest_by_type, sig: [
|
80
|
+
delorean_fn :get_latest_by_type, sig: [1, 2] do
|
77
81
|
|limit, posting_types=[]|
|
78
82
|
raise "missing posting types list" unless posting_types
|
79
83
|
raise "bad posting types list" unless posting_types.is_a?(Array)
|
80
84
|
|
81
|
-
joins(:posting_type).where("created_dt <> 'infinity'").
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
delorean_fn :get_last, sig: [0, 1] do
|
87
|
-
|posting_type=nil|
|
88
|
-
|
89
|
-
raise "bad posting type" if
|
90
|
-
posting_type && !posting_type.is_a?(Marty::PostingType)
|
91
|
-
|
92
|
-
q = where("created_dt <> 'infinity'")
|
93
|
-
q = q.where(posting_type_id: posting_type.id) if posting_type
|
94
|
-
q.order("created_dt DESC").first
|
85
|
+
q=joins(:posting_type).where("created_dt <> 'infinity'").
|
86
|
+
where(marty_posting_types: { name: posting_types } ).
|
87
|
+
select(get_struct_attrs).
|
88
|
+
order("created_dt DESC").limit(limit || 1)
|
89
|
+
q.map{|ar| ar.attributes}
|
95
90
|
end
|
96
91
|
end
|
data/app/models/marty/script.rb
CHANGED
@@ -11,12 +11,11 @@ class Marty::Script < Marty::Base
|
|
11
11
|
belongs_to :user, class_name: "Marty::User"
|
12
12
|
|
13
13
|
gen_mcfly_lookup :lookup, [:name], cache: true
|
14
|
-
gen_mcfly_lookup :get_all, {}, mode: nil
|
15
14
|
|
16
15
|
# find script by name/tag
|
17
16
|
def self.find_script(sname, tag=nil)
|
18
17
|
tag = Marty::Tag.map_to_tag(tag)
|
19
|
-
Marty::Script.lookup(tag.created_dt, sname)
|
18
|
+
Marty::Script.lookup(tag.created_dt, sname, {"no_convert"=>true})
|
20
19
|
end
|
21
20
|
|
22
21
|
def find_tag
|
@@ -33,7 +32,7 @@ class Marty::Script < Marty::Base
|
|
33
32
|
end
|
34
33
|
|
35
34
|
def self.load_a_script(sname, body, dt=nil)
|
36
|
-
s = Marty::Script.lookup('infinity', sname)
|
35
|
+
s = Marty::Script.lookup('infinity', sname, {"no_convert"=>true})
|
37
36
|
|
38
37
|
if !s
|
39
38
|
s = Marty::Script.new
|
data/app/models/marty/tag.rb
CHANGED
@@ -6,6 +6,10 @@ class Marty::Tag < Marty::Base
|
|
6
6
|
|
7
7
|
belongs_to :user, class_name: "Marty::User"
|
8
8
|
|
9
|
+
def self.get_struct_attrs
|
10
|
+
self.struct_attrs ||= super + ["id", "created_dt"]
|
11
|
+
end
|
12
|
+
|
9
13
|
def self.make_name(dt)
|
10
14
|
return 'DEV' if Mcfly.is_infinity(dt)
|
11
15
|
|
@@ -38,7 +42,7 @@ class Marty::Tag < Marty::Base
|
|
38
42
|
def self.map_to_tag(tag_id)
|
39
43
|
# FIXME: this is really hacky. This function should not take so
|
40
44
|
# many different types of arguments.
|
41
|
-
|
45
|
+
nc = {"no_convert"=>true}
|
42
46
|
case tag_id
|
43
47
|
when Integer, /\A[0-9]+\z/
|
44
48
|
tag = find_by_id(tag_id)
|
@@ -47,8 +51,8 @@ class Marty::Tag < Marty::Base
|
|
47
51
|
# if tag name wasn't found, look for a matching
|
48
52
|
# posting, then find the tag whose created_dt <= posting dt.
|
49
53
|
if !tag
|
50
|
-
posting = Marty::Posting.lookup(tag_id)
|
51
|
-
tag = find_match(Mcfly.normalize_infinity(posting
|
54
|
+
posting = Marty::Posting.lookup(tag_id, nc)
|
55
|
+
tag = find_match(Mcfly.normalize_infinity(posting['created_dt'])) if
|
52
56
|
posting
|
53
57
|
end
|
54
58
|
when nil
|
@@ -56,44 +60,28 @@ class Marty::Tag < Marty::Base
|
|
56
60
|
else
|
57
61
|
tag = tag_id
|
58
62
|
end
|
59
|
-
|
60
|
-
raise "bad tag identifier #{tag_id.inspect}" unless tag.is_a? Marty::Tag
|
63
|
+
raise "bad tag identifier #{tag_id.inspect}" unless tag.is_a?(Marty::Tag)
|
61
64
|
tag
|
62
65
|
end
|
63
66
|
|
64
67
|
cached_delorean_fn :lookup, sig: 1 do
|
65
68
|
|name|
|
66
|
-
self.find_by_name(name)
|
69
|
+
t = self.find_by_name(name).select(get_struct_attrs)
|
70
|
+
t && t.attributes
|
67
71
|
end
|
68
72
|
|
69
|
-
|
70
|
-
|
71
|
-
|id|
|
72
|
-
find_by_id(id)
|
73
|
+
def self.get_latest1
|
74
|
+
order("created_dt DESC").find_by("created_dt <> 'infinity'")
|
73
75
|
end
|
74
76
|
|
75
|
-
|
76
|
-
|
77
|
-
lookup(name).try(:created_dt)
|
78
|
-
end
|
79
|
-
|
80
|
-
delorean_fn :get_latest1, sig: 0 do
|
81
|
-
where("created_dt <> 'infinity'").order("created_dt DESC").first
|
82
|
-
end
|
83
|
-
|
84
|
-
delorean_fn :find_match, sig: 1 do
|
85
|
-
|dt|
|
86
|
-
id = select(:id).where("created_dt <= ?", dt).order("created_dt DESC").first.id
|
87
|
-
|
88
|
-
# performance hack to use cached version
|
89
|
-
id && lookup_id(id)
|
77
|
+
def self.find_match(dt)
|
78
|
+
order("created_dt DESC").find_by("created_dt <= ?", dt)
|
90
79
|
end
|
91
80
|
|
92
81
|
# Performance hack for script sets -- FIXME: making find_mtach
|
93
82
|
# cached breaks Gemini tests. Need to look into it.
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
find_match dt
|
83
|
+
def self.cached_find_match(dt)
|
84
|
+
@@CACHE_FIND_BY_DT ||= {}
|
85
|
+
@@CACHE_FIND_BY_DT[dt] ||= find_match(dt)
|
98
86
|
end
|
99
87
|
end
|
data/lib/marty/data_change.rb
CHANGED
@@ -21,7 +21,7 @@ class Marty::DataChange
|
|
21
21
|
|
22
22
|
changes.each_with_object({}) do |(group_id, ol), h|
|
23
23
|
h[group_id] = ol.each_with_index.map do |o, i|
|
24
|
-
profile = {"obj" => o}
|
24
|
+
profile = {"obj" => o.attributes}
|
25
25
|
|
26
26
|
# Create a profile hash for each object in the group.
|
27
27
|
# "status" tells us if the object is old/new/mod. If
|
@@ -128,7 +128,7 @@ class Marty::DataChange
|
|
128
128
|
klass = k.constantize
|
129
129
|
next (klass.is_a? Marty::PgEnum) ? klass.get_all : []
|
130
130
|
end
|
131
|
-
|
131
|
+
|
132
132
|
delorean_fn :export_changes, sig: 3 do
|
133
133
|
|t0, t1, class_name|
|
134
134
|
|
data/lib/marty/mcfly_model.rb
CHANGED
@@ -27,7 +27,6 @@ module Mcfly::Model
|
|
27
27
|
cache_key = [name, ts] + args.map{ |a|
|
28
28
|
a.is_a?(ActiveRecord::Base) ? a.id : a
|
29
29
|
} unless Mcfly.is_infinity(ts)
|
30
|
-
|
31
30
|
next @LOOKUP_CACHE[cache_key] if
|
32
31
|
cache_key && @LOOKUP_CACHE.has_key?(cache_key)
|
33
32
|
|
@@ -53,19 +52,54 @@ module Mcfly::Model
|
|
53
52
|
end
|
54
53
|
end
|
55
54
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
55
|
+
def base_mcfly_lookup(meth, name, options = {}, &block)
|
56
|
+
|
57
|
+
sig = options[:sig]
|
58
|
+
newsig = sig.is_a?(Array) ? [sig[0], sig[1]+1] :
|
59
|
+
sig == -1 ? sig : [sig, sig+1]
|
60
|
+
options[:sig] = newsig
|
61
|
+
asig = options[:asig] || newsig[1]-1
|
62
|
+
|
63
|
+
send(meth, name, options) do |ts, *pargs|
|
64
|
+
raise "time cannot be nil" if ts.nil?
|
65
|
+
|
66
|
+
args, opts = pargs.last.is_a?(Hash) && pargs.length == asig ?
|
67
|
+
[pargs[0..-2], pargs.last] :
|
68
|
+
[pargs, {}]
|
60
69
|
|
61
70
|
ts = Mcfly.normalize_infinity(ts)
|
62
71
|
|
63
|
-
self.
|
72
|
+
q = self.where("#{table_name}.obsoleted_dt >= ? AND " +
|
73
|
+
"#{table_name}.created_dt < ?", ts, ts).scoping do
|
64
74
|
block.call(ts, *args)
|
65
75
|
end
|
76
|
+
fa = get_final_attrs(opts)
|
77
|
+
opts += {"fa"=>fa}
|
78
|
+
|
79
|
+
q = q.select(*fa) if fa.present? &&
|
80
|
+
q.respond_to?(:select) && !q.is_a?(Array) &&
|
81
|
+
!q.is_a?(Hash)
|
82
|
+
|
83
|
+
case
|
84
|
+
when opts["no_convert"] == true
|
85
|
+
q
|
86
|
+
when q.is_a?(ActiveRecord::Relation)
|
87
|
+
q.map{|ar| make_openstruct(ar, opts)}
|
88
|
+
when q.is_a?(ActiveRecord::Base)
|
89
|
+
make_openstruct(q, opts)
|
90
|
+
else
|
91
|
+
q
|
92
|
+
end
|
66
93
|
end
|
67
94
|
end
|
68
95
|
|
96
|
+
def cached_mcfly_lookup(name, options = {}, &block)
|
97
|
+
base_mcfly_lookup(:cached_delorean_fn, name, options, &block)
|
98
|
+
end
|
99
|
+
def mcfly_lookup(name, options = {}, &block)
|
100
|
+
base_mcfly_lookup(:delorean_fn, name, options, &block)
|
101
|
+
end
|
102
|
+
|
69
103
|
# FIXME: add private mode. This should make the function
|
70
104
|
# unavailable to delorean.
|
71
105
|
def gen_mcfly_lookup(name, attrs, options={})
|
@@ -99,14 +133,11 @@ module Mcfly::Model
|
|
99
133
|
raise "bad attrs" unless Array === attrs
|
100
134
|
end
|
101
135
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
# called from delorean. Ideally, we should have a 'private'
|
106
|
-
# option for delorean_fn.
|
107
|
-
sig = options[:private] ? -1 : attrs.length+1
|
136
|
+
actual_sig = attrs.length + 1
|
137
|
+
fn = cache ? :cached_delorean_fn : :delorean_fn
|
138
|
+
sig = options[:private] ? -1 : actual_sig
|
108
139
|
|
109
|
-
|
140
|
+
base_mcfly_lookup(fn, name, {sig: sig, asig: actual_sig}) do
|
110
141
|
|t, *attr_list|
|
111
142
|
|
112
143
|
attr_list_ids = attr_list.each_with_index.map {|x, i|
|
data/lib/marty/monkey.rb
CHANGED
@@ -264,6 +264,7 @@ args_hack = [[ActiveRecord::Relation, ActiveRecord::QueryMethods::WhereChain]] +
|
|
264
264
|
Delorean::RUBY_WHITELIST.merge!(
|
265
265
|
count: [ActiveRecord::Relation],
|
266
266
|
distinct: args_hack,
|
267
|
+
find_by: args_hack,
|
267
268
|
group: args_hack,
|
268
269
|
joins: args_hack,
|
269
270
|
limit: [ActiveRecord::Relation, Integer],
|
@@ -275,6 +276,9 @@ Delorean::RUBY_WHITELIST.merge!(
|
|
275
276
|
mcfly_pt: [ActiveRecord::Relation,
|
276
277
|
[Date, Time, ActiveSupport::TimeWithZone, String],
|
277
278
|
[nil, Class]],
|
279
|
+
lookup_grid_distinct_entry: [OpenStruct,
|
280
|
+
[Date, Time, ActiveSupport::TimeWithZone, String],
|
281
|
+
Hash],
|
278
282
|
)
|
279
283
|
|
280
284
|
######################################################################
|
@@ -285,3 +289,24 @@ module Mcfly::Controller
|
|
285
289
|
find_current_user rescue nil
|
286
290
|
end
|
287
291
|
end
|
292
|
+
|
293
|
+
######################################################################
|
294
|
+
|
295
|
+
class OpenStruct
|
296
|
+
def save
|
297
|
+
loc = %r([^/]+:[0-9]+).match(caller.first)[0]
|
298
|
+
raise "save called from #{loc} on #{self}"
|
299
|
+
end
|
300
|
+
def save!
|
301
|
+
loc = %r([^/]+:[0-9]+).match(caller.first)[0]
|
302
|
+
raise "save! called from #{loc} on #{self}"
|
303
|
+
end
|
304
|
+
def reload
|
305
|
+
loc = %r([^/]+:[0-9]+).match(caller.first)[0]
|
306
|
+
raise "reload called from #{loc} on #{self}"
|
307
|
+
end
|
308
|
+
#def method_missing(meth, *args)
|
309
|
+
# puts caller[0..8]
|
310
|
+
# super
|
311
|
+
#end
|
312
|
+
end
|
data/lib/marty/promise_job.rb
CHANGED
data/lib/marty/version.rb
CHANGED
data/marty.gemspec
CHANGED
@@ -21,18 +21,20 @@ class Gemini::Helper
|
|
21
21
|
|
22
22
|
# Just for testing
|
23
23
|
delorean_fn :import_data, sig: [2, 3] do
|
24
|
-
|
|
24
|
+
|import_type_name, data, col_sep|
|
25
25
|
|
26
26
|
col_sep ||= "\t"
|
27
27
|
|
28
|
+
imp_t = Marty::ImportType.find_by_name(import_type_name)
|
29
|
+
|
28
30
|
raise "Insufficient permissions to run the data import" unless
|
29
|
-
|
31
|
+
imp_t.allow_import?
|
30
32
|
|
31
|
-
Marty::DataImporter.do_import_summary(
|
33
|
+
Marty::DataImporter.do_import_summary(imp_t.get_model_class,
|
32
34
|
data,
|
33
35
|
'infinity',
|
34
|
-
|
35
|
-
|
36
|
+
imp_t.cleaner_function,
|
37
|
+
imp_t.validation_function,
|
36
38
|
col_sep,
|
37
39
|
false)
|
38
40
|
end
|
@@ -2,7 +2,9 @@ import Fields
|
|
2
2
|
import Styles
|
3
3
|
|
4
4
|
PostingField2: Fields::PostingField2
|
5
|
-
store = ["NOW"] +
|
5
|
+
store = ["NOW"] + Marty::Posting.
|
6
|
+
where("created_dt <> 'infinity'").
|
7
|
+
order("created_dt DESC").limit(10).pluck("name")
|
6
8
|
|
7
9
|
StyleRow:
|
8
10
|
profile =?
|
@@ -70,7 +70,7 @@ ImportTypeField:
|
|
70
70
|
field_label = "Import Type"
|
71
71
|
name = "import_type"
|
72
72
|
xtype = ":combo"
|
73
|
-
store =
|
73
|
+
store = Marty::ImportType.pluck("name").sort
|
74
74
|
value = store[0]
|
75
75
|
|
76
76
|
CommaSepField:
|
@@ -92,11 +92,8 @@ DataImportReport:
|
|
92
92
|
|
93
93
|
data_import_field =?
|
94
94
|
|
95
|
-
import_type_rec = Marty::ImportType.lookup(import_type) ||
|
96
|
-
ERR("NULL ImportType", import_type)
|
97
|
-
|
98
95
|
result = Gemini::Helper.import_data(
|
99
|
-
|
96
|
+
import_type,
|
100
97
|
data_import_field,
|
101
98
|
if comma_sep then "," else nil
|
102
99
|
)
|
@@ -2,7 +2,9 @@ PostingField:
|
|
2
2
|
field_label = "Posting"
|
3
3
|
xtype = ":combo"
|
4
4
|
name = "pt_name"
|
5
|
-
store =
|
5
|
+
store = Marty::Posting.
|
6
|
+
where("created_dt <> 'infinity'").
|
7
|
+
order("created_dt DESC").limit(10).pluck("name")
|
6
8
|
value = store[0]
|
7
9
|
|
8
10
|
######################################################################
|
@@ -83,7 +83,9 @@ feature 'under Applications menu, Reports using Data Import', js: true do
|
|
83
83
|
import_type_combo = netzke_find('Import Type', 'combobox')
|
84
84
|
import_type_combo.select_values('FB')
|
85
85
|
bud_id = Gemini::BudCategory.first.id
|
86
|
-
paste("bud_category_id\tnote_rate\tsettlement_mm\tsettlement_yy\
|
86
|
+
paste("bud_category_id\tnote_rate\tsettlement_mm\tsettlement_yy\t"\
|
87
|
+
"buy_up\tbuy_down\n#{bud_id}\t9.500\t9\t2014\t0\t0\n"\
|
88
|
+
"#{bud_id}\t9.750\t9\t2014\t0\t0\n",
|
87
89
|
'data_import_field')
|
88
90
|
end
|
89
91
|
end
|
@@ -37,7 +37,9 @@ PostingField:
|
|
37
37
|
field_label = "Posting"
|
38
38
|
xtype = ":combo"
|
39
39
|
name = "pt_name"
|
40
|
-
store =
|
40
|
+
store = Marty::Posting.
|
41
|
+
where("created_dt <> 'infinity'").
|
42
|
+
order("created_dt DESC").limit(10).pluck("name")
|
41
43
|
|
42
44
|
RateField:
|
43
45
|
field_label = "Note Rate"
|
data/spec/features/rule_spec.rb
CHANGED
@@ -117,8 +117,8 @@ feature 'rule view', js: true do
|
|
117
117
|
"results"=>"",
|
118
118
|
})
|
119
119
|
|
120
|
-
r = Gemini::MyRule.lookup('infinity','abc')
|
121
|
-
expect(r.
|
120
|
+
r = Gemini::MyRule.lookup('infinity','abc', {"no_convert"=>true})
|
121
|
+
expect(r.attributes).to include({"user_id"=>1,
|
122
122
|
"o_user_id"=>nil,
|
123
123
|
"name"=>"abc",
|
124
124
|
"engine"=>"Gemini::MyRuleScriptSet",
|
@@ -172,7 +172,7 @@ feature 'rule view', js: true do
|
|
172
172
|
"results"=>"",
|
173
173
|
}
|
174
174
|
r = Gemini::MyRule.lookup('infinity','abc')
|
175
|
-
expect(r
|
175
|
+
expect(r["simple_guards"]["g_nullbool"]).to eq(false)
|
176
176
|
expect(mrv.get_row_vals(1)).to include(exp)
|
177
177
|
# grid edits
|
178
178
|
press("Edit")
|
@@ -189,7 +189,7 @@ feature 'rule view', js: true do
|
|
189
189
|
"grids"=>
|
190
190
|
"{\"grid1\":\"DataGrid1\"}"})
|
191
191
|
r = Gemini::MyRule.lookup('infinity','abc')
|
192
|
-
expect(r
|
192
|
+
expect(r["simple_guards"]).not_to include('g_nullbool')
|
193
193
|
# computed fields
|
194
194
|
press("Edit")
|
195
195
|
fill_in(:computed_guards, with: 'sadf asdf ljsf')
|
@@ -240,8 +240,8 @@ feature 'rule view', js: true do
|
|
240
240
|
fill_in("Range Guard 2", with: "[30,40)")
|
241
241
|
press("OK")
|
242
242
|
r = Gemini::XyzRule.get_matches('infinity', {}, {"g_range1"=> 150,
|
243
|
-
"g_range2"=> 35}
|
244
|
-
|
243
|
+
"g_range2"=> 35},
|
244
|
+
{"no_convert"=>true})
|
245
245
|
expect(r.to_a.count).to eq(1)
|
246
246
|
exp = {"user_id"=>1,
|
247
247
|
"o_user_id"=>nil,
|
@@ -37,6 +37,12 @@ A:
|
|
37
37
|
select("note_rate").
|
38
38
|
first.note_rate
|
39
39
|
|
40
|
+
oo = Gemini::FannieBup.
|
41
|
+
order("note_rate", "buy_down ASC").
|
42
|
+
select("note_rate").
|
43
|
+
find_by("obsoleted_dt = 'infinity'").
|
44
|
+
note_rate
|
45
|
+
|
40
46
|
g = Gemini::FannieBup.
|
41
47
|
select("settlement_yy*settlement_mm AS x, count(*) AS c").
|
42
48
|
group("settlement_mm", "settlement_yy").
|
@@ -124,6 +130,16 @@ EOF
|
|
124
130
|
first.note_rate
|
125
131
|
end
|
126
132
|
|
133
|
+
it "perfroms order+find_by" do
|
134
|
+
res = @engine.evaluate("A", "oo", {})
|
135
|
+
|
136
|
+
expect(res).to eq Gemini::FannieBup.
|
137
|
+
order("note_rate", "buy_down ASC").
|
138
|
+
select("note_rate").
|
139
|
+
find_by("obsoleted_dt = 'infinity'").
|
140
|
+
note_rate
|
141
|
+
end
|
142
|
+
|
127
143
|
it "perfroms group+count" do
|
128
144
|
res = @engine.evaluate("A", "gg", {})
|
129
145
|
|
@@ -50,7 +50,7 @@ module Marty
|
|
50
50
|
|
51
51
|
it "should allow a tagged script version to be associated when a DEV " +
|
52
52
|
"version of that script also exists" do
|
53
|
-
s = Marty::Script.lookup('infinity', 'Script1')
|
53
|
+
s = Marty::Script.lookup('infinity', 'Script1', {"no_convert"=>true})
|
54
54
|
s.body = "A:\n a = 3\n"
|
55
55
|
s.save!
|
56
56
|
|
@@ -204,9 +204,10 @@ EOS
|
|
204
204
|
dg_from_import("G8", G8)
|
205
205
|
dg_from_import("Ga", Ga)
|
206
206
|
|
207
|
-
|
208
|
-
expect(Marty::DataGrid.lookup('infinity', "
|
209
|
-
expect(Marty::DataGrid.lookup('infinity', "
|
207
|
+
inc = {"include_attrs"=>"name"}
|
208
|
+
expect(Marty::DataGrid.lookup('infinity', "G1", inc).name).to eq "G1"
|
209
|
+
expect(Marty::DataGrid.lookup('infinity', "G2", inc).name).to eq "G2"
|
210
|
+
expect(Marty::DataGrid.lookup('infinity', "G3", inc).name).to eq "G3"
|
210
211
|
end
|
211
212
|
|
212
213
|
it "should not allow bad axis types" do
|
@@ -415,7 +416,7 @@ EOS
|
|
415
416
|
expect(res).to eq [5.6,"G2"]
|
416
417
|
}
|
417
418
|
|
418
|
-
dg = Marty::DataGrid.lookup('infinity', "G1")
|
419
|
+
dg = Marty::DataGrid.lookup('infinity', "G1", {"no_convert"=>true})
|
419
420
|
|
420
421
|
h = {
|
421
422
|
"fico" => 600,
|
@@ -562,7 +563,6 @@ EOS
|
|
562
563
|
it "should handle multi DataGrid lookups" do
|
563
564
|
expect(Marty::DataGrid.lookup('infinity', "G8").data_type).
|
564
565
|
to eq "Marty::DataGrid"
|
565
|
-
g1 = Marty::DataGrid.lookup('infinity', "G1")
|
566
566
|
|
567
567
|
h = {
|
568
568
|
"fico" => 600,
|
@@ -581,7 +581,7 @@ EOS
|
|
581
581
|
end
|
582
582
|
|
583
583
|
it "should handle DataGrid typed data grids" do
|
584
|
-
g1 = Marty::DataGrid.lookup('infinity', "G1")
|
584
|
+
g1 = Marty::DataGrid.lookup('infinity', "G1", {"no_convert"=>true})
|
585
585
|
|
586
586
|
res = lookup_grid_helper('infinity',
|
587
587
|
"Ga",
|
@@ -824,8 +824,9 @@ EOS
|
|
824
824
|
|
825
825
|
expect(sum).to eq({create: 1})
|
826
826
|
|
827
|
-
|
828
|
-
|
827
|
+
nc = {"no_convert"=>true}
|
828
|
+
g1 = Marty::DataGrid.lookup('infinity', "G1", nc)
|
829
|
+
g11 = Marty::DataGrid.lookup('infinity', "G11", nc)
|
829
830
|
|
830
831
|
expect(g1.export).to eq g11.export
|
831
832
|
end
|
data/spec/models/posting_spec.rb
CHANGED
@@ -69,31 +69,38 @@ module Marty
|
|
69
69
|
# First param is just the limit (max) to return
|
70
70
|
res = Posting.get_latest_by_type(10, ['BASE'])
|
71
71
|
expect(res.count).to eq 1
|
72
|
-
|
72
|
+
r0 = Posting.find_by_name(res[0]['name'])
|
73
|
+
expect(r0.comment).to eq 'base posting'
|
73
74
|
end
|
74
75
|
|
75
76
|
it "filters on multiple posting types" do
|
76
77
|
res = Posting.get_latest_by_type(10, ['BASE', 'SNAPSHOT'])
|
77
78
|
expect(res.count).to eq 4
|
78
79
|
# snapshot3 is most recent with this filter
|
79
|
-
|
80
|
-
|
80
|
+
r0 = Posting.find_by_name(res[0]['name'])
|
81
|
+
r3 = Posting.find_by_name(res[3]['name'])
|
82
|
+
expect(r0.comment).to eq 'snapshot3 posting'
|
83
|
+
expect(r3.comment).to eq 'base posting'
|
81
84
|
end
|
82
85
|
|
83
86
|
it "filters on posting types that are single or double quoted" do
|
84
87
|
res = Posting.get_latest_by_type(10, ['SNAPSHOT', "OTHER"])
|
85
88
|
expect(res.count).to eq 5
|
86
89
|
# other2 is most recent with this filter
|
87
|
-
|
88
|
-
|
90
|
+
r0 = Posting.find_by_name(res[0]['name'])
|
91
|
+
r4 = Posting.find_by_name(res[4]['name'])
|
92
|
+
expect(r0.comment).to eq 'other2 posting'
|
93
|
+
expect(r4.comment).to eq 'snapshot1 posting'
|
89
94
|
end
|
90
95
|
|
91
96
|
it "filters and limits on multiple posting types" do
|
92
97
|
res = Posting.get_latest_by_type(3, ['SNAPSHOT', 'OTHER'])
|
93
98
|
expect(res.count).to eq 3
|
94
99
|
# other2 is most recent with this filter
|
95
|
-
|
96
|
-
|
100
|
+
r0 = Posting.find_by_name(res[0]['name'])
|
101
|
+
r2 = Posting.find_by_name(res[2]['name'])
|
102
|
+
expect(r0.comment).to eq 'other2 posting'
|
103
|
+
expect(r2.comment).to eq 'other1 posting'
|
97
104
|
end
|
98
105
|
|
99
106
|
it "returns nothing with an empty posting type list" do
|
data/spec/models/rule_spec.rb
CHANGED
@@ -170,66 +170,68 @@ module Marty::RuleSpec
|
|
170
170
|
|
171
171
|
context "lookups" do
|
172
172
|
it "matches" do
|
173
|
+
nc = {"no_convert"=>true}
|
173
174
|
lookup = Gemini::MyRule.get_matches('infinity',
|
174
175
|
{'rule_type'=>'SimpleRule'},
|
175
|
-
{'g_array'=>'G1V3'})
|
176
|
+
{'g_array'=>'G1V3'}, nc)
|
176
177
|
expect(lookup.to_a.count).to eq(1)
|
177
178
|
expect(lookup.first.name).to eq("Rule1")
|
178
179
|
lookup = Gemini::MyRule.get_matches('infinity',
|
179
180
|
{'rule_type'=>'SimpleRule',
|
181
|
+
|
180
182
|
'other_flag'=>true},
|
181
|
-
{})
|
183
|
+
{}, nc)
|
182
184
|
expect(lookup.to_a.count).to eq(4)
|
183
185
|
expect(lookup.map{|l|l.name}.to_set).to eq(Set["Rule2","Rule2a",
|
184
186
|
"Rule2b", "Rule2c"])
|
185
187
|
lookup = Gemini::MyRule.get_matches('infinity',
|
186
188
|
{'rule_type'=>'ComplexRule',
|
187
189
|
'other_flag'=>false},
|
188
|
-
{})
|
190
|
+
{}, nc)
|
189
191
|
expect(lookup.to_a.count).to eq(1)
|
190
192
|
expect(lookup.first.name).to eq("Rule3")
|
191
193
|
# bool false matches bool nil
|
192
194
|
lookup = Gemini::MyRule.get_matches('infinity',
|
193
195
|
{'rule_type'=>'ComplexRule',
|
194
196
|
'other_flag'=>false},
|
195
|
-
{'g_bool'=>false})
|
197
|
+
{'g_bool'=>false}, nc)
|
196
198
|
expect(lookup.to_a.count).to eq(1)
|
197
199
|
expect(lookup.first.name).to eq("Rule3")
|
198
200
|
lookup = Gemini::MyRule.get_matches('infinity',
|
199
201
|
{'rule_type'=>'ComplexRule'},
|
200
|
-
{'g_string'=>'def'})
|
202
|
+
{'g_string'=>'def'}, nc)
|
201
203
|
expect(lookup.to_a.count).to eq(1)
|
202
204
|
expect(lookup.first.name).to eq("Rule3")
|
203
205
|
lookup = Gemini::MyRule.get_matches('infinity',
|
204
206
|
{'rule_type'=>'ComplexRule'},
|
205
|
-
{'g_string'=>'abc'})
|
207
|
+
{'g_string'=>'abc'}, nc)
|
206
208
|
expect(lookup).to eq([])
|
207
209
|
lookup = Gemini::MyRule.get_matches('infinity',
|
208
210
|
{'rule_type'=>'SimpleRule'},
|
209
211
|
{'g_bool'=>true, "g_range"=>25,
|
210
|
-
'g_integer'=>99})
|
212
|
+
'g_integer'=>99}, nc)
|
211
213
|
expect(lookup.to_a.count).to eq(1)
|
212
214
|
expect(lookup.first.name).to eq("Rule2a")
|
213
215
|
lookup = Gemini::MyRule.get_matches('infinity',
|
214
216
|
{'rule_type'=>'SimpleRule'},
|
215
|
-
{'g_bool'=>true, "g_range"=>75})
|
217
|
+
{'g_bool'=>true, "g_range"=>75}, nc)
|
216
218
|
expect(lookup.to_a.count).to eq(1)
|
217
219
|
expect(lookup.first.name).to eq("Rule1")
|
218
220
|
lookup = Gemini::MyRule.get_matches('infinity',
|
219
221
|
{'rule_type'=>'SimpleRule'},
|
220
222
|
{'g_bool'=>true, "g_range"=>75,
|
221
|
-
'g_integer'=>11})
|
223
|
+
'g_integer'=>11}, nc)
|
222
224
|
expect(lookup).to eq([])
|
223
225
|
lookup = Gemini::MyRule.get_matches('infinity',
|
224
226
|
{'rule_type'=>'SimpleRule'},
|
225
227
|
{'g_bool'=>true, "g_range"=>75,
|
226
|
-
'g_integer'=>10})
|
228
|
+
'g_integer'=>10}, nc)
|
227
229
|
expect(lookup.to_a.count).to eq(1)
|
228
230
|
expect(lookup.first.name).to eq("Rule1")
|
229
231
|
lookup = Gemini::MyRule.get_matches('infinity',
|
230
232
|
{'rule_type'=>'SimpleRule'},
|
231
233
|
{'g_bool'=>false, "g_range"=>25,
|
232
|
-
'g_integer'=>10})
|
234
|
+
'g_integer'=>10}, nc)
|
233
235
|
expect(lookup.to_a.count).to eq(1)
|
234
236
|
expect(lookup.first.name).to eq("Rule2c")
|
235
237
|
lookup = Gemini::MyRule.get_matches('infinity',
|
@@ -237,13 +239,13 @@ module Marty::RuleSpec
|
|
237
239
|
expect(lookup.to_a.count).to eq(5)
|
238
240
|
lookup = Gemini::MyRule.get_matches('infinity',
|
239
241
|
{'rule_dt'=>"2017-3-1 02:00:00"},
|
240
|
-
{})
|
242
|
+
{}, nc)
|
241
243
|
expect(lookup.to_a.count).to eq(6)
|
242
244
|
expect(lookup.pluck(:name).to_set).to eq(Set["Rule1", "Rule2", "Rule2a",
|
243
245
|
"Rule2b", "Rule2c", "Rule3"])
|
244
246
|
lookup = Gemini::MyRule.get_matches('infinity',
|
245
247
|
{'rule_dt'=>"2017-4-1 16:00:00"},
|
246
|
-
{})
|
248
|
+
{}, nc)
|
247
249
|
expect(lookup.to_a.count).to eq(1)
|
248
250
|
expect(lookup.pluck(:name).first).to eq("Rule4")
|
249
251
|
lookup = Gemini::MyRule.get_matches('infinity',
|
@@ -254,38 +256,40 @@ module Marty::RuleSpec
|
|
254
256
|
expect(lookup.to_a).to eq([])
|
255
257
|
lookup = Gemini::MyRule.get_matches('infinity', {},
|
256
258
|
{"g_bool_def"=>false,
|
257
|
-
"g_nbool_def"=>true})
|
259
|
+
"g_nbool_def"=>true}, nc)
|
258
260
|
expect(lookup.to_a.count).to eq(1)
|
259
261
|
expect(lookup.pluck(:name).first).to eq("Rule1")
|
260
262
|
end
|
261
263
|
end
|
262
264
|
context "rule compute" do
|
265
|
+
let(:nc) {{"no_convert"=>true}}
|
263
266
|
let(:complex) { Gemini::MyRule.get_matches('infinity',
|
264
267
|
{'rule_type'=>'ComplexRule'},
|
265
|
-
{'g_string'=>'def'}).first }
|
268
|
+
{'g_string'=>'def'}, nc).first }
|
266
269
|
let(:xyz) { Gemini::XyzRule.get_matches('infinity',
|
267
270
|
{'rule_type'=>'ZRule'},
|
268
|
-
{'g_integer'=> 2}).first }
|
271
|
+
{'g_integer'=> 2}, nc).first }
|
269
272
|
let(:simple) {
|
270
273
|
Gemini::MyRule.get_matches('infinity',
|
271
274
|
{'rule_type'=>'SimpleRule'},
|
272
|
-
{'g_bool'=>true, "g_range"=>25}).first }
|
275
|
+
{'g_bool'=>true, "g_range"=>25}, nc).first }
|
273
276
|
let(:simple2a) {
|
274
277
|
Gemini::MyRule.get_matches('infinity',
|
275
278
|
{'rule_type'=>'SimpleRule'},
|
276
|
-
{'g_bool'=>true, "g_integer"=>99}).first }
|
279
|
+
{'g_bool'=>true, "g_integer"=>99}, nc).first }
|
277
280
|
let(:simple2b) {
|
278
281
|
Gemini::MyRule.get_matches('infinity',
|
279
282
|
{'rule_type'=>'SimpleRule'},
|
280
|
-
{'g_bool'=>true, "g_integer"=>999}).first }
|
283
|
+
{'g_bool'=>true, "g_integer"=>999}, nc).first }
|
281
284
|
let(:altgridmethod) {
|
282
285
|
Gemini::MyRule.get_matches('infinity',
|
283
286
|
{'rule_type'=>'ComplexRule'},
|
284
|
-
{"g_integer"=>3757}).first }
|
287
|
+
{"g_integer"=>3757}, nc).first }
|
285
288
|
let(:gridcomputedname) {
|
286
289
|
Gemini::MyRule.get_matches('infinity',
|
287
290
|
{'rule_type'=>'ComplexRule'},
|
288
|
-
{"g_string"=>"Hi Mom",
|
291
|
+
{"g_string"=>"Hi Mom",
|
292
|
+
"g_integer"=>11}, nc).first }
|
289
293
|
it "computed guards work" do
|
290
294
|
c = complex.compute({"pt"=>Time.zone.now,
|
291
295
|
'param2'=>'def'})
|
data/spec/models/script_spec.rb
CHANGED
@@ -17,7 +17,8 @@ describe Marty::Script do
|
|
17
17
|
it "creates a new script if it doesn't already exist" do
|
18
18
|
expect { Marty::Script.load_a_script('TestNew', s1, now) }.
|
19
19
|
to change(Marty::Script, :count).by(1)
|
20
|
-
expect(Marty::Script.lookup('infinity', 'TestNew').
|
20
|
+
expect(Marty::Script.lookup('infinity', 'TestNew', {"no_convert"=>true}).
|
21
|
+
created_dt.to_s).
|
21
22
|
to eq(now.to_s)
|
22
23
|
end
|
23
24
|
|
@@ -39,8 +40,8 @@ describe Marty::Script do
|
|
39
40
|
s2, now) }.
|
40
41
|
to change { Marty::Script.where(name: 'TestExistsAndDifferent2',
|
41
42
|
obsoleted_dt: 'infinity').count }.by(0)
|
42
|
-
expect(Marty::Script.lookup('infinity', 'TestExistsAndDifferent2'
|
43
|
-
|
43
|
+
expect(Marty::Script.lookup('infinity', 'TestExistsAndDifferent2',
|
44
|
+
{"no_convert"=>true}).created_dt.to_s).to eq(now.to_s)
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
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.0.
|
4
|
+
version: 2.0.1
|
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: 2018-
|
17
|
+
date: 2018-04-09 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: pg
|
@@ -64,14 +64,14 @@ dependencies:
|
|
64
64
|
requirements:
|
65
65
|
- - "~>"
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: 0.3.
|
67
|
+
version: 0.3.37
|
68
68
|
type: :runtime
|
69
69
|
prerelease: false
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
72
|
- - "~>"
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version: 0.3.
|
74
|
+
version: 0.3.37
|
75
75
|
- !ruby/object:Gem::Dependency
|
76
76
|
name: mcfly
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -508,7 +508,6 @@ files:
|
|
508
508
|
- other/marty/diagnostic/request.rb
|
509
509
|
- other/marty/diagnostic/version.rb
|
510
510
|
- script/rails
|
511
|
-
- script_id,
|
512
511
|
- spec/controllers/application_controller_spec.rb
|
513
512
|
- spec/controllers/diagnostic/controller_spec.rb
|
514
513
|
- spec/controllers/job_controller_spec.rb
|
data/script_id,
DELETED
File without changes
|