sus 0.17.2 → 0.18.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
  SHA256:
3
- metadata.gz: b86dafae68ebeadfd3e2b7aa2f94e955a05f9b65bf3fcaf1dfdd65a8822a0722
4
- data.tar.gz: 7714b5ca6dbac3f8a68f386a369c152c2086e1b9d907040c3163f4f7df8b2670
3
+ metadata.gz: 77921dd1b6bbde6e2a47db7f4a2f0c421c3f517eb04b7d4273538a5891f51ad2
4
+ data.tar.gz: 204c68cd216e6ddb74e469bbdc01ce042f4d4d0d9fab9b3b897d2ebbcce7fec6
5
5
  SHA512:
6
- metadata.gz: 1d35bd5af4e176105da748d46df24d101e828bd579f6daa32f1907909daa8401abdd73d0bb8f63195ac2c5c787db8af56ec1d7c7131947e0553a7005db0127c6
7
- data.tar.gz: 510e795dfe14659e2dc2ab166a546c1547b26d2c1476595260ee67124c5d01e162223196057e22635317cac382d399e36a46f8487b6bdc98baa29867b4606966
6
+ metadata.gz: a9e50aa174880249cd96f519242d59396315475972432b60dd41e6b2c35d5025a7dfb7824fc538a1bee5199c2d93686c0673e4d72de7126f512a1c237041c8ad
7
+ data.tar.gz: 8580ec8e113b18c6e61f14c3f31804d76663cfa6288e965fb44d4a06238283461b856d593abb83bee4d270d32da865c609fc253a840d6f58d3ac49a8a7d9cc66
checksums.yaml.gz.sig CHANGED
Binary file
data/bin/sus-host ADDED
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'json'
4
+
5
+ require_relative '../lib/sus/config'
6
+ config = Sus::Config.load
7
+
8
+ require_relative '../lib/sus'
9
+
10
+ verbose = false
11
+ guard = Thread::Mutex.new
12
+
13
+ require 'etc'
14
+ count = Etc.nprocessors
15
+
16
+ $stdout.sync = true
17
+
18
+ input = $stdin.dup
19
+ $stdin.reopen(File::NULL)
20
+ output = $stdout.dup
21
+ $stdout.reopen($stderr)
22
+
23
+ while line = input.gets
24
+ message = JSON.parse(line)
25
+
26
+ if tests = message['run']
27
+ jobs = Thread::Queue.new
28
+ results = Thread::Queue.new
29
+
30
+ top = Sus::Assertions.new(measure: true)
31
+ config.before_tests(top)
32
+
33
+ aggregate = Thread.new do
34
+ while result = results.pop
35
+ top.add(result)
36
+ end
37
+ end
38
+
39
+ loader = Thread.new do
40
+ registry = config.load_registry(tests)
41
+
42
+ registry.each do |child|
43
+ jobs << child
44
+ end
45
+
46
+ jobs.close
47
+ end
48
+
49
+ workers = count.times.map do |index|
50
+ Thread.new do
51
+ while job = jobs.pop
52
+ guard.synchronize do
53
+ output.puts JSON.generate({started: job.identity})
54
+ end
55
+
56
+ assertions = Sus::Assertions.new(measure: true)
57
+ job.call(assertions)
58
+
59
+ results.push(assertions)
60
+
61
+ guard.synchronize do
62
+ if assertions.passed?
63
+ output.puts JSON.generate({passed: job.identity, message: assertions.output.string, duration: assertions.clock.ms})
64
+ else
65
+ output.puts JSON.generate({failed: job.identity, message: assertions.output.string, duration: assertions.clock.ms})
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ loader.join
73
+ workers.each(&:join)
74
+ results.close
75
+
76
+ aggregate.join
77
+ config.after_tests(top)
78
+
79
+ workers.each(&:join)
80
+
81
+ if config.respond_to?(:covered)
82
+ if covered = config.covered and covered.record?
83
+ covered.policy.each do |coverage|
84
+ output.puts JSON.generate({coverage: coverage.path, counts: coverage.counts})
85
+ end
86
+ end
87
+ end
88
+
89
+ output.puts JSON.generate({finished: true, message: top.output.string, duration: top.clock.ms})
90
+ else
91
+ $stderr.puts "Unknown message: #{message}"
92
+ end
93
+ end
data/bin/sus-tree ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'json'
4
+
5
+ require_relative '../lib/sus/config'
6
+ config = Sus::Config.load
7
+
8
+ require_relative '../lib/sus'
9
+
10
+ verbose = false
11
+ registry = config.registry
12
+ puts Sus::Tree.new(registry.base).to_json
@@ -138,20 +138,32 @@ module Sus
138
138
  @errored.any?
139
139
  end
140
140
 
141
+ class Assert
142
+ def initialize(location, message)
143
+ @location = location
144
+ @message = message
145
+ end
146
+
147
+ attr :location
148
+ attr :message
149
+ end
150
+
141
151
  def assert(condition, message = nil)
142
152
  @count += 1
153
+ backtrace = Output::Backtrace.first(@identity)
143
154
 
144
155
  if condition
145
- @passed << self
156
+ @passed << Assert.new(message, backtrace)
146
157
 
147
158
  if !@orientation || @verbose
148
- @output.puts(:indent, *pass_prefix, message || "assertion", Output::Backtrace.first(@identity))
159
+ @output.puts(:indent, *pass_prefix, message || "assertion", backtrace)
149
160
  end
150
161
  else
151
- @failed << self
162
+
163
+ @failed << Assert.new(message, backtrace)
152
164
 
153
165
  if @orientation || @verbose
154
- @output.puts(:indent, *fail_prefix, message || "assertion", Output::Backtrace.first(@identity))
166
+ @output.puts(:indent, *fail_prefix, message || "assertion", backtrace)
155
167
  end
156
168
  end
157
169
  end
data/lib/sus/base.rb CHANGED
@@ -39,10 +39,11 @@ module Sus
39
39
  end
40
40
  end
41
41
 
42
- def self.base(description = nil)
42
+ def self.base(description = nil, root: nil)
43
43
  base = Class.new(Base)
44
44
 
45
45
  base.extend(Context)
46
+ base.identity = Identity.new(root) if root
46
47
  base.description = description
47
48
 
48
49
  return base
data/lib/sus/clock.rb CHANGED
@@ -33,6 +33,10 @@ module Sus
33
33
  duration
34
34
  end
35
35
 
36
+ def ms
37
+ duration * 1000.0
38
+ end
39
+
36
40
  def to_s
37
41
  duration = self.duration
38
42
 
@@ -45,6 +49,10 @@ module Sus
45
49
  end
46
50
  end
47
51
 
52
+ def reset!(duration = 0.0)
53
+ @duration = duration
54
+ end
55
+
48
56
  def start!
49
57
  @start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
50
58
  end
data/lib/sus/config.rb CHANGED
@@ -82,12 +82,12 @@ module Sus
82
82
  @registry ||= self.load_registry
83
83
  end
84
84
 
85
- def load_registry
86
- registry = Sus::Registry.new
85
+ def load_registry(paths = @paths)
86
+ registry = Sus::Registry.new(root: @root)
87
87
 
88
- if @paths&.any?
88
+ if paths&.any?
89
89
  registry = Sus::Filter.new(registry)
90
- @paths.each do |path|
90
+ paths.each do |path|
91
91
  registry.load(path)
92
92
  end
93
93
  else
@@ -99,42 +99,41 @@ module Sus
99
99
  return registry
100
100
  end
101
101
 
102
- def before_tests(assertions)
102
+ def before_tests(assertions, output: self.output)
103
+ @clock.reset!
103
104
  @clock.start!
104
105
  end
105
106
 
106
- def after_tests(assertions)
107
+ def after_tests(assertions, output: self.output)
107
108
  @clock.stop!
108
109
 
109
- self.print_summary(assertions)
110
+ self.print_summary(output, assertions)
110
111
  end
111
112
 
112
113
  protected
113
114
 
114
- def print_summary(assertions)
115
- output = self.output
116
-
115
+ def print_summary(output, assertions)
117
116
  assertions.print(output)
118
117
  output.puts
119
118
 
120
- print_finished_statistics(assertions)
119
+ print_finished_statistics(output, assertions)
121
120
 
122
121
  if !partial? and assertions.passed?
123
- print_test_feedback(assertions)
122
+ print_test_feedback(output, assertions)
124
123
  end
125
124
 
126
- print_slow_tests(assertions)
127
- print_failed_assertions(assertions)
125
+ print_slow_tests(output, assertions)
126
+ print_failed_assertions(output, assertions)
128
127
  end
129
128
 
130
- def print_finished_statistics(assertions)
129
+ def print_finished_statistics(output, assertions)
131
130
  duration = @clock.duration
132
131
  rate = assertions.count / duration
133
132
 
134
133
  output.puts "🏁 Finished in ", @clock, "; #{rate.round(3)} assertions per second."
135
134
  end
136
135
 
137
- def print_test_feedback(assertions)
136
+ def print_test_feedback(output, assertions)
138
137
  duration = @clock.duration
139
138
  rate = assertions.count / duration
140
139
 
@@ -179,7 +178,7 @@ module Sus
179
178
  end
180
179
  end
181
180
 
182
- def print_slow_tests(assertions, threshold = 0.1)
181
+ def print_slow_tests(output, assertions, threshold = 0.1)
183
182
  slowest_tests = assertions.passed.select{|test| test.clock > threshold}.sort_by(&:clock).reverse!
184
183
 
185
184
  if slowest_tests.empty?
@@ -193,7 +192,7 @@ module Sus
193
192
  end
194
193
  end
195
194
 
196
- def print_assertions(title, assertions)
195
+ def print_assertions(output, title, assertions)
197
196
  if assertions.any?
198
197
  output.puts
199
198
  output.puts title
@@ -206,9 +205,9 @@ module Sus
206
205
  end
207
206
  end
208
207
 
209
- def print_failed_assertions(assertions)
210
- print_assertions("🤔 Failed assertions:", assertions.failed)
211
- print_assertions("🔥 Errored assertions:", assertions.errored)
208
+ def print_failed_assertions(output, assertions)
209
+ print_assertions(output, "🤔 Failed assertions:", assertions.failed)
210
+ print_assertions(output, "🔥 Errored assertions:", assertions.errored)
212
211
  end
213
212
  end
214
213
  end
data/lib/sus/expect.rb CHANGED
@@ -10,9 +10,10 @@ module Sus
10
10
  @subject = subject
11
11
  @inverted = inverted
12
12
  end
13
-
13
+
14
14
  attr :subject
15
15
  attr :inverted
16
+ attr :assertions
16
17
 
17
18
  def not
18
19
  self.dup.tap do |expect|
data/lib/sus/file.rb CHANGED
@@ -50,6 +50,12 @@ module Sus
50
50
  true
51
51
  end
52
52
 
53
+ EMPTY = Array.new.freeze
54
+
55
+ def children
56
+ EMPTY
57
+ end
58
+
53
59
  def print(output)
54
60
  output.write("file ", :path, @identity)
55
61
  end
@@ -30,14 +30,12 @@ module Sus
30
30
  self.class.new(self)
31
31
  end
32
32
 
33
- attr :output
34
-
35
33
  def each(&block)
36
34
  @chunks.each(&block)
37
35
  end
38
36
 
39
37
  def append(buffer)
40
- @chunks.concat(buffer.output)
38
+ @chunks.concat(buffer.chunks)
41
39
  @tee&.append(buffer)
42
40
  end
43
41
 
data/lib/sus/registry.rb CHANGED
@@ -23,16 +23,21 @@ module Sus
23
23
  DIRECTORY_GLOB = "**/*.rb"
24
24
 
25
25
  # Create a top level scope with self as the instance:
26
- def initialize(base = Sus.base(self))
27
- @base = base
26
+ def initialize(**options)
27
+ @base = Sus.base(self, **options)
28
+ @loaded = {}
28
29
  end
29
-
30
+
30
31
  attr :base
31
32
 
32
33
  def print(output)
33
34
  output.write("Test Registry")
34
35
  end
35
36
 
37
+ def to_s
38
+ @base.identity.to_s
39
+ end
40
+
36
41
  def load(path)
37
42
  if ::File.directory?(path)
38
43
  load_directory(path)
@@ -42,7 +47,7 @@ module Sus
42
47
  end
43
48
 
44
49
  private def load_file(path)
45
- @base.file(path)
50
+ @loaded[path] ||= @base.file(path)
46
51
  end
47
52
 
48
53
  private def load_directory(path)
data/lib/sus/tree.rb ADDED
@@ -0,0 +1,27 @@
1
+ module Sus
2
+ class Tree
3
+ def initialize(context)
4
+ @context = context
5
+ end
6
+
7
+ def traverse(current = @context, &block)
8
+ node = {}
9
+
10
+ node[:self] = yield(current)
11
+
12
+ if children = current.children # and children.any?
13
+ node[:children] = children.values.map do |context|
14
+ self.traverse(context, &block)
15
+ end
16
+ end
17
+
18
+ return node
19
+ end
20
+
21
+ def to_json(options = nil)
22
+ traverse do |context|
23
+ [context.identity, context.description, context.leaf?]
24
+ end.to_json(options)
25
+ end
26
+ end
27
+ end
data/lib/sus/version.rb CHANGED
@@ -4,5 +4,5 @@
4
4
  # Copyright, 2021-2022, by Samuel Williams.
5
5
 
6
6
  module Sus
7
- VERSION = "0.17.2"
7
+ VERSION = "0.18.0"
8
8
  end
data/lib/sus.rb CHANGED
@@ -7,6 +7,7 @@ require_relative 'sus/version'
7
7
  require_relative 'sus/config'
8
8
  require_relative 'sus/registry'
9
9
  require_relative 'sus/assertions'
10
+ require_relative 'sus/tree'
10
11
 
11
12
  require_relative 'sus/expect'
12
13
  require_relative 'sus/be'
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.2
4
+ version: 0.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -38,7 +38,7 @@ cert_chain:
38
38
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
39
39
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
40
40
  -----END CERTIFICATE-----
41
- date: 2023-02-18 00:00:00.000000000 Z
41
+ date: 2023-02-19 00:00:00.000000000 Z
42
42
  dependencies:
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: bake-test
@@ -87,11 +87,15 @@ email:
87
87
  executables:
88
88
  - sus
89
89
  - sus-parallel
90
+ - sus-tree
91
+ - sus-host
90
92
  extensions: []
91
93
  extra_rdoc_files: []
92
94
  files:
93
95
  - bin/sus
96
+ - bin/sus-host
94
97
  - bin/sus-parallel
98
+ - bin/sus-tree
95
99
  - lib/sus.rb
96
100
  - lib/sus/assertions.rb
97
101
  - lib/sus/base.rb
@@ -131,6 +135,7 @@ files:
131
135
  - lib/sus/registry.rb
132
136
  - lib/sus/respond_to.rb
133
137
  - lib/sus/shared.rb
138
+ - lib/sus/tree.rb
134
139
  - lib/sus/version.rb
135
140
  - lib/sus/with.rb
136
141
  - license.md
metadata.gz.sig CHANGED
Binary file