skn_utils 5.6.0 → 5.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2822f2d8bb83e07b5b099fe277285948dc0e687f
4
- data.tar.gz: 28ae0ca8c94fbc7998ce696d3424345976588ff8
3
+ metadata.gz: '01339ef95f65037a1a9951185b69a8ee2fb9160c'
4
+ data.tar.gz: fd2bd2b6b3ae66f17b268f6f23abd2d1a8c0e69b
5
5
  SHA512:
6
- metadata.gz: 951ff479251217472626d4e8c4dca4bf8e40d59be6606ecefc7ee21b9eb5150f2ff080a9edb8e02b003d2d5cc59cca194cd63a57fc8b5c19dd36a6f4fe334671
7
- data.tar.gz: a7919693b23911d56a4c3411e5f8c89e62142921a507ecae61357d49e8f7a4eda5e1df65ecf0abf1516f4d3c47fead9820568d1fb2aeaf95972c83f3cfa58f36
6
+ metadata.gz: cb6089054a1e97e7e21d03df41c6622e253487fee45e9799217c8cff211dcb8ca63c39776e15c89876edd88e22a9a22c099a133328bb5786801a0d53ce682924
7
+ data.tar.gz: 288b6c71971afd3f0b84b5524d0c96ceec28b7db93a8183ea6c9e31e0a00a974b0eb11f8acbcda03f7b3d0b5160de6e244ec78b7fca13d43f75a63951765e72c
data/README.md CHANGED
@@ -8,6 +8,7 @@ dependencies, to augment the development of Ruby applications. Examples of thes
8
8
  utilities in action can be found in my related projects `SknServices`, `SknWebApp`,
9
9
  and `SknBase`.
10
10
 
11
+ * Most classes are standalone modules, or cleary documented, and can be copy/pasted into your project.
11
12
  * The exchange or handoff of values between objects is addressed via the `NestedResults`
12
13
  class which implements dot-notation and nesting over a concurrent hash: A ruby Hash can
13
14
  use any valid ruby object as a key or value.
@@ -31,7 +32,8 @@ classname, symbol, or string as needed
31
32
  * `ConcurrentJobs` is a feature implemented to allow concurrent/multi-threaded execution of jobs. The included
32
33
  companion classes focus on HTTP GET,PUT,POST, and DELETE jobs as an example of how to use the `ConcurrentJobs` feature.
33
34
 
34
- All classes and modules have RSpec test coverage (90+) of their originally intended use-cases.
35
+ All classes and modules have RSpec test coverage (90+) of their originally intended
36
+ use-cases.
35
37
 
36
38
 
37
39
  ### Available Classes
@@ -65,8 +67,19 @@ All classes and modules have RSpec test coverage (90+) of their originally inten
65
67
  * SknUtils.as_human_size()
66
68
  * SknUtils.duration(start_time=nil)
67
69
 
70
+ ### Available RSpec Helpers
71
+ * spec/support/xml_matchers.rb
72
+ * expect(bundle).to have_xpath('//witnesses/witness/role')
73
+ * expect(bundle).to have_nodes('//witnesses/witness/role', 3)
74
+ * expect(bundle).to match_xpath('//lossInformation/date', "2020-01-28")
75
+
68
76
 
69
77
  ## History
78
+ 2/3/2030 V5.7.0
79
+ Added
80
+ * RSpec XML_Matchers to spec/support folders
81
+ * Update ConcurrentJobs JobCommands to support HTTP Headers
82
+
70
83
  2/24/2019 V5.5.0
71
84
  Added
72
85
  * ConcurrentJobs feature set
@@ -15,6 +15,8 @@ module SknUtils
15
15
 
16
16
  def call
17
17
  @blk.call
18
+ rescue => ex
19
+ SknFailure.(ex.class.name, { cause: ex.message, backtrace: ex.backtrace[0..8]})
18
20
  end
19
21
  end
20
22
 
@@ -25,6 +27,8 @@ module SknUtils
25
27
 
26
28
  def call
27
29
  @blk.value
30
+ rescue => ex
31
+ SknFailure.(ex.class.name, { cause: ex.message, backtrace: ex.backtrace[0..8]})
28
32
  end
29
33
  end
30
34
 
@@ -50,7 +54,7 @@ module SknUtils
50
54
  def self.call(command, callable)
51
55
  callable.call(command)
52
56
  rescue => ex
53
- SknFailure.(ex.class.name, "#{ex.message}; #{ex.backtrace[0]}")
57
+ SknFailure.(ex.class.name, { cause: ex.message, backtrace: ex.backtrace[0..8]})
54
58
  end
55
59
  end
56
60
 
@@ -85,7 +89,12 @@ module SknUtils
85
89
  def render_jobs
86
90
  stime = SknUtils.duration
87
91
  merged = @workers.each_with_object([]) do |worker, acc|
88
- acc.push( worker.call )
92
+ begin
93
+ res = worker.call
94
+ acc.push( res.nil? ? SknFailure.("Unknown", {cause: "Nil Return Value to render Jobs", backtrace: []}) : res )
95
+ rescue => ex
96
+ acc.push SknFailure.(ex.class.name, { cause: ex.message, backtrace: ex.backtrace[0..8]})
97
+ end
89
98
  end
90
99
  @elapsed_time_string = SknUtils.duration(stime)
91
100
  Result.new(merged)
@@ -59,6 +59,10 @@ module SknUtils
59
59
  # - env = string value from RACK_ENV
60
60
  # - registry = SknRegistry instance
61
61
  # - logger = Assigned Logger instance
62
+ # - romDB = var for Rom-DB if used or Any Platform Database
63
+ # - metadata = platform metadata container
64
+ # - userdata = user area
65
+ # - metrics = platform metrics container
62
66
  # #with(*user_attrs, enable_root: true|false) - defaults to enable of Main Class Attrs
63
67
  # ##
64
68
  # User-Defined Attrs
@@ -131,6 +135,38 @@ module SknUtils
131
135
  def logger=(obj)
132
136
  @__logger = obj
133
137
  end
138
+
139
+ # Any Platform Database
140
+ def romDB
141
+ @__db ||= nil
142
+ end
143
+ def romDB(obj)
144
+ @__db = obj
145
+ end
146
+
147
+ # Maybe Platform Metadata
148
+ def metadata
149
+ @__metadata ||= nil
150
+ end
151
+ def metadata=(obj)
152
+ @__metadata = obj
153
+ end
154
+
155
+ # Userdata container for any use
156
+ def userdata
157
+ @__userdata ||= nil
158
+ end
159
+ def userdata=(obj)
160
+ @__userdata = obj
161
+ end
162
+
163
+ # Metrics container for any use
164
+ def metrics
165
+ @__metrics ||= nil
166
+ end
167
+ def metrics=(obj)
168
+ @__metrics = obj
169
+ end
134
170
  end
135
171
  end
136
172
 
@@ -7,7 +7,7 @@ module SknUtils
7
7
  # #################################################
8
8
  #
9
9
  class CommandJSONPost
10
- def self.call(options) # {full_url:,username:,userpass:,payload:}
10
+ def self.call(options) # {full_url:,username:,userpass:,payload:,headers:}
11
11
  new(options)
12
12
  end
13
13
 
@@ -20,7 +20,7 @@ module SknUtils
20
20
  end
21
21
 
22
22
  def request
23
- req = Net::HTTP::Post.new(uri.path) # Generate HTTPRequest object
23
+ req = @_headers.nil? ? Net::HTTP::Post.new(uri.path) : Net::HTTP::Post.new(uri.path, @_headers) # Generate HTTPRequest object
24
24
  req.basic_auth(@_username, @_userpass) if credentials?
25
25
  req.content_type = 'application/json'
26
26
  req.body = formatted_data
@@ -32,6 +32,7 @@ module SknUtils
32
32
  def initialize(opts={})
33
33
  @_username = opts[:username]
34
34
  @_userpass = opts[:userpass]
35
+ @_headers = opts[:headers]
35
36
  @_uri = URI.parse( opts[:full_url])
36
37
  @_data = opts[:payload]
37
38
  end
@@ -49,7 +50,7 @@ module SknUtils
49
50
  # #################################################
50
51
  #
51
52
  class CommandFORMPost
52
- def self.call(options) # {full_url:,username:,userpass:,payload:}
53
+ def self.call(options) # {full_url:,username:,userpass:,payload:,headers:}
53
54
  new(options)
54
55
  end
55
56
 
@@ -62,7 +63,7 @@ module SknUtils
62
63
  end
63
64
 
64
65
  def request
65
- req = Net::HTTP::Post.new(uri.path) # Generate HTTPRequest object
66
+ req = @_headers.nil? ? Net::HTTP::Post.new(uri.path) : Net::HTTP::Post.new(uri.path, @_headers) # Generate HTTPRequest object
66
67
  req.basic_auth(@_username, @_userpass) if credentials?
67
68
  req.content_type = 'application/x-www-form-urlencoded'
68
69
  req.set_form_data(formatted_data)
@@ -74,6 +75,7 @@ module SknUtils
74
75
  def initialize(opts={})
75
76
  @_username = opts[:username]
76
77
  @_userpass = opts[:userpass]
78
+ @_headers = opts[:headers]
77
79
  @_uri = URI.parse( opts[:full_url])
78
80
  @_data = opts[:payload]
79
81
  end
@@ -91,7 +93,7 @@ module SknUtils
91
93
  # #################################################
92
94
  #
93
95
  class CommandJSONGet
94
- def self.call(options) # {full_url:,username:,userpass:}
96
+ def self.call(options) # {full_url:,username:,userpass:,headers:}
95
97
  new(options)
96
98
  end
97
99
 
@@ -104,7 +106,7 @@ module SknUtils
104
106
  end
105
107
 
106
108
  def request
107
- req = Net::HTTP::Get.new(uri.request_uri)
109
+ req = @_headers.nil? ? Net::HTTP::Get.new(uri.request_uri) : Net::HTTP::Get.new(uri.request_uri, @_headers) # Generate HTTPRequest object
108
110
  req.basic_auth(@_username, @_userpass) if credentials?
109
111
  req
110
112
  end
@@ -114,6 +116,7 @@ module SknUtils
114
116
  def initialize(opts={})
115
117
  @_username = opts[:username]
116
118
  @_userpass = opts[:userpass]
119
+ @_headers = opts[:headers]
117
120
  @_uri = URI.parse( opts[:full_url])
118
121
  end
119
122
 
@@ -126,7 +129,7 @@ module SknUtils
126
129
  # #################################################
127
130
  #
128
131
  class CommandJSONPut
129
- def self.call(options) # {full_url:,username:,userpass:,payload:}
132
+ def self.call(options) # {full_url:,username:,userpass:,payload:,headers:}
130
133
  new(options)
131
134
  end
132
135
 
@@ -139,7 +142,7 @@ module SknUtils
139
142
  end
140
143
 
141
144
  def request
142
- req = Net::HTTP::Put.new(uri.path) # Generate HTTPRequest object
145
+ req = @_headers.nil? ? Net::HTTP::Put.new(uri.path) : Net::HTTP::Put.new(uri.path, @_headers) # Generate HTTPRequest object
143
146
  req.basic_auth(@_username, @_userpass) if credentials?
144
147
  req.content_type = 'application/json'
145
148
  req.body = formatted_data
@@ -151,6 +154,7 @@ module SknUtils
151
154
  def initialize(opts={})
152
155
  @_username = opts[:username]
153
156
  @_userpass = opts[:userpass]
157
+ @_headers = opts[:headers]
154
158
  @_uri = URI.parse( opts[:full_url])
155
159
  @_data = opts[:payload]
156
160
  end
@@ -181,7 +185,7 @@ module SknUtils
181
185
  end
182
186
 
183
187
  def request
184
- req = Net::HTTP::Delete.new(uri.request_uri)
188
+ req = @_headers.nil? ? Net::HTTP::Delete.new(uri.request_uri) : Net::HTTP::Delete.new(uri.request_uri, @_headers) # Generate HTTPRequest object
185
189
  req.basic_auth(@_username, @_userpass) if credentials?
186
190
  req
187
191
  end
@@ -191,6 +195,7 @@ module SknUtils
191
195
  def initialize(opts={})
192
196
  @_username = opts[:username]
193
197
  @_userpass = opts[:userpass]
198
+ @_headers = opts[:headers]
194
199
  @_uri = URI.parse( opts[:full_url])
195
200
  end
196
201
 
@@ -4,7 +4,7 @@
4
4
  module SknUtils
5
5
  class Version
6
6
  MAJOR = 5
7
- MINOR = 6
7
+ MINOR = 7
8
8
  PATCH = 0
9
9
 
10
10
  def self.to_s
@@ -7,7 +7,7 @@ describe SknUtils::ConcurrentJobs, 'Run Multiple Jobs' do
7
7
 
8
8
  let(:commands) {
9
9
  [
10
- SknUtils::CommandJSONPost.call(full_url: "http://example.com/posts", payload: {one: 1}),
10
+ SknUtils::CommandJSONPost.call(full_url: "http://example.com/posts", payload: {one: 1}, headers: {'my-header'=> "header-value"}),
11
11
  SknUtils::CommandFORMPost.call(full_url: "http://example.com/posts", payload: {one: 1}),
12
12
  SknUtils::CommandJSONGet.call(full_url: "http://example.com/posts/1"),
13
13
  SknUtils::CommandJSONPut.call(full_url: "http://example.com/posts", payload: {one: 1}),
@@ -199,10 +199,12 @@ describe SknUtils::ConcurrentJobs, 'Run Multiple Jobs' do
199
199
  expect(result).to be_a(SknUtils::Result)
200
200
  expect(result.success?).to be false
201
201
  expect(result.values.size).to eq(commands.size)
202
+ expect(result.values.last).to be_a(SknSuccess)
202
203
  expect(result.values[3].value).to eq("NameError")
203
- expect(result.values[3]).to be_a(SknFailure)
204
- expect(result.values[3]).to be_a(SknFailure)
205
- expect(result.values[0]).to be nil
204
+ expect(result.values[2]).to be_a(SknFailure)
205
+ expect(result.values[1]).to be_a(SknFailure)
206
+ expect(result.values[0]).to be_a(SknFailure)
207
+ expect(result.values[0].value).to eq("Unknown")
206
208
  end
207
209
  end
208
210
 
@@ -16,6 +16,7 @@ require 'skn_utils'
16
16
  require 'rspec'
17
17
 
18
18
  require 'webmock/rspec'
19
+ require 'support/xml_matchers'
19
20
 
20
21
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
21
22
  RSpec.configure do |config|
@@ -0,0 +1,121 @@
1
+ # ##
2
+ # File: <spec>/xml_matchers.rb
3
+ #
4
+ # Refs: https://github.com/sparklemotion/nokogiri/wiki/Cheat-sheet
5
+ # https://arjanvandergaag.nl/blog/rspec-matchers.html
6
+ # http://blog.wolfman.com/articles/2008/1/2/xpath-matchers-for-rspec
7
+ # https://semaphoreci.com/community/tutorials/how-to-use-custom-rspec-matchers-to-specify-behaviour
8
+ #
9
+
10
+ # Useage
11
+ # ----------------------------------------------------------------------
12
+ # expect(bundle).to have_xpath('//witnesses/witness/role')
13
+ # expect(bundle).to have_nodes('//witnesses/witness/role', 3)
14
+ # expect(bundle).to match_xpath('//lossInformation/date', "2020-01-28")
15
+
16
+ # check if the xpath exists one or more times
17
+ class HaveXpath
18
+ def initialize(xpath)
19
+ @xpath = xpath
20
+ end
21
+
22
+ def matches?(str)
23
+ @str = str
24
+ xml_document.xpath(@xpath).any?
25
+ end
26
+
27
+ def failure_message
28
+ "Expected xpath #{@xpath.inspect} to match in:\n" + pretty_printed_xml
29
+ end
30
+
31
+ def failure_message_when_negated
32
+ "Expected xpath #{@xpath.inspect} not to match in:\n" + pretty_printed_xml
33
+ end
34
+
35
+ private
36
+
37
+ def pretty_printed_xml
38
+ xml_document.to_xml(indent: 2)
39
+ end
40
+
41
+ def xml_document
42
+ @xml_document ||= Nokogiri::XML(@str)
43
+ end
44
+ end
45
+
46
+ def have_xpath(*xpath)
47
+ HaveXpath.new(*xpath)
48
+ end
49
+
50
+ # check if the xpath has the specified value
51
+ # value is a string and there must be a single result to match its
52
+ # equality against
53
+ class MatchXpath
54
+ def initialize(xpath, val)
55
+ @xpath = xpath
56
+ @val= val
57
+ end
58
+
59
+ def matches?(response)
60
+ @response = response
61
+ doc = response.is_a?(Nokogiri::XML::Document) ? response : Nokogiri::XML(@response)
62
+ ok= true
63
+ doc.xpath(@xpath).each do |e|
64
+ @actual_val= case e
65
+ when Nokogiri::XML::Attr
66
+ e.to_s
67
+ when Nokogiri::XML::Element
68
+ e.text
69
+ else
70
+ e.to_s
71
+ end
72
+ return false unless @val == @actual_val
73
+ end
74
+ return ok
75
+ end
76
+
77
+ def failure_message
78
+ "The xpath #{@xpath} did not have the value '#{@val}' \n It was '#{@actual_val}'"
79
+ end
80
+
81
+ def failure_message_when_negated
82
+ "The xpath #{@xpath} has the value '#{@val}' \n Was expected not to match '#{@actual_val}'"
83
+ end
84
+
85
+ def description
86
+ "match the xpath expression #{@xpath} with #{@val}"
87
+ end
88
+ end
89
+
90
+ def match_xpath(xpath, val)
91
+ MatchXpath.new(xpath, val)
92
+ end
93
+
94
+ # checks if the given xpath occurs num times
95
+ class HaveNodes #:nodoc:
96
+ def initialize(xpath, num)
97
+ @xpath= xpath
98
+ @num = num
99
+ end
100
+
101
+ def matches?(response)
102
+ @response = response
103
+ doc = response.is_a?(Nokogiri::XML::Document) ? response : Nokogiri::XML(@response)
104
+ matches = doc.xpath(@xpath)
105
+ @num_found= matches.size
106
+ @num_found == @num
107
+ end
108
+
109
+ def failure_message
110
+ "Did not find expected number of nodes #{@num} in xpath #{@xpath} \n Found #{@num_found}"
111
+ end
112
+
113
+ def description
114
+ "match the number of nodes #{@num}"
115
+ end
116
+ end
117
+
118
+ def have_nodes(xpath, num)
119
+ HaveNodes.new(xpath, num)
120
+ end
121
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skn_utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.6.0
4
+ version: 5.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Scott Jr
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-02 00:00:00.000000000 Z
11
+ date: 2020-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deep_merge
@@ -242,6 +242,7 @@ files:
242
242
  - spec/lib/skn_utils/wrappers_spec.rb
243
243
  - spec/spec_helper.rb
244
244
  - spec/support/configurables.rb
245
+ - spec/support/xml_matchers.rb
245
246
  homepage: https://github.com/skoona/skn_utils
246
247
  licenses:
247
248
  - MIT
@@ -293,3 +294,4 @@ test_files:
293
294
  - spec/lib/skn_utils/wrappers_spec.rb
294
295
  - spec/spec_helper.rb
295
296
  - spec/support/configurables.rb
297
+ - spec/support/xml_matchers.rb