packspec 0.1.4 → 0.1.5
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/lib/cli.rb +138 -50
- data/packspec.gemspec +1 -1
- 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: 0531ed015b0fcc81e3aa62bac12011f33b69ce9b
|
4
|
+
data.tar.gz: cc8de8f4ac4d27cc08b2fa006bce54a6400c918d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e924e041feab6d6b9c1befc1db57246e3597509eebbf8ee09fe3af06a77c461ad2cf05ef8d605a50b7a076e5339cd47f0bc45288ff01129fb1c3c82540bbdc9f
|
7
|
+
data.tar.gz: a41c8cfd6b471370cba5fe506898ddfdc3fb98c9d8d25243b559be03e023d3fcc8fa6af871d2e647e2d1b6e430b8757ff57fb7f22741a60b47d9f2644493f441
|
data/lib/cli.rb
CHANGED
@@ -13,22 +13,59 @@ def parse_specs(path)
|
|
13
13
|
|
14
14
|
# Specs
|
15
15
|
specmap = {}
|
16
|
-
for
|
17
|
-
spec = parse_spec(File.read(
|
16
|
+
for filepath in Dir.glob("#{path}/**/*.yml")
|
17
|
+
spec = parse_spec(File.read(filepath))
|
18
18
|
if !spec
|
19
19
|
next
|
20
20
|
elsif !specmap.include?(spec['package'])
|
21
21
|
specmap[spec['package']] = spec
|
22
22
|
else
|
23
23
|
specmap[spec['package']]['features'].merge!(spec['features'])
|
24
|
+
specmap[spec['package']]['scope'].merge!(spec['scope'])
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
27
28
|
# Hooks
|
28
|
-
|
29
|
+
hookmap = {}
|
30
|
+
for filepath in Dir.glob("#{path}/**/packspec.rb")
|
31
|
+
begin
|
32
|
+
eval(File.read(filepath))
|
33
|
+
hook_scope = Packspec::User.new()
|
34
|
+
for name in hook_scope.public_methods
|
35
|
+
# TODO: filter ruby builtin methods
|
36
|
+
hookmap["$#{name}"] = hook_scope.public_method(name)
|
37
|
+
end
|
38
|
+
rescue Exception
|
39
|
+
end
|
40
|
+
end
|
29
41
|
|
30
42
|
# Result
|
31
43
|
specs = Array(specmap.sort.to_h.each_value)
|
44
|
+
for spec in specs
|
45
|
+
skip = false
|
46
|
+
spec['ready'] = !spec['scope'].empty?
|
47
|
+
spec['stats'] = {'features' => 0, 'comments' => 0, 'skipped' => 0, 'tests' => 0}
|
48
|
+
for feature, index in spec['features'].dup.each_with_index
|
49
|
+
if feature['assign'] == 'PACKAGE'
|
50
|
+
if index > 0
|
51
|
+
spec['features'].delete_at(index)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
spec['stats']['features'] += 1
|
55
|
+
if feature['comment']
|
56
|
+
skip = feature['skip']
|
57
|
+
spec['stats']['comments'] += 1
|
58
|
+
end
|
59
|
+
feature['skip'] = skip || feature['skip']
|
60
|
+
if !feature['comment']
|
61
|
+
spec['stats']['tests'] += 1
|
62
|
+
if feature['skip']
|
63
|
+
spec['stats']['skipped'] += 1
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
spec['scope'].merge!(hookmap)
|
68
|
+
end
|
32
69
|
|
33
70
|
return specs
|
34
71
|
|
@@ -44,6 +81,15 @@ def parse_spec(spec)
|
|
44
81
|
package = feature['result']
|
45
82
|
assert_equal(feature['assign'], 'PACKAGE')
|
46
83
|
assert_equal(feature['skip'], nil)
|
84
|
+
if package.is_a?(String)
|
85
|
+
package = {'default' => [package]}
|
86
|
+
elsif package.is_a?(Array)
|
87
|
+
package = {'default' => package}
|
88
|
+
elsif package.is_a?(Hash)
|
89
|
+
for key, value in package.each_pair()
|
90
|
+
package[key] = value.is_a?(Array) ? value : [value]
|
91
|
+
end
|
92
|
+
end
|
47
93
|
rescue Exception
|
48
94
|
return nil
|
49
95
|
end
|
@@ -57,19 +103,28 @@ def parse_spec(spec)
|
|
57
103
|
|
58
104
|
# Scope
|
59
105
|
scope = {}
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
106
|
+
packages = []
|
107
|
+
attributes = {}
|
108
|
+
for namespace, module_names in package.each_pair
|
109
|
+
packages.push(*module_names)
|
110
|
+
namespace_scope = scope
|
111
|
+
if namespace != 'default'
|
112
|
+
if !scope.key?(namespace) then scope[namespace] = {} end
|
113
|
+
namespace_scope = scope[namespace]
|
114
|
+
end
|
115
|
+
for module_name in module_names
|
116
|
+
attributes = get_module_attributes(module_name)
|
117
|
+
namespace_scope.merge!(attributes)
|
118
|
+
if !attributes.empty?
|
119
|
+
break
|
70
120
|
end
|
71
121
|
end
|
122
|
+
if attributes.empty?
|
123
|
+
scope = {}
|
124
|
+
break
|
125
|
+
end
|
72
126
|
end
|
127
|
+
package = packages.sort().join('/')
|
73
128
|
|
74
129
|
return {
|
75
130
|
'package' => package,
|
@@ -81,8 +136,16 @@ end
|
|
81
136
|
|
82
137
|
|
83
138
|
def parse_feature(feature)
|
139
|
+
|
140
|
+
# General
|
84
141
|
if feature.is_a?(String)
|
85
|
-
|
142
|
+
match = /^(?:(.*):)?(\w.*)$/.match(feature)
|
143
|
+
skip, comment = match[1], match[2]
|
144
|
+
if !!skip
|
145
|
+
filters = skip.split(':')
|
146
|
+
skip = (filters[0] == 'not') == (filters.include?('rb'))
|
147
|
+
end
|
148
|
+
return {'assign' => nil, 'comment' => comment, 'skip' => skip}
|
86
149
|
end
|
87
150
|
left, right = Array(feature.each_pair)[0]
|
88
151
|
|
@@ -94,7 +157,7 @@ def parse_feature(feature)
|
|
94
157
|
filters = skip.split(':')
|
95
158
|
skip = (filters[0] == 'not') == (filters.include?('rb'))
|
96
159
|
end
|
97
|
-
if !assign
|
160
|
+
if !assign && !property
|
98
161
|
raise Exception.new('Non-valid feature')
|
99
162
|
end
|
100
163
|
if !!property
|
@@ -143,7 +206,7 @@ def parse_feature(feature)
|
|
143
206
|
text = "#{text}(#{items.join(', ')})"
|
144
207
|
end
|
145
208
|
if !!result && !assign
|
146
|
-
text = "#{text} == #{JSON.generate(result)}"
|
209
|
+
text = "#{text} == #{result == 'ERROR' ? result : JSON.generate(result)}"
|
147
210
|
end
|
148
211
|
text = text.gsub(/{"([^{}]*?)": null}/, '\1')
|
149
212
|
|
@@ -176,7 +239,6 @@ end
|
|
176
239
|
|
177
240
|
def test_spec(spec)
|
178
241
|
passed = 0
|
179
|
-
amount = spec['features'].length
|
180
242
|
message = Emoji.find_by_alias('heavy_minus_sign').raw * 3 + "\n\n"
|
181
243
|
puts(message)
|
182
244
|
for feature in spec['features']
|
@@ -185,14 +247,14 @@ def test_spec(spec)
|
|
185
247
|
passed += 1
|
186
248
|
end
|
187
249
|
end
|
188
|
-
success = (passed ==
|
250
|
+
success = (passed == spec['stats']['features'])
|
189
251
|
color = 'green'
|
190
252
|
message = ("\n " + Emoji.find_by_alias('heavy_check_mark').raw + ' ').green.bold
|
191
253
|
if !success
|
192
254
|
color = 'red'
|
193
255
|
message = ("\n " + Emoji.find_by_alias('x').raw + ' ').red.bold
|
194
256
|
end
|
195
|
-
message += "#{spec['package']}: #{passed}/#{
|
257
|
+
message += "#{spec['package']}: #{passed - spec['stats']['comments'] - spec['stats']['skipped']}/#{spec['stats']['tests'] - spec['stats']['skipped']}\n".colorize(color).bold
|
196
258
|
puts(message)
|
197
259
|
return success
|
198
260
|
end
|
@@ -215,8 +277,16 @@ def test_feature(feature, scope)
|
|
215
277
|
return true
|
216
278
|
end
|
217
279
|
|
280
|
+
# Dereference
|
281
|
+
# TODO: deepcopy feature
|
282
|
+
if !!feature['call']
|
283
|
+
feature['args'] = dereference_value(feature['args'], scope)
|
284
|
+
feature['kwargs'] = dereference_value(feature['kwargs'], scope)
|
285
|
+
end
|
286
|
+
feature['result'] = dereference_value(feature['result'], scope)
|
287
|
+
|
218
288
|
# Execute
|
219
|
-
|
289
|
+
exception = nil
|
220
290
|
result = feature['result']
|
221
291
|
if !!feature['property']
|
222
292
|
begin
|
@@ -225,16 +295,23 @@ def test_feature(feature, scope)
|
|
225
295
|
property = get_property(property, name)
|
226
296
|
end
|
227
297
|
if !!feature['call']
|
228
|
-
|
298
|
+
args = feature['args'].dup
|
299
|
+
if !feature['kwargs'].empty?
|
300
|
+
args.push(Hash[feature['kwargs'].map{|k, v| [k.to_sym, v]}])
|
301
|
+
end
|
229
302
|
if property.respond_to?('new')
|
230
|
-
result = property.new(*
|
303
|
+
result = property.new(*args)
|
231
304
|
else
|
232
|
-
result = property.call(*
|
305
|
+
result = property.call(*args)
|
233
306
|
end
|
234
307
|
else
|
235
308
|
result = property
|
309
|
+
if result.is_a?(Method)
|
310
|
+
result = result.call()
|
311
|
+
end
|
236
312
|
end
|
237
|
-
rescue Exception
|
313
|
+
rescue Exception => exc
|
314
|
+
exception = exc
|
238
315
|
result = 'ERROR'
|
239
316
|
end
|
240
317
|
end
|
@@ -251,7 +328,6 @@ def test_feature(feature, scope)
|
|
251
328
|
end
|
252
329
|
|
253
330
|
# Compare
|
254
|
-
# TODO: isoformat value
|
255
331
|
if feature['result'] != nil
|
256
332
|
success = result == feature['result']
|
257
333
|
else
|
@@ -268,7 +344,12 @@ def test_feature(feature, scope)
|
|
268
344
|
result_text = result.to_s
|
269
345
|
end
|
270
346
|
message = " #{Emoji.find_by_alias('x').raw} ".red
|
271
|
-
message += "#{feature['text']}
|
347
|
+
message += "#{feature['text']}\n"
|
348
|
+
if exception
|
349
|
+
message += "Exception: #{exception}".red.bold
|
350
|
+
else
|
351
|
+
message += "Assertion: #{result_text} != #{JSON.generate(feature['result'])}".red.bold
|
352
|
+
end
|
272
353
|
puts(message)
|
273
354
|
end
|
274
355
|
|
@@ -277,20 +358,31 @@ def test_feature(feature, scope)
|
|
277
358
|
end
|
278
359
|
|
279
360
|
|
280
|
-
def
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
361
|
+
def get_module_attributes(module_name)
|
362
|
+
attributes = {}
|
363
|
+
begin
|
364
|
+
require(module_name)
|
365
|
+
rescue Exception
|
366
|
+
return {}
|
367
|
+
end
|
368
|
+
for item in ObjectSpace.each_object
|
369
|
+
if module_name == String(item).downcase
|
370
|
+
begin
|
371
|
+
module_scope = Kernel.const_get(item)
|
372
|
+
rescue Exception
|
373
|
+
next
|
374
|
+
end
|
375
|
+
for name in module_scope.constants
|
376
|
+
attributes[String(name)] = module_scope.const_get(name)
|
377
|
+
end
|
285
378
|
end
|
286
|
-
|
287
|
-
|
379
|
+
end
|
380
|
+
return attributes
|
288
381
|
end
|
289
382
|
|
290
383
|
|
291
384
|
def dereference_value(value, scope)
|
292
|
-
|
293
|
-
if value.is_a?(Hash) && value.lengh == 1 && Array(value.each_value)[0] == nil
|
385
|
+
if value.is_a?(Hash) && value.length == 1 && Array(value.each_value)[0] == nil
|
294
386
|
result = scope
|
295
387
|
for name in Array(value.each_key)[0].split('.')
|
296
388
|
result = get_property(result, name)
|
@@ -309,30 +401,26 @@ def dereference_value(value, scope)
|
|
309
401
|
end
|
310
402
|
|
311
403
|
|
312
|
-
def isoformat_value(value)
|
313
|
-
# TODO: implement
|
314
|
-
return value
|
315
|
-
end
|
316
|
-
|
317
|
-
|
318
404
|
def get_property(owner, name)
|
319
|
-
|
320
|
-
|
321
|
-
if owner.is_a?(Hash)
|
322
|
-
result = owner[name]
|
405
|
+
if owner.is_a?(Method)
|
406
|
+
owner = owner.call()
|
323
407
|
end
|
324
|
-
if
|
325
|
-
|
408
|
+
if owner.class == Hash
|
409
|
+
return owner[name]
|
410
|
+
elsif owner.class == Array
|
411
|
+
return owner[name.to_i]
|
326
412
|
end
|
327
|
-
return
|
413
|
+
return owner.method(name)
|
328
414
|
end
|
329
415
|
|
330
416
|
|
331
417
|
def set_property(owner, name, value)
|
332
|
-
|
333
|
-
if owner.is_a?(Hash)
|
418
|
+
if owner.class == Hash
|
334
419
|
owner[name] = value
|
335
420
|
return
|
421
|
+
elsif owner.class == Array
|
422
|
+
owner[name.to_i] = value
|
423
|
+
return
|
336
424
|
end
|
337
425
|
return owner.const_set(name, value)
|
338
426
|
end
|
data/packspec.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: packspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- |
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-06-
|
12
|
+
date: 2017-06-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|