sus 0.14.0 → 0.15.1

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
  SHA256:
3
- metadata.gz: 1aa2de6186ab05050d85b1125c7244bb6cf25b1250f9973bc067f72a405e9396
4
- data.tar.gz: 0bed63c55b1d2571d981efcb44fd5c008eab6f78e47bb7bf2d53e061b356b59a
3
+ metadata.gz: 83bf82adb70fa074a1f303a612403523b64317dc0bc780432a46c1babe5e853b
4
+ data.tar.gz: bc6e9c2f98c527fb09ca5b2a0b6cb3c977f42d1cf4a287bd956fa33576b2d443
5
5
  SHA512:
6
- metadata.gz: fe13105ac13ba02104c02e512273964b0b784cae3663faec805cd6bb4d3ed2efeb4fe0720521817766ea3a438f81ebf5ffc5a8877c864d131c31fbedaed6ec17
7
- data.tar.gz: 23abcec32de31cdb6243a43439bc2a41e38842a456feb191808734aa2387c701c75de25af39f15c35474c1c6e222ea78e797b305247a8cd6ed5b646824cf7ea4
6
+ metadata.gz: 9865aac49407ff145daf5bc98ec83b3d3f63fb4ea06b483ff0713cfb25966443191f40c47990ea3bfd928248f9dcce70ebdbb522ad57ed46029e7b7304d9de59
7
+ data.tar.gz: fea67b00c8999565b4a6d3e08dad67a3e4132172d6ee40d2b3c93fd37b7135cb410d95fe5ba79a779cbc5d00ec99ec4aae44024bfba1e0de08860f408859e93d
checksums.yaml.gz.sig CHANGED
Binary file
data/bin/sus CHANGED
@@ -28,6 +28,6 @@ config.after_tests(assertions)
28
28
  #
29
29
  # $ stackprof sus.stackprof --text --limit 10
30
30
 
31
- if assertions.failed.any?
31
+ unless assertions.passed?
32
32
  exit(1)
33
33
  end
data/bin/sus-parallel CHANGED
@@ -65,6 +65,6 @@ results.close
65
65
  assertions = aggregation.value
66
66
  config.after_tests(assertions)
67
67
 
68
- if assertions.failed.any?
68
+ unless assertions.passed?
69
69
  exit(1)
70
70
  end
@@ -35,6 +35,8 @@ module Sus
35
35
  @passed = Array.new
36
36
  @failed = Array.new
37
37
  @deferred = Array.new
38
+ @skipped = Array.new
39
+ @errored = Array.new
38
40
 
39
41
  @count = 0
40
42
  end
@@ -63,15 +65,18 @@ module Sus
63
65
  # Nested assertions have been deferred.
64
66
  attr :deferred
65
67
 
68
+ attr :skipped
69
+ attr :errored
70
+
66
71
  # The total number of assertions performed:
67
72
  attr :count
68
73
 
69
74
  def inspect
70
- "\#<#{self.class} #{@passed.size} passed #{@failed.size} failed #{@deferred.size} deferred>"
75
+ "\#<#{self.class} #{@passed.size} passed #{@failed.size} failed #{@deferred.size} deferred #{@skipped.size} skipped #{@errored.size} errored>"
71
76
  end
72
77
 
73
78
  def total
74
- @passed.size + @failed.size
79
+ @passed.size + @failed.size + @deferred.size + @skipped.size + @errored.size
75
80
  end
76
81
 
77
82
  def print(output, verbose: @verbose)
@@ -95,6 +100,14 @@ module Sus
95
100
  output.write(:deferred, @deferred.size, " deferred", :reset, " ")
96
101
  end
97
102
 
103
+ if @skipped.any?
104
+ output.write(:skipped, @skipped.size, " skipped", :reset, " ")
105
+ end
106
+
107
+ if @errored.any?
108
+ output.write(:errored, @errored.size, " errored", :reset, " ")
109
+ end
110
+
98
111
  output.write("out of ", self.total, " total (", @count, " assertions)")
99
112
  end
100
113
  end
@@ -104,16 +117,16 @@ module Sus
104
117
  end
105
118
 
106
119
  def empty?
107
- @passed.empty? and @failed.empty?
120
+ @passed.empty? and @failed.empty? and @deferred.empty? and @skipped.empty? and @errored.empty?
108
121
  end
109
122
 
110
123
  def passed?
111
124
  if @inverted
112
125
  # Inverted assertions:
113
- self.failed.any?
126
+ @failed.any? and @errored.empty?
114
127
  else
115
128
  # Normal assertions:
116
- self.failed.empty?
129
+ @failed.empty? and @errored.empty?
117
130
  end
118
131
  end
119
132
 
@@ -121,6 +134,10 @@ module Sus
121
134
  !self.passed?
122
135
  end
123
136
 
137
+ def errored?
138
+ @errored.any?
139
+ end
140
+
124
141
  def assert(condition, message = nil)
125
142
  @count += 1
126
143
 
@@ -139,6 +156,11 @@ module Sus
139
156
  end
140
157
  end
141
158
 
159
+ def skip(reason)
160
+ @output.puts(:indent, :skipped, skip_prefix, reason)
161
+ @skipped << self
162
+ end
163
+
142
164
  def inform(message)
143
165
  @output.puts(:indent, :inform, inform_prefix, message)
144
166
  end
@@ -162,15 +184,15 @@ module Sus
162
184
  end
163
185
  end
164
186
 
165
- def fail(error)
166
- @failed << self
187
+ def error!(error)
188
+ @errored << self
167
189
 
168
190
  lines = error.message.split(/\r?\n/)
169
191
 
170
- @output.puts(:indent, *fail_prefix, "Unhandled exception ", :value, error.class, ":", :reset, " ", lines.shift)
192
+ @output.puts(:indent, *error_prefix, error.class, ": ", lines.shift)
171
193
 
172
194
  lines.each do |line|
173
- @output.puts(:indent, "| ", line)
195
+ @output.puts(:indent, line)
174
196
  end
175
197
 
176
198
  @output.write(Output::Backtrace.for(error, @identity))
@@ -201,7 +223,7 @@ module Sus
201
223
  begin
202
224
  result = yield(assertions)
203
225
  rescue StandardError => error
204
- assertions.fail(error)
226
+ assertions.error!(error)
205
227
  end
206
228
  end
207
229
 
@@ -251,7 +273,9 @@ module Sus
251
273
  def merge!(assertions)
252
274
  @count += assertions.count
253
275
 
254
- if assertions.passed?
276
+ if assertions.errored?
277
+ @errored << assertions
278
+ elsif assertions.passed?
255
279
  @passed << assertions
256
280
 
257
281
  # if @verbose
@@ -273,6 +297,8 @@ module Sus
273
297
  @passed.concat(assertions.passed)
274
298
  @failed.concat(assertions.failed)
275
299
  @deferred.concat(assertions.deferred)
300
+ @skipped.concat(assertions.skipped)
301
+ @errored.concat(assertions.errored)
276
302
 
277
303
  # if @verbose
278
304
  # @output.write(:indent)
@@ -303,5 +329,13 @@ module Sus
303
329
  def inform_prefix
304
330
  "ℹ "
305
331
  end
332
+
333
+ def skip_prefix
334
+ "⏸ "
335
+ end
336
+
337
+ def error_prefix
338
+ [:errored, "⚠ "]
339
+ end
306
340
  end
307
341
  end
data/lib/sus/be.rb CHANGED
@@ -16,7 +16,9 @@ module Sus
16
16
  end
17
17
 
18
18
  def call(assertions, subject)
19
- assertions.assert(subject.public_send(*@arguments), self)
19
+ assertions.nested(self) do |assertions|
20
+ assertions.assert(subject.public_send(*@arguments))
21
+ end
20
22
  end
21
23
 
22
24
  class << self
@@ -72,5 +74,9 @@ module Sus
72
74
  def be_nil
73
75
  Be::NIL
74
76
  end
77
+
78
+ def be_equal(other)
79
+ Be.new(:equal?, other)
80
+ end
75
81
  end
76
82
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2021-2022, by Samuel Williams.
5
+
6
+ module Sus
7
+ module BeTruthy
8
+ def self.print(output)
9
+ output.write("be truthy")
10
+ end
11
+
12
+ def self.call(assertions, subject)
13
+ assertions.nested(self) do |assertions|
14
+ assertions.assert(subject, self)
15
+ end
16
+ end
17
+ end
18
+
19
+ module BeFalsey
20
+ def self.print(output)
21
+ output.write("be falsey")
22
+ end
23
+
24
+ def self.call(assertions, subject)
25
+ assertions.nested(self) do |assertions|
26
+ assertions.assert(!subject, self)
27
+ end
28
+ end
29
+ end
30
+
31
+ class Base
32
+ def be_truthy
33
+ BeTruthy
34
+ end
35
+
36
+ def be_falsey
37
+ BeFalsey
38
+ end
39
+ end
40
+ end
data/lib/sus/config.rb CHANGED
@@ -116,13 +116,13 @@ module Sus
116
116
 
117
117
  assertions.print(output)
118
118
  output.puts
119
-
119
+
120
120
  print_finished_statistics(assertions)
121
-
121
+
122
122
  if !partial? and assertions.passed?
123
123
  print_test_feedback(assertions)
124
124
  end
125
-
125
+
126
126
  print_slow_tests(assertions)
127
127
  print_failed_assertions(assertions)
128
128
  end
@@ -193,14 +193,22 @@ module Sus
193
193
  end
194
194
  end
195
195
 
196
- def print_failed_assertions(assertions)
197
- if assertions.failed.any?
196
+ def print_assertions(title, assertions)
197
+ if assertions.any?
198
198
  output.puts
199
+ output.puts title
199
200
 
200
- assertions.failed.each do |failure|
201
- output.append(failure.output)
201
+ assertions.each do |assertion|
202
+ assertions.each do |failure|
203
+ output.append(failure.output)
204
+ end
202
205
  end
203
206
  end
204
207
  end
208
+
209
+ def print_failed_assertions(assertions)
210
+ print_assertions("🤔 Failed assertions:", assertions.failed)
211
+ print_assertions("🔥 Errored assertions:", assertions.errored)
212
+ end
205
213
  end
206
214
  end
data/lib/sus/file.rb CHANGED
@@ -11,7 +11,7 @@ Sus::TOPLEVEL_CLASS_EVAL = ->(klass, path){klass.class_eval(::File.read(path), p
11
11
  module Sus
12
12
  module File
13
13
  extend Context
14
-
14
+
15
15
  def self.extended(base)
16
16
  base.children = Hash.new
17
17
  end
data/lib/sus/it.rb CHANGED
@@ -39,10 +39,20 @@ module Sus
39
39
  instance = self.new(assertions)
40
40
 
41
41
  instance.around do
42
- instance.call
42
+ handle_skip(instance, assertions)
43
43
  end
44
44
  end
45
45
  end
46
+
47
+ def handle_skip(instance, assertions)
48
+ reason = catch(:skip) do
49
+ return instance.call
50
+ end
51
+
52
+ assertions.skip(reason)
53
+
54
+ return nil
55
+ end
46
56
  end
47
57
 
48
58
  module Context
@@ -50,4 +60,10 @@ module Sus
50
60
  add It.build(self, ...)
51
61
  end
52
62
  end
63
+
64
+ class Base
65
+ def skip(reason)
66
+ throw :skip, reason
67
+ end
68
+ end
53
69
  end
@@ -11,12 +11,18 @@ module Sus
11
11
 
12
12
  attr_accessor :shared
13
13
 
14
- def self.build(parent, shared, unique: false)
14
+ def self.build(parent, shared, unique: false, &block)
15
15
  base = Class.new(parent)
16
16
  base.singleton_class.prepend(ItBehavesLike)
17
17
  base.children = Hash.new
18
18
  base.description = shared.name
19
19
  base.identity = Identity.nested(parent.identity, base.description, unique: unique)
20
+
21
+ # User provided block is evaluated first, so that it can provide default behaviour for the shared context:
22
+ if block_given?
23
+ base.class_exec(&block)
24
+ end
25
+
20
26
  base.class_exec(&shared.block)
21
27
  return base
22
28
  end
@@ -28,8 +34,8 @@ module Sus
28
34
  end
29
35
 
30
36
  module Context
31
- def it_behaves_like(shared, **options)
32
- add ItBehavesLike.build(self, shared, **options)
37
+ def it_behaves_like(shared, **options, &block)
38
+ add ItBehavesLike.build(self, shared, **options, &block)
33
39
  end
34
40
  end
35
41
  end
@@ -14,7 +14,6 @@ module Sus
14
14
  def initialize(state = :free, context = nil)
15
15
  @state = state
16
16
  @context = context
17
- @index = 0
18
17
  end
19
18
 
20
19
  INDICATORS = {
@@ -36,8 +35,6 @@ module Sus
36
35
  end
37
36
 
38
37
  def print(output)
39
- message = @message
40
-
41
38
  output.write(
42
39
  @state, self.indicator, " "
43
40
  )
@@ -19,6 +19,8 @@ module Sus
19
19
  @styles[:indent] = @indent
20
20
  end
21
21
 
22
+ attr :styles
23
+
22
24
  def buffered
23
25
  Buffered.new(self)
24
26
  end
data/lib/sus/output.rb CHANGED
@@ -39,7 +39,9 @@ module Sus
39
39
 
40
40
  output[:passed] = output.style(:green)
41
41
  output[:failed] = output.style(:red)
42
- output[:error] = output.style(:red)
42
+ output[:deferred] = output.style(:yellow)
43
+ output[:skipped] = output.style(:blue)
44
+ output[:errored] = output.style(:red)
43
45
  # output[:inform] = output.style(nil, nil, :bold)
44
46
 
45
47
  return output
data/lib/sus/receive.rb CHANGED
@@ -47,14 +47,17 @@ module Sus
47
47
 
48
48
  def once
49
49
  @times = Times.new(Be.new(:==, 1))
50
+ return self
50
51
  end
51
52
 
52
53
  def twice
53
54
  @times = Times.new(Be.new(:==, 2))
55
+ return self
54
56
  end
55
57
 
56
58
  def with_call_count(predicate)
57
59
  @times = Times.new(predicate)
60
+ return self
58
61
  end
59
62
 
60
63
  def and_return(*returning)
data/lib/sus/registry.rb CHANGED
@@ -19,6 +19,8 @@ require_relative 'let'
19
19
 
20
20
  module Sus
21
21
  class Registry
22
+ DIRECTORY_GLOB = "**/*.rb"
23
+
22
24
  # Create a top level scope with self as the instance:
23
25
  def initialize(base = Sus.base(self))
24
26
  @base = base
@@ -31,9 +33,21 @@ module Sus
31
33
  end
32
34
 
33
35
  def load(path)
36
+ if ::File.directory?(path)
37
+ load_directory(path)
38
+ else
39
+ load_file(path)
40
+ end
41
+ end
42
+
43
+ private def load_file(path)
34
44
  @base.file(path)
35
45
  end
36
46
 
47
+ private def load_directory(path)
48
+ ::Dir.glob(::File.join(path, DIRECTORY_GLOB), &self.method(:load_file))
49
+ end
50
+
37
51
  def call(assertions = Assertions.default)
38
52
  @base.call(assertions)
39
53
 
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.14.0"
7
+ VERSION = "0.15.1"
8
8
  end
data/lib/sus.rb CHANGED
@@ -10,6 +10,7 @@ require_relative 'sus/assertions'
10
10
 
11
11
  require_relative 'sus/expect'
12
12
  require_relative 'sus/be'
13
+ require_relative 'sus/be_truthy'
13
14
  require_relative 'sus/be_within'
14
15
 
15
16
  require_relative 'sus/mock'
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.14.0
4
+ version: 0.15.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -37,7 +37,7 @@ cert_chain:
37
37
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
38
38
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
39
39
  -----END CERTIFICATE-----
40
- date: 2022-10-03 00:00:00.000000000 Z
40
+ date: 2022-12-04 00:00:00.000000000 Z
41
41
  dependencies:
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: bake-test
@@ -95,6 +95,7 @@ files:
95
95
  - lib/sus/assertions.rb
96
96
  - lib/sus/base.rb
97
97
  - lib/sus/be.rb
98
+ - lib/sus/be_truthy.rb
98
99
  - lib/sus/be_within.rb
99
100
  - lib/sus/clock.rb
100
101
  - lib/sus/config.rb
metadata.gz.sig CHANGED
Binary file