marty 2.0.2 → 2.0.3
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 +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
|