marty 2.0.2 → 2.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/app/models/marty/api_auth.rb +3 -8
- data/app/models/marty/base.rb +16 -19
- data/app/models/marty/posting.rb +3 -3
- data/app/models/marty/script.rb +3 -3
- data/app/models/marty/tag.rb +3 -4
- data/lib/marty/mcfly_model.rb +7 -23
- data/lib/marty/version.rb +1 -1
- data/lib/pyxll/README.txt +3 -1
- data/spec/controllers/rpc_import_spec.rb +1 -1
- data/spec/dummy/app/models/gemini/fannie_bup.rb +0 -2
- data/spec/features/rule_spec.rb +16 -16
- data/spec/features/scripting_spec.rb +1 -1
- data/spec/features/scripting_test_spec.rb +1 -1
- data/spec/lib/mcfly_model_spec.rb +28 -85
- data/spec/models/api_auth_spec.rb +1 -1
- data/spec/models/data_grid_spec.rb +10 -33
- data/spec/models/rule_spec.rb +27 -28
- data/spec/models/script_spec.rb +5 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da7cae1ae6b567cbf3f8674cea6376869f6c81f8
|
4
|
+
data.tar.gz: 5eede83f082569ef70cba547e2a654b1697b95c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5611d1364fd1ecea6dc10c7c90d27c57bfdc7e4b27949ac5811fc3e709546a2aae03063afb786418bef2b28d82da14af50ea869143b1bc29a69e2262ab305dff
|
7
|
+
data.tar.gz: 235f9cd65d8e63075fbe546b70f796293fda42f332090e5acf16436ab90a2d4b059d40ce2d34051ca141667ecfe85f9221f5de8c21b073a28c328c96df7b1dee
|
data/Gemfile.lock
CHANGED
@@ -9,15 +9,11 @@ class Marty::ApiAuth < Marty::Base
|
|
9
9
|
|
10
10
|
class ApiAuthValidator < ActiveModel::Validator
|
11
11
|
def validate(api)
|
12
|
-
api.errors.add(
|
13
|
-
:base,
|
14
|
-
"API Key length must be #{KEY_SIZE*2}") if
|
12
|
+
api.errors.add(:base, "API Key length must be #{KEY_SIZE*2}") if
|
15
13
|
api.api_key && api.api_key.length != KEY_SIZE*2
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
"Script Name must reference a valid script") if
|
20
|
-
Marty::Script.find_script(api.script_name, nil).nil?
|
15
|
+
api.errors.add(:base, "Script Name must reference a valid script") unless
|
16
|
+
Marty::Script.find_script(api.script_name, nil)
|
21
17
|
end
|
22
18
|
end
|
23
19
|
|
@@ -41,5 +37,4 @@ class Marty::ApiAuth < Marty::Base
|
|
41
37
|
script_name: script_name,
|
42
38
|
obsoleted_dt: 'infinity').pluck(:app_name).first
|
43
39
|
end
|
44
|
-
|
45
40
|
end
|
data/app/models/marty/base.rb
CHANGED
@@ -25,18 +25,16 @@ class Marty::Base < ActiveRecord::Base
|
|
25
25
|
class << self
|
26
26
|
attr_accessor :struct_attrs
|
27
27
|
end
|
28
|
+
|
28
29
|
def self.get_struct_attrs
|
29
|
-
self.struct_attrs ||=
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
self.const_get('MCFLY_UNIQUENESS') || []).map(&:to_s)
|
30
|
+
self.struct_attrs ||=
|
31
|
+
self.attribute_names - Mcfly::COLUMNS.to_a -
|
32
|
+
(self.const_defined?('MCFLY_UNIQUENESS') &&
|
33
|
+
self.const_get('MCFLY_UNIQUENESS') || []).map(&:to_s)
|
34
34
|
end
|
35
35
|
|
36
|
-
def self.get_final_attrs
|
37
|
-
|
38
|
-
include_attrs = [opts["include_attrs"] || []].flatten
|
39
|
-
final_attrs = get_struct_attrs + include_attrs
|
36
|
+
def self.get_final_attrs
|
37
|
+
final_attrs = get_struct_attrs
|
40
38
|
return final_attrs if final_attrs.present?
|
41
39
|
|
42
40
|
# otherwise raise with error line
|
@@ -58,20 +56,19 @@ class Marty::Base < ActiveRecord::Base
|
|
58
56
|
# end
|
59
57
|
end
|
60
58
|
|
61
|
-
def self.
|
59
|
+
def self.make_hash(inst)
|
60
|
+
fa = get_final_attrs
|
61
|
+
inst.attributes.slice(*fa)
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.make_openstruct(inst)
|
62
65
|
return nil unless inst
|
63
|
-
|
64
|
-
fa = opts["fa"] || get_final_attrs(opts)
|
66
|
+
fa = get_final_attrs
|
65
67
|
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
68
|
if self == Marty::DataGrid
|
72
69
|
def os.lookup_grid_distinct_entry(pt, params)
|
73
|
-
dgh = self.to_h.stringify_keys.slice(
|
74
|
-
|
70
|
+
dgh = self.to_h.stringify_keys.slice(
|
71
|
+
"id", "group_id", "created_dt", "metadata", "data_type")
|
75
72
|
Marty::DataGrid.lookup_grid_distinct_entry_h(pt, params, dgh)
|
76
73
|
end
|
77
74
|
end
|
data/app/models/marty/posting.rb
CHANGED
@@ -49,10 +49,10 @@ class Marty::Posting < Marty::Base
|
|
49
49
|
# may allow deletion of postings. i.e. a new one with same name
|
50
50
|
# might be created. Or, use regular validates_uniqueness_of instead
|
51
51
|
# of mcfly_validates_uniqueness_of.
|
52
|
-
delorean_fn :lookup, sig:
|
53
|
-
|name
|
52
|
+
delorean_fn :lookup, sig: 1 do
|
53
|
+
|name|
|
54
54
|
p = select(get_struct_attrs).find_by_name(name)
|
55
|
-
make_openstruct(p
|
55
|
+
make_openstruct(p)
|
56
56
|
end
|
57
57
|
|
58
58
|
delorean_fn :lookup_dt, sig: 1 do
|
data/app/models/marty/script.rb
CHANGED
@@ -12,10 +12,10 @@ class Marty::Script < Marty::Base
|
|
12
12
|
|
13
13
|
gen_mcfly_lookup :lookup, [:name], cache: true
|
14
14
|
|
15
|
-
# find script by name/tag
|
15
|
+
# find script by name/tag (not cached)
|
16
16
|
def self.find_script(sname, tag=nil)
|
17
17
|
tag = Marty::Tag.map_to_tag(tag)
|
18
|
-
Marty::Script.
|
18
|
+
Marty::Script.mcfly_pt(tag.created_dt).find_by(name: sname)
|
19
19
|
end
|
20
20
|
|
21
21
|
def find_tag
|
@@ -32,7 +32,7 @@ class Marty::Script < Marty::Base
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def self.load_a_script(sname, body, dt=nil)
|
35
|
-
s = Marty::Script.
|
35
|
+
s = Marty::Script.find_by(obsoleted_dt: 'infinity', name: sname)
|
36
36
|
|
37
37
|
if !s
|
38
38
|
s = Marty::Script.new
|
data/app/models/marty/tag.rb
CHANGED
@@ -42,7 +42,6 @@ class Marty::Tag < Marty::Base
|
|
42
42
|
def self.map_to_tag(tag_id)
|
43
43
|
# FIXME: this is really hacky. This function should not take so
|
44
44
|
# many different types of arguments.
|
45
|
-
nc = {"no_convert"=>true}
|
46
45
|
case tag_id
|
47
46
|
when Integer, /\A[0-9]+\z/
|
48
47
|
tag = find_by_id(tag_id)
|
@@ -51,9 +50,9 @@ class Marty::Tag < Marty::Base
|
|
51
50
|
# if tag name wasn't found, look for a matching
|
52
51
|
# posting, then find the tag whose created_dt <= posting dt.
|
53
52
|
if !tag
|
54
|
-
|
55
|
-
|
56
|
-
|
53
|
+
cdt = Marty::Posting.where(name: tag_id).pluck('created_dt').first
|
54
|
+
|
55
|
+
tag = find_match(Mcfly.normalize_infinity(cdt)) if cdt
|
57
56
|
end
|
58
57
|
when nil
|
59
58
|
tag = get_latest1
|
data/lib/marty/mcfly_model.rb
CHANGED
@@ -55,23 +55,10 @@ module Mcfly::Model
|
|
55
55
|
def base_mcfly_lookup(meth, name, options = {}, &block)
|
56
56
|
|
57
57
|
priv = options[:private]
|
58
|
-
sig = priv ? -1 : options[:sig]
|
59
58
|
|
60
|
-
|
61
|
-
# options hash (unless private)
|
62
|
-
newsig = sig.is_a?(Array) ? [sig[0], sig[1]+1] :
|
63
|
-
sig == -1 ? sig : [sig, sig+1]
|
64
|
-
options[:sig] = newsig
|
65
|
-
|
66
|
-
send(meth, name, options) do |ts, *pargs|
|
59
|
+
send(meth, name, options) do |ts, *args|
|
67
60
|
raise "time cannot be nil" if ts.nil?
|
68
61
|
|
69
|
-
# get the options hash if method is not private and last arg is a hash
|
70
|
-
# and pargs len = max sig (-1 because ts is separated in the arg list)
|
71
|
-
args, opts = !priv && pargs.last.is_a?(Hash) &&
|
72
|
-
pargs.length == newsig[1]-1 ? [pargs[0..-2], pargs.last] :
|
73
|
-
[pargs, {}]
|
74
|
-
|
75
62
|
ts = Mcfly.normalize_infinity(ts)
|
76
63
|
|
77
64
|
q = self.where("#{table_name}.obsoleted_dt >= ? AND " +
|
@@ -80,19 +67,17 @@ module Mcfly::Model
|
|
80
67
|
end
|
81
68
|
next q if priv
|
82
69
|
|
83
|
-
fa = get_final_attrs
|
84
|
-
opts += {"fa"=>fa}
|
70
|
+
fa = get_final_attrs
|
85
71
|
q = q.select(*fa) if fa.present? && q.is_a?(ActiveRecord::Relation)
|
86
72
|
|
87
73
|
case
|
88
|
-
when opts["no_convert"] == true
|
89
|
-
q
|
90
74
|
when q.is_a?(ActiveRecord::Relation)
|
91
|
-
# shouldn't happen - lookups that are mode nil should be
|
92
|
-
# raise "#{self}.#{name} can't convert
|
75
|
+
# shouldn't happen - lookups that are mode nil should be
|
76
|
+
# private raise "#{self}.#{name} can't convert
|
77
|
+
# ActiveRecord::Relation to OpenStruct"
|
93
78
|
q
|
94
79
|
when q.is_a?(ActiveRecord::Base)
|
95
|
-
make_openstruct(q
|
80
|
+
make_openstruct(q)
|
96
81
|
else
|
97
82
|
q
|
98
83
|
end
|
@@ -102,12 +87,11 @@ module Mcfly::Model
|
|
102
87
|
def cached_mcfly_lookup(name, options = {}, &block)
|
103
88
|
base_mcfly_lookup(:cached_delorean_fn, name, options, &block)
|
104
89
|
end
|
90
|
+
|
105
91
|
def mcfly_lookup(name, options = {}, &block)
|
106
92
|
base_mcfly_lookup(:delorean_fn, name, options, &block)
|
107
93
|
end
|
108
94
|
|
109
|
-
# FIXME: add private mode. This should make the function
|
110
|
-
# unavailable to delorean.
|
111
95
|
def gen_mcfly_lookup(name, attrs, options={})
|
112
96
|
raise "bad options #{options.keys}" unless
|
113
97
|
(options.keys - [:mode, :cache, :private]).empty?
|
data/lib/marty/version.rb
CHANGED
data/lib/pyxll/README.txt
CHANGED
@@ -8,10 +8,12 @@ PyXLL - Gemini interface
|
|
8
8
|
* Install PyXLL package from Canopy
|
9
9
|
|
10
10
|
* Install gemini.py and pyxll.cfg in the canopy pyxll/ folder.
|
11
|
-
Usually installs at
|
11
|
+
Usually installs at. [OLD STEP -- this should not be needed now]
|
12
12
|
|
13
13
|
c:/Users/<usr>/AppData/Local/Enthought/Canopy32/User/Lib/site-packages/pyxll/
|
14
14
|
|
15
|
+
* pip install requests
|
16
|
+
|
15
17
|
* Should be able to see the addAdd-Ins tab in Excel and it should
|
16
18
|
include the PyXLL menu.
|
17
19
|
|
data/spec/features/rule_spec.rb
CHANGED
@@ -117,21 +117,21 @@ feature 'rule view', js: true do
|
|
117
117
|
"results"=>"",
|
118
118
|
})
|
119
119
|
|
120
|
-
r = Gemini::MyRule.
|
120
|
+
r = Gemini::MyRule.find_by(obsoleted_dt: 'infinity', name: 'abc')
|
121
121
|
expect(r.attributes).to include({"user_id"=>1,
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
122
|
+
"o_user_id"=>nil,
|
123
|
+
"name"=>"abc",
|
124
|
+
"engine"=>"Gemini::MyRuleScriptSet",
|
125
|
+
"rule_type"=>"SimpleRule",
|
126
|
+
"simple_guards"=>{"g_bool"=>false,
|
127
|
+
"g_bool_def"=>false,
|
128
|
+
"g_nbool_def"=>false,
|
129
|
+
"g_has_default"=>
|
130
|
+
"string default"},
|
131
|
+
"computed_guards"=>{},
|
132
|
+
"grids"=>{},
|
133
|
+
"results"=>{},
|
134
|
+
})
|
135
135
|
# type validation (string with values list)
|
136
136
|
mrv.select_row(1)
|
137
137
|
press("Edit")
|
@@ -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
|
+
|
245
245
|
expect(r.to_a.count).to eq(1)
|
246
246
|
exp = {"user_id"=>1,
|
247
247
|
"o_user_id"=>nil,
|
@@ -54,7 +54,7 @@ feature 'under Applications menu, Scripting workflows', js: true do
|
|
54
54
|
|
55
55
|
# create 3 additional tags and modify A5 in the process
|
56
56
|
(1..3).each { |i|
|
57
|
-
body = Marty::Script.
|
57
|
+
body = Marty::Script.find_by(name: "A5").body
|
58
58
|
|
59
59
|
Marty::Script.
|
60
60
|
load_script_bodies({
|
@@ -54,7 +54,7 @@ DELOREAN
|
|
54
54
|
}, Date.today)
|
55
55
|
|
56
56
|
# add a DEV version of M1.
|
57
|
-
s = Marty::Script.
|
57
|
+
s = Marty::Script.find_by(obsoleted_dt: 'infinity', name: "M1")
|
58
58
|
s.body = sample_script.gsub(/A/, "AA") + ' e =? "hello"'
|
59
59
|
s.save!
|
60
60
|
}
|
@@ -35,43 +35,32 @@ A:
|
|
35
35
|
pt =?
|
36
36
|
entity =?
|
37
37
|
note_rate =?
|
38
|
+
e_id =?
|
39
|
+
bc_id =?
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
-
"bud_category": "name"}}
|
42
|
-
ex2 = {"include_attrs": ["settlement_mm", "settlement_yy", "entity_id",
|
43
|
-
"bud_category_id"]}
|
41
|
+
lookup = Gemini::FannieBup.lookup( pt, entity, note_rate)
|
42
|
+
clookup = Gemini::FannieBup.clookup( pt, entity, note_rate)
|
44
43
|
|
45
|
-
|
46
|
-
lookup_extra = Gemini::FannieBup.lookup( pt, entity, note_rate, extra)
|
44
|
+
lookupn = Gemini::FannieBup.lookupn( pt, entity, note_rate)
|
47
45
|
|
48
|
-
|
49
|
-
|
50
|
-
lookupn = Gemini::FannieBup.lookupn( pt, entity, note_rate)
|
51
|
-
lookupn_extra = Gemini::FannieBup.lookupn( pt, entity, note_rate, ex2)
|
52
|
-
|
53
|
-
clookupn = Gemini::FannieBup.clookupn(pt, entity, note_rate)
|
54
|
-
|
55
|
-
a_func = Gemini::FannieBup.a_func('infinity', 1, 2)
|
56
|
-
a_func_extra = Gemini::FannieBup.a_func('infinity', 1, 2, ex2)
|
57
|
-
b_func = Gemini::FannieBup.b_func('infinity',1, 2, 12)
|
58
|
-
b_func_extra = Gemini::FannieBup.b_func('infinity',1, 2, 12, extra)
|
59
|
-
ca_func = Gemini::FannieBup.ca_func('infinity',1, 2, ex2)
|
46
|
+
clookupn = Gemini::FannieBup.clookupn(pt, entity, note_rate)
|
60
47
|
|
48
|
+
a_func = Gemini::FannieBup.a_func('infinity', e_id, bc_id)
|
49
|
+
b_func = Gemini::FannieBup.b_func('infinity', e_id, bc_id, 12)
|
61
50
|
EOF
|
62
51
|
errscript =<<EOF
|
63
52
|
Err:
|
64
53
|
pt =?
|
65
54
|
entity =?
|
66
55
|
note_rate =?
|
67
|
-
result = Gemini::FannieBup.%s(pt, entity, note_rate)
|
56
|
+
result = Gemini::FannieBup.%s(pt, entity, note_rate, 1)
|
68
57
|
EOF
|
69
58
|
errscript2 =<<EOF
|
70
59
|
Err:
|
71
60
|
pt =?
|
72
61
|
e_id =?
|
73
62
|
bc_id =?
|
74
|
-
result = Gemini::FannieBup.%s(pt, e_id, bc_id)
|
63
|
+
result = Gemini::FannieBup.%s(pt, e_id, bc_id, nil)
|
75
64
|
EOF
|
76
65
|
errscript3 =<<EOF
|
77
66
|
Err:
|
@@ -79,7 +68,7 @@ Err:
|
|
79
68
|
e_id =?
|
80
69
|
bc_id =?
|
81
70
|
mm =?
|
82
|
-
result = Gemini::FannieBup.%s(pt, e_id, bc_id, mm)
|
71
|
+
result = Gemini::FannieBup.%s(pt, e_id, bc_id, mm, {})
|
83
72
|
EOF
|
84
73
|
|
85
74
|
describe 'McflyModel' do
|
@@ -131,84 +120,32 @@ EOF
|
|
131
120
|
end
|
132
121
|
|
133
122
|
it "lookup non generated" do
|
134
|
-
# a1
|
135
|
-
# b1
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
123
|
+
# a1 will be AR Relations
|
124
|
+
# b1 will be OpenStructs because the b fns return #first
|
125
|
+
e_id = Gemini::Entity.where(name: "PLS").first.id
|
126
|
+
bc_id = Gemini::BudCategory.where(name: "Conv Fixed 20").first.id
|
127
|
+
p = {"e_id"=>e_id, "bc_id"=>bc_id}
|
128
|
+
a1 = @engine.evaluate("A", "a_func", p)
|
129
|
+
b1 = @engine.evaluate("A", "b_func", p)
|
141
130
|
|
142
131
|
# all return relations
|
143
132
|
expect(ActiveRecord::Relation === a1).to be_truthy
|
144
|
-
expect(ActiveRecord::Relation === a2).to be_truthy
|
145
|
-
expect(ActiveRecord::Relation === a3).to be_truthy
|
146
133
|
expect(ActiveRecord::Base === a1.first).to be_truthy
|
147
|
-
expect(ActiveRecord::Base === a2.first).to be_truthy
|
148
|
-
expect(ActiveRecord::Base === a3.first).to be_truthy
|
149
134
|
|
150
135
|
expect(a1.to_a.count).to eq(2)
|
151
|
-
expect(a2.to_a.count).to eq(2)
|
152
|
-
expect(a3.to_a.count).to eq(2)
|
153
136
|
|
154
137
|
# a1 lookup did not include extra attrs
|
155
138
|
expect(a1.first.attributes.keys.to_set).to eq(Set["id", "buy_up", "buy_down"])
|
156
139
|
|
157
|
-
# a2 and a3 did
|
158
|
-
s = Set["id", "entity_id", "bud_category_id", "buy_up", "buy_down",
|
159
|
-
"settlement_mm", "settlement_yy"]
|
160
|
-
expect(a2.first.attributes.keys.to_set).to eq(s)
|
161
|
-
expect(a3.first.attributes.keys.to_set).to eq(s)
|
162
|
-
|
163
140
|
# a1 is AR but still missing the FK entity_id so will raise
|
164
141
|
expect{a1.first.entity}.to raise_error(/missing attribute: entity_id/)
|
165
142
|
|
166
|
-
# a3 included those so can access them
|
167
|
-
expect(a3.first.entity.name).to eq('PLS')
|
168
|
-
expect(a3.first.bud_category.name).to eq('Conv Fixed 20')
|
169
|
-
|
170
143
|
expect(b1.class).to eq(OpenStruct)
|
171
|
-
expect(b2.class).to eq(OpenStruct)
|
172
144
|
|
173
|
-
# make sure b1
|
145
|
+
# make sure b1 has correct keys
|
174
146
|
expect(b1.to_h.keys.to_set).to eq(Set[:buy_up, :buy_down])
|
175
|
-
expect(b2.to_h.keys.to_set).to eq(
|
176
|
-
Set[:buy_up, :buy_down, :settlement_mm, :settlement_yy,
|
177
|
-
:entity, :bud_category])
|
178
|
-
expect(b2.entity.name).to eq('PLS')
|
179
|
-
expect(b2.bud_category.name).to eq('Conv Fixed 20')
|
180
147
|
end
|
181
|
-
it "lookup extra values" do
|
182
|
-
a2 = @engine.evaluate("A", "lookup_extra", params)
|
183
|
-
expect(a2.class).to eq(OpenStruct)
|
184
148
|
|
185
|
-
# check that extra values are there
|
186
|
-
expect(a2.to_h.keys.to_set).to eq(Set[:buy_up, :buy_down, :settlement_mm,
|
187
|
-
:settlement_yy, :entity,
|
188
|
-
:bud_category])
|
189
|
-
# check that linked values are there
|
190
|
-
expect(a2.entity.name).to eq("PLS")
|
191
|
-
expect(a2.bud_category.name).to eq("Conv Fixed 20")
|
192
|
-
end
|
193
|
-
it "lookup mode nil extra values" do
|
194
|
-
all = @engine.evaluate("A", "lookupn_extra", params)
|
195
|
-
|
196
|
-
# mode nil always returns AR
|
197
|
-
expect(ActiveRecord::Relation === all).to be_truthy
|
198
|
-
|
199
|
-
# check keys returned
|
200
|
-
all.each do |a2|
|
201
|
-
expect(a2.attributes.keys.to_set).to eq(
|
202
|
-
Set["id", "buy_up", "buy_down", "settlement_mm",
|
203
|
-
"settlement_yy", "entity_id", "bud_category_id"])
|
204
|
-
if a2.entity_id
|
205
|
-
expect(a2.entity.name).to eq("PLS")
|
206
|
-
expect(ActiveRecord::Base === a2.entity).to be_truthy
|
207
|
-
expect(a2.bud_category.name).to eq("Conv Fixed 20")
|
208
|
-
expect(ActiveRecord::Base === a2.bud_category).to be_truthy
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
149
|
it "lookup mode nil" do
|
213
150
|
# make sure ARs are returned
|
214
151
|
a1 = @engine.evaluate("A", "lookupn", params)
|
@@ -217,16 +154,21 @@ EOF
|
|
217
154
|
expect(ActiveRecord::Relation === a1).to be_truthy
|
218
155
|
expect(a1.to_a.count).to eq(4)
|
219
156
|
end
|
157
|
+
|
220
158
|
it "private methods can't be called by delorean" do
|
221
159
|
# generated methods
|
222
160
|
aggregate_failures "errors" do
|
223
161
|
@errs.in_groups_of(2) do |name, fn|
|
224
162
|
err = /Too many args to #{fn}/
|
225
|
-
|
226
|
-
|
163
|
+
|
164
|
+
expect{
|
165
|
+
Marty::ScriptSet.new.get_engine(name)
|
166
|
+
}.to raise_error(Delorean::BadCallError, err)
|
227
167
|
end
|
228
168
|
end
|
169
|
+
end
|
229
170
|
|
171
|
+
it "private methods can't be called by delorean (2)" do
|
230
172
|
# non-generated
|
231
173
|
aggregate_failures "errors" do
|
232
174
|
['E5', 'a_func_p', 'E6', 'b_func_p'].in_groups_of(2) do |scr, fn|
|
@@ -236,6 +178,7 @@ EOF
|
|
236
178
|
end
|
237
179
|
end
|
238
180
|
end
|
181
|
+
|
239
182
|
it "caching times" do
|
240
183
|
ts = DateTime.now
|
241
184
|
x=Benchmark.measure { 10000.times {
|
@@ -244,7 +187,7 @@ EOF
|
|
244
187
|
}
|
245
188
|
}
|
246
189
|
y=Benchmark.measure { 10000.times {
|
247
|
-
Gemini::FannieBup.ca_func(ts,
|
190
|
+
Gemini::FannieBup.ca_func(ts,
|
248
191
|
1, 2)
|
249
192
|
}
|
250
193
|
}
|
@@ -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.
|
53
|
+
s = Marty::Script.find_by(obsoleted_dt: 'infinity', name: 'Script1')
|
54
54
|
s.body = "A:\n a = 3\n"
|
55
55
|
s.save!
|
56
56
|
|
@@ -197,19 +197,6 @@ EOS
|
|
197
197
|
end
|
198
198
|
|
199
199
|
describe "validations" do
|
200
|
-
it "a basic data grid should load ok" do
|
201
|
-
dg_from_import("G1", G1)
|
202
|
-
dg_from_import("G2", G2)
|
203
|
-
dg_from_import("G3", G3)
|
204
|
-
dg_from_import("G8", G8)
|
205
|
-
dg_from_import("Ga", Ga)
|
206
|
-
|
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"
|
211
|
-
end
|
212
|
-
|
213
200
|
it "should not allow bad axis types" do
|
214
201
|
expect {
|
215
202
|
dg_from_import("Gi", Gi)
|
@@ -416,7 +403,7 @@ EOS
|
|
416
403
|
expect(res).to eq [5.6,"G2"]
|
417
404
|
}
|
418
405
|
|
419
|
-
dg = Marty::DataGrid.
|
406
|
+
dg = Marty::DataGrid.find_by(obsoleted_dt: 'infinity', name: "G1")
|
420
407
|
|
421
408
|
h = {
|
422
409
|
"fico" => 600,
|
@@ -581,7 +568,7 @@ EOS
|
|
581
568
|
end
|
582
569
|
|
583
570
|
it "should handle DataGrid typed data grids" do
|
584
|
-
g1 = Marty::DataGrid.
|
571
|
+
g1 = Marty::DataGrid.find_by(obsoleted_dt: 'infinity', name: "G1")
|
585
572
|
|
586
573
|
res = lookup_grid_helper('infinity',
|
587
574
|
"Ga",
|
@@ -716,19 +703,15 @@ EOS
|
|
716
703
|
"\u201C", "\u201D"]
|
717
704
|
100.times do
|
718
705
|
st = 30.times.map{quotes[rand(9)]}.join
|
719
|
-
res = Marty::DataGrid.lookup_grid_distinct_entry_h(
|
720
|
-
|
721
|
-
"state" => st }, dgh, nil,
|
722
|
-
false, true)
|
706
|
+
res = Marty::DataGrid.lookup_grid_distinct_entry_h(
|
707
|
+
pt, {"ltv" => 10, "fico" => 690, "state" => st}, dgh, nil, false, true)
|
723
708
|
end
|
724
709
|
end
|
725
710
|
it "should handle quote chars in object name" do
|
726
711
|
dgh = Marty::DataGrid.lookup_h(pt, 'G1')
|
727
712
|
st = Gemini::State.new(name: "'\\")
|
728
|
-
res = Marty::DataGrid.lookup_grid_distinct_entry_h(
|
729
|
-
|
730
|
-
"state" => st }, dgh, nil,
|
731
|
-
false, true)
|
713
|
+
res = Marty::DataGrid.lookup_grid_distinct_entry_h(
|
714
|
+
pt, {"ltv" => 10, "fico" => 690, "state" => st}, dgh, nil, false, true)
|
732
715
|
end
|
733
716
|
end
|
734
717
|
|
@@ -814,19 +797,13 @@ EOS
|
|
814
797
|
|
815
798
|
res11 = res.sub(/G1/, "G11")
|
816
799
|
|
817
|
-
sum = do_import_summary(
|
818
|
-
|
819
|
-
'infinity',
|
820
|
-
nil,
|
821
|
-
nil,
|
822
|
-
",",
|
823
|
-
)
|
800
|
+
sum = do_import_summary(
|
801
|
+
Marty::DataGrid, res11, 'infinity', nil, nil, ",")
|
824
802
|
|
825
803
|
expect(sum).to eq({create: 1})
|
826
804
|
|
827
|
-
|
828
|
-
|
829
|
-
g11 = Marty::DataGrid.lookup('infinity', "G11", nc)
|
805
|
+
g1 = Marty::DataGrid.find_by(obsoleted_dt: 'infinity', name: "G1")
|
806
|
+
g11 = Marty::DataGrid.find_by(obsoleted_dt: 'infinity', name: "G11")
|
830
807
|
|
831
808
|
expect(g1.export).to eq g11.export
|
832
809
|
end
|
data/spec/models/rule_spec.rb
CHANGED
@@ -170,68 +170,67 @@ module Marty::RuleSpec
|
|
170
170
|
|
171
171
|
context "lookups" do
|
172
172
|
it "matches" do
|
173
|
-
nc = {"no_convert"=>true}
|
174
173
|
lookup = Gemini::MyRule.get_matches('infinity',
|
175
174
|
{'rule_type'=>'SimpleRule'},
|
176
|
-
{'g_array'=>'G1V3'}
|
175
|
+
{'g_array'=>'G1V3'})
|
177
176
|
expect(lookup.to_a.count).to eq(1)
|
178
177
|
expect(lookup.first.name).to eq("Rule1")
|
179
178
|
lookup = Gemini::MyRule.get_matches('infinity',
|
180
179
|
{'rule_type'=>'SimpleRule',
|
181
180
|
|
182
181
|
'other_flag'=>true},
|
183
|
-
{}
|
182
|
+
{})
|
184
183
|
expect(lookup.to_a.count).to eq(4)
|
185
184
|
expect(lookup.map{|l|l.name}.to_set).to eq(Set["Rule2","Rule2a",
|
186
185
|
"Rule2b", "Rule2c"])
|
187
186
|
lookup = Gemini::MyRule.get_matches('infinity',
|
188
187
|
{'rule_type'=>'ComplexRule',
|
189
188
|
'other_flag'=>false},
|
190
|
-
{}
|
189
|
+
{})
|
191
190
|
expect(lookup.to_a.count).to eq(1)
|
192
191
|
expect(lookup.first.name).to eq("Rule3")
|
193
192
|
# bool false matches bool nil
|
194
193
|
lookup = Gemini::MyRule.get_matches('infinity',
|
195
194
|
{'rule_type'=>'ComplexRule',
|
196
195
|
'other_flag'=>false},
|
197
|
-
{'g_bool'=>false}
|
196
|
+
{'g_bool'=>false})
|
198
197
|
expect(lookup.to_a.count).to eq(1)
|
199
198
|
expect(lookup.first.name).to eq("Rule3")
|
200
199
|
lookup = Gemini::MyRule.get_matches('infinity',
|
201
200
|
{'rule_type'=>'ComplexRule'},
|
202
|
-
{'g_string'=>'def'}
|
201
|
+
{'g_string'=>'def'})
|
203
202
|
expect(lookup.to_a.count).to eq(1)
|
204
203
|
expect(lookup.first.name).to eq("Rule3")
|
205
204
|
lookup = Gemini::MyRule.get_matches('infinity',
|
206
205
|
{'rule_type'=>'ComplexRule'},
|
207
|
-
{'g_string'=>'abc'}
|
206
|
+
{'g_string'=>'abc'})
|
208
207
|
expect(lookup).to eq([])
|
209
208
|
lookup = Gemini::MyRule.get_matches('infinity',
|
210
209
|
{'rule_type'=>'SimpleRule'},
|
211
210
|
{'g_bool'=>true, "g_range"=>25,
|
212
|
-
'g_integer'=>99}
|
211
|
+
'g_integer'=>99})
|
213
212
|
expect(lookup.to_a.count).to eq(1)
|
214
213
|
expect(lookup.first.name).to eq("Rule2a")
|
215
214
|
lookup = Gemini::MyRule.get_matches('infinity',
|
216
215
|
{'rule_type'=>'SimpleRule'},
|
217
|
-
{'g_bool'=>true, "g_range"=>75}
|
216
|
+
{'g_bool'=>true, "g_range"=>75})
|
218
217
|
expect(lookup.to_a.count).to eq(1)
|
219
218
|
expect(lookup.first.name).to eq("Rule1")
|
220
219
|
lookup = Gemini::MyRule.get_matches('infinity',
|
221
220
|
{'rule_type'=>'SimpleRule'},
|
222
221
|
{'g_bool'=>true, "g_range"=>75,
|
223
|
-
'g_integer'=>11}
|
222
|
+
'g_integer'=>11})
|
224
223
|
expect(lookup).to eq([])
|
225
224
|
lookup = Gemini::MyRule.get_matches('infinity',
|
226
225
|
{'rule_type'=>'SimpleRule'},
|
227
226
|
{'g_bool'=>true, "g_range"=>75,
|
228
|
-
'g_integer'=>10}
|
227
|
+
'g_integer'=>10})
|
229
228
|
expect(lookup.to_a.count).to eq(1)
|
230
229
|
expect(lookup.first.name).to eq("Rule1")
|
231
230
|
lookup = Gemini::MyRule.get_matches('infinity',
|
232
231
|
{'rule_type'=>'SimpleRule'},
|
233
232
|
{'g_bool'=>false, "g_range"=>25,
|
234
|
-
'g_integer'=>10}
|
233
|
+
'g_integer'=>10})
|
235
234
|
expect(lookup.to_a.count).to eq(1)
|
236
235
|
expect(lookup.first.name).to eq("Rule2c")
|
237
236
|
lookup = Gemini::MyRule.get_matches('infinity',
|
@@ -239,13 +238,13 @@ module Marty::RuleSpec
|
|
239
238
|
expect(lookup.to_a.count).to eq(5)
|
240
239
|
lookup = Gemini::MyRule.get_matches('infinity',
|
241
240
|
{'rule_dt'=>"2017-3-1 02:00:00"},
|
242
|
-
{}
|
241
|
+
{})
|
243
242
|
expect(lookup.to_a.count).to eq(6)
|
244
243
|
expect(lookup.pluck(:name).to_set).to eq(Set["Rule1", "Rule2", "Rule2a",
|
245
244
|
"Rule2b", "Rule2c", "Rule3"])
|
246
245
|
lookup = Gemini::MyRule.get_matches('infinity',
|
247
246
|
{'rule_dt'=>"2017-4-1 16:00:00"},
|
248
|
-
{}
|
247
|
+
{})
|
249
248
|
expect(lookup.to_a.count).to eq(1)
|
250
249
|
expect(lookup.pluck(:name).first).to eq("Rule4")
|
251
250
|
lookup = Gemini::MyRule.get_matches('infinity',
|
@@ -256,40 +255,39 @@ module Marty::RuleSpec
|
|
256
255
|
expect(lookup.to_a).to eq([])
|
257
256
|
lookup = Gemini::MyRule.get_matches('infinity', {},
|
258
257
|
{"g_bool_def"=>false,
|
259
|
-
"g_nbool_def"=>true}
|
258
|
+
"g_nbool_def"=>true})
|
260
259
|
expect(lookup.to_a.count).to eq(1)
|
261
260
|
expect(lookup.pluck(:name).first).to eq("Rule1")
|
262
261
|
end
|
263
262
|
end
|
264
263
|
context "rule compute" do
|
265
|
-
let(:nc) {{"no_convert"=>true}}
|
266
264
|
let(:complex) { Gemini::MyRule.get_matches('infinity',
|
267
265
|
{'rule_type'=>'ComplexRule'},
|
268
|
-
{'g_string'=>'def'}
|
266
|
+
{'g_string'=>'def'}).first }
|
269
267
|
let(:xyz) { Gemini::XyzRule.get_matches('infinity',
|
270
268
|
{'rule_type'=>'ZRule'},
|
271
|
-
{'g_integer'=> 2}
|
269
|
+
{'g_integer'=> 2}).first }
|
272
270
|
let(:simple) {
|
273
271
|
Gemini::MyRule.get_matches('infinity',
|
274
272
|
{'rule_type'=>'SimpleRule'},
|
275
|
-
{'g_bool'=>true, "g_range"=>25}
|
273
|
+
{'g_bool'=>true, "g_range"=>25}).first }
|
276
274
|
let(:simple2a) {
|
277
275
|
Gemini::MyRule.get_matches('infinity',
|
278
276
|
{'rule_type'=>'SimpleRule'},
|
279
|
-
{'g_bool'=>true, "g_integer"=>99}
|
277
|
+
{'g_bool'=>true, "g_integer"=>99}).first }
|
280
278
|
let(:simple2b) {
|
281
279
|
Gemini::MyRule.get_matches('infinity',
|
282
280
|
{'rule_type'=>'SimpleRule'},
|
283
|
-
{'g_bool'=>true, "g_integer"=>999}
|
281
|
+
{'g_bool'=>true, "g_integer"=>999}).first }
|
284
282
|
let(:altgridmethod) {
|
285
283
|
Gemini::MyRule.get_matches('infinity',
|
286
284
|
{'rule_type'=>'ComplexRule'},
|
287
|
-
{"g_integer"=>3757}
|
285
|
+
{"g_integer"=>3757}).first }
|
288
286
|
let(:gridcomputedname) {
|
289
287
|
Gemini::MyRule.get_matches('infinity',
|
290
288
|
{'rule_type'=>'ComplexRule'},
|
291
289
|
{"g_string"=>"Hi Mom",
|
292
|
-
"g_integer"=>11}
|
290
|
+
"g_integer"=>11}).first }
|
293
291
|
it "computed guards work" do
|
294
292
|
c = complex.compute({"pt"=>Time.zone.now,
|
295
293
|
'param2'=>'def'})
|
@@ -313,11 +311,12 @@ module Marty::RuleSpec
|
|
313
311
|
"sr2"=>true,
|
314
312
|
"sr3"=>123})
|
315
313
|
# simple2b should return grid results without evaluation
|
316
|
-
expect(simple2b.
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
314
|
+
expect(simple2b.
|
315
|
+
compute({"pt"=>Time.zone.now,
|
316
|
+
'param1'=> 66,
|
317
|
+
'param2'=>'abc',
|
318
|
+
'paramb'=>false})).to eq({"grid1_grid_result"=>3,
|
319
|
+
"grid2_grid_result"=>1300})
|
321
320
|
|
322
321
|
end
|
323
322
|
it "returns computed results" do
|
data/spec/models/script_spec.rb
CHANGED
@@ -17,9 +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.
|
21
|
-
|
22
|
-
to eq(now.to_s)
|
20
|
+
expect(Marty::Script.find_by(obsoleted_dt: 'infinity', name: 'TestNew').
|
21
|
+
created_dt.to_s).to eq(now.to_s)
|
23
22
|
end
|
24
23
|
|
25
24
|
it "doesn't create a new script entry if it already exists and is the " +
|
@@ -40,8 +39,9 @@ describe Marty::Script do
|
|
40
39
|
s2, now) }.
|
41
40
|
to change { Marty::Script.where(name: 'TestExistsAndDifferent2',
|
42
41
|
obsoleted_dt: 'infinity').count }.by(0)
|
43
|
-
expect(Marty::Script.
|
44
|
-
|
42
|
+
expect(Marty::Script.find_by(
|
43
|
+
obsoleted_dt: 'infinity', name: 'TestExistsAndDifferent2').
|
44
|
+
created_dt.to_s).to eq(now.to_s)
|
45
45
|
end
|
46
46
|
end
|
47
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.3
|
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-04-
|
17
|
+
date: 2018-04-16 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: pg
|