marty 1.0.42 → 1.0.43

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c9b9b42bbdeeada46c3064d29dc28140076dbb2a
4
- data.tar.gz: afa5534bdeb008725d64f7ac81c342ad58c6a7f9
3
+ metadata.gz: b66276891458efd498648be59d402697d007be05
4
+ data.tar.gz: 6fd5ee9414488b17042c87bb1439ca1021d371b6
5
5
  SHA512:
6
- metadata.gz: 578d03d84c806f58c5ac5caca2f25535de98e0499cb78cda5c2329ce25a50218cf500114e332ecd9cbdc3b696dd3ac881f28ceac69fa184c5d50d543496276d3
7
- data.tar.gz: 54991e5001815e0adcfd5eea4108cd15cdd234dc7a698bafffae8299fcc9434f5c33e62e6a99133deab0030aa78459b005396e718b5c0c5653cc763294ad5d61
6
+ metadata.gz: acff2e6a1842b34ed8ec5c17e8d15bd314723eae74cc11e043ca8f4f23bee95da6c0a46a56dca72bec7e248878f2849b517fb8f8397f3f1873ffd3658bd6c0d5
7
+ data.tar.gz: b596a59fd785a72531318a652dc9f20c71944df9a433e5b8db183316d4434015c974cc0276940ca7c3d418f94e49fbd07d6fbc228447c2fd63172f03bab0ff4c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- marty (1.0.39)
4
+ marty (1.0.43)
5
5
  axlsx (= 2.1.0pre)
6
6
  coderay
7
7
  delorean_lang (~> 0.1)
@@ -224,4 +224,4 @@ DEPENDENCIES
224
224
  timecop
225
225
 
226
226
  BUNDLED WITH
227
- 1.15.4
227
+ 1.16.0.pre.2
@@ -34,6 +34,24 @@ class Marty::RpcController < ActionController::Base
34
34
  end
35
35
  end
36
36
 
37
+ def _get_errors(errs)
38
+ if errs.is_a?(Array)
39
+ errs.map { |err| _get_errors(err) }
40
+ elsif errs.is_a?(Hash)
41
+ if !errs.include?(:failed_attribute)
42
+ errs.map { |k, v| _get_errors(v) }
43
+ else
44
+ fa, message, errors = errs.values_at(:failed_attribute,
45
+ :message, :errors)
46
+ (['AllOf','AnyOf','Not'].include?(fa) ? [] : [message]) +
47
+ _get_errors(errors || {})
48
+ end
49
+ end
50
+ end
51
+ def get_errors(errs)
52
+ _get_errors(errs).flatten
53
+ end
54
+
37
55
  def do_eval(sname, tag, node, attrs, params, api_key, background)
38
56
  return {error: "Malformed attrs"} unless attrs.is_a?(String)
39
57
 
@@ -95,7 +113,8 @@ class Marty::RpcController < ActionController::Base
95
113
  rescue => ex
96
114
  return {error: "#{attr}: #{ex.message}"}
97
115
  end
98
- validation_error[attr] = er.map{ |e| e[:message] } if er.size > 0
116
+
117
+ validation_error[attr] = get_errors(er) if er.size > 0
99
118
  err_count += er.size
100
119
  end
101
120
  end
@@ -187,6 +187,7 @@ EOSQL
187
187
  encode(line.encoding, :crlf_newline => true)
188
188
  end
189
189
  end
190
+
190
191
  def self.generate_sql_migrations(migrations_dir, sql_files_dir)
191
192
  sd = Rails.root.join(sql_files_dir)
192
193
  md = Rails.root.join(migrations_dir)
@@ -218,7 +219,8 @@ EOSQL
218
219
  newbase = "#{timestamp}_#{klass}"
219
220
  mig_name = File.join(md, "#{newbase}.rb")
220
221
  sql_snap_literal = Rails.root.join(md, 'sql', "#{newbase}.sql")
221
- sql_snap_call = "Rails.root.join('#{migrations_dir}', 'sql', '#{newbase}.sql')"
222
+ sql_snap_call =
223
+ "Rails.root.join('#{migrations_dir}', 'sql', '#{newbase}.sql')"
222
224
 
223
225
  File.open(sql_snap_literal, "w") do |f|
224
226
  f.print sql_lines.join
@@ -0,0 +1,42 @@
1
+ class Marty::SchemaHelper
2
+ include Delorean::Model
3
+ delorean_fn :enum_is, sig: 2 do
4
+ |var, value|
5
+ {"properties"=> {var => { "enum"=> value}}}
6
+ end
7
+ delorean_fn :bool_is, sig: 2 do
8
+ |var, value|
9
+ {"properties"=> {var => { "type"=> "boolean", "enum"=> [value]}}}
10
+ end
11
+
12
+ delorean_fn :or, sig: [1, 20] do
13
+ |*args|
14
+ {"anyOf"=>args}
15
+ end
16
+
17
+ delorean_fn :and, sig: [1, 20] do
18
+ |*args|
19
+ {"allOf"=>args}
20
+ end
21
+
22
+ delorean_fn :not, sig: 1 do
23
+ |arg|
24
+ {"not"=>{"allOf"=>[arg]}}
25
+ end
26
+
27
+ # if conds is true, var_array columns we be required
28
+ delorean_fn :required_if, sig: [2, 20] do
29
+ |var_array, *conds_array|
30
+ {"anyOf"=>[{"not"=>{"allOf"=> conds_array}},
31
+ {"required"=>var_array}]}
32
+ end
33
+
34
+ # if dep_column is present, checks must pass
35
+ delorean_fn :dep_check, sig: [2, 20] do
36
+ |dep_column, *checks|
37
+ {"dependencies"=> {dep_column =>
38
+ {"type"=>"object",
39
+ "allOf"=> checks}}}
40
+ end
41
+
42
+ end
data/lib/marty/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Marty
2
- VERSION = "1.0.42"
2
+ VERSION = "1.0.43"
3
3
  end
@@ -89,6 +89,35 @@ A:
89
89
  result = [{"a": 1, "b": res}, {"a": 789, "b": res}]
90
90
  eof
91
91
 
92
+ sample_script10 = <<eof
93
+ A:
94
+ opt1 =?
95
+ optn =?
96
+ opttf =?
97
+ opttrue =?
98
+ optfalse =?
99
+ req1 =?
100
+ req2 =?
101
+ req3 =?
102
+
103
+ optif = if opttf == true
104
+ then opttrue
105
+ else if opttf == false
106
+ then optfalse
107
+ else nil
108
+
109
+ v1 = if req1 == 'no opts'
110
+ then req2
111
+ else if req1 == "opt1"
112
+ then opt1
113
+ else if req2 != 'no opts'
114
+ then optn
115
+ else if req3 == "opttf"
116
+ then optif
117
+ else 'req3'
118
+
119
+ eof
120
+
92
121
  script3_schema = <<eof
93
122
  A:
94
123
  pc = { "properties : {
@@ -227,6 +256,56 @@ A:
227
256
  }
228
257
  eof
229
258
 
259
+ script10_schema = <<eof
260
+ A:
261
+ properties = {
262
+ "opt1" : { "type" : "string" },
263
+ "opttf" : { "type" : "boolean" },
264
+ "opttrue" : { "type" : "string" },
265
+ "optfalse" : { "type" : "string" },
266
+ "req1" : { "pg_enum" : "CondEnum" },
267
+ "req2" : { "pg_enum" : "CondEnum" }
268
+ }
269
+
270
+ req1_is_opt1 = Marty::SchemaHelper.enum_is('req1', ['opt1'])
271
+ req2_is_not_no_opts = Marty::SchemaHelper.not(
272
+ Marty::SchemaHelper.enum_is('req2', ['no opts']))
273
+ req3_is_opttf = Marty::SchemaHelper.enum_is('req3', ['opttf'])
274
+ opttf_is_true = Marty::SchemaHelper.bool_is('opttf', true)
275
+ opttf_is_false = Marty::SchemaHelper.bool_is('opttf', false)
276
+
277
+ # opt1 is required if req1 == 'opt1'
278
+ opt1_check = Marty::SchemaHelper.required_if(['opt1'], req1_is_opt1)
279
+
280
+ # optn is required if req2 != 'no opts'
281
+ optn_check = Marty::SchemaHelper.required_if(['optn'], req2_is_not_no_opts)
282
+
283
+ # opttf is required if req3 == 'opttf'
284
+ opttf_check = Marty::SchemaHelper.required_if(['opttf'], req3_is_opttf)
285
+
286
+ # opttrue is required if opttf is true
287
+ opttrue_check = Marty::SchemaHelper.required_if(['opttrue'], opttf_is_true)
288
+
289
+ # optfalse is required if opttf is false
290
+ optfalse_check = Marty::SchemaHelper.required_if(['optfalse'],
291
+ opttf_is_false)
292
+
293
+ # opttf is optional (contingent on req3) so eval of opttrue_check
294
+ # and optfalse_check is dependent upon opttf existing
295
+ opttruefalse_check = Marty::SchemaHelper.dep_check('opttf',
296
+ opttrue_check,
297
+ optfalse_check)
298
+
299
+ v1 = { "properties": properties,
300
+ "required": ["req1", "req2", "req3"],
301
+ "allOf": [
302
+ opt1_check,
303
+ optn_check,
304
+ opttf_check,
305
+ opttruefalse_check
306
+ ] }
307
+ eof
308
+
230
309
  describe Marty::RpcController do
231
310
  before(:each) {
232
311
  @routes = Marty::Engine.routes
@@ -250,6 +329,7 @@ describe Marty::RpcController do
250
329
  "M7" => sample_script7,
251
330
  "M8" => sample_script8,
252
331
  "M9" => sample_script9,
332
+ "M10" => sample_script10,
253
333
  "M3Schemas" => script3_schema,
254
334
  "M4Schemas" => script4_schema,
255
335
  "M5Schemas" => script5_schema,
@@ -257,6 +337,7 @@ describe Marty::RpcController do
257
337
  "M7Schemas" => script7_schema,
258
338
  "M8Schemas" => script8_schema,
259
339
  "M9Schemas" => script9_schema,
340
+ "M10Schemas" => script10_schema,
260
341
  }, Date.today + 1.minute)
261
342
 
262
343
  @p1 = Marty::Posting.do_create("BASE", Date.today + 2.minute, 'a comment')
@@ -792,6 +873,9 @@ describe Marty::RpcController do
792
873
  class FruitsEnum
793
874
  VALUES=Set['Apple', 'Banana', 'Orange']
794
875
  end
876
+ class CondEnum
877
+ VALUES=Set['no opts','opt1','opt2','opttf']
878
+ end
795
879
 
796
880
  it "validates schema with a pg_enum (Positive)" do
797
881
  Marty::ApiConfig.create!(script: "M5",
@@ -1033,6 +1117,61 @@ describe Marty::RpcController do
1033
1117
  expect(response.body).to match(/"error":"Permission denied"/)
1034
1118
  end
1035
1119
 
1120
+ context "conditional validation" do
1121
+ before(:all) do
1122
+ Marty::ApiConfig.create!(script: "M10",
1123
+ node: "A",
1124
+ attr: nil,
1125
+ logged: false,
1126
+ input_validated: true,
1127
+ output_validated: false,
1128
+ strict_validate: false)
1129
+ end
1130
+ def do_call(req1, req2, req3, optionals={})
1131
+ attrs = ["v1"].to_json
1132
+ params = optionals.merge({"req1" => req1,
1133
+ "req2"=> req2,
1134
+ "req3"=> req3}).to_json
1135
+ get 'evaluate', {
1136
+ format: :json,
1137
+ script: "M10",
1138
+ node: "A",
1139
+ attrs: attrs,
1140
+ params: params
1141
+ }
1142
+ end
1143
+
1144
+ it "does conditional" do
1145
+ aggregate_failures "conditionals" do
1146
+ [# first group has all required fields
1147
+ [['opt1', 'no opts', 'no opts', opt1: 'hi mom'], "hi mom"],
1148
+ [['no opts', 'no opts', 'no opts', opt1: 'hi mom'], "no opts"],
1149
+ [['opt2', 'opt2', 'no opts', optn: 'foo'], 'foo'],
1150
+ [['opt2', 'no opts', 'opt2'], 'req3'],
1151
+ [['opt2', 'no opts', 'opttf', opttf: true, opttrue: 'bar'], 'bar'],
1152
+ [['opt2', 'no opts', 'opttf', opttf: false, optfalse: 'baz'], 'baz'],
1153
+ # second group is missing fields
1154
+ [['opt1', 'no opts', 'no opts'],
1155
+ "did not contain a required property of 'opt1'"],
1156
+ [['opt2', 'opt2', 'no opts',],
1157
+ "did not contain a required property of 'optn'"],
1158
+ [['opt2', 'no opts', 'opttf'],
1159
+ "did not contain a required property of 'opttf'"],
1160
+ [['opt2', 'no opts', 'opttf', opttf: true],
1161
+ "did not contain a required property of 'opttrue'"],
1162
+ [['opt2', 'no opts', 'opttf', opttf: false],
1163
+ "did not contain a required property of 'optfalse'"],
1164
+ ].each do
1165
+ |a, exp|
1166
+ do_call(*a)
1167
+ res_hash = JSON.parse(response.body)
1168
+ got = res_hash.is_a?(Array) ? res_hash[0] : res_hash["error"]
1169
+ expect(got).to include(exp)
1170
+ end
1171
+ end
1172
+ end
1173
+ end
1174
+
1036
1175
  context "error handling" do
1037
1176
  it 'returns bad attrs if attrs is not a string' do
1038
1177
  get :evaluate, format: :json, attrs: 0
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: 1.0.42
4
+ version: 1.0.43
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: 2017-10-06 00:00:00.000000000 Z
17
+ date: 2017-10-09 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: pg
@@ -499,6 +499,7 @@ files:
499
499
  - lib/marty/railtie.rb
500
500
  - lib/marty/relation.rb
501
501
  - lib/marty/rpc_call.rb
502
+ - lib/marty/schema_helper.rb
502
503
  - lib/marty/util.rb
503
504
  - lib/marty/version.rb
504
505
  - lib/marty/xl.rb