speq 0.2.0 → 0.2.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: 32ff60fc943c04afc5c85f9b49c020a08f0e38720eed9f02c7be16aa9e4c1777
4
- data.tar.gz: b5622c58ca6fd050185092fc4a6fda473393ebdf6d33dc1a8cd1a176c2cbcce6
3
+ metadata.gz: ca948589baaf3fd6d4385aec6da046cb0b96595ea1cc78af59787bf76112abe0
4
+ data.tar.gz: 5879601e06032198afc0675b44130900b3fdbb895f207cab7c2cfc94b70638fb
5
5
  SHA512:
6
- metadata.gz: e088259968e6271760e885a1aef4e90b23b93073633c9828d8e2c241735ae79d4be980f0055b21aabfbf4883f79aec37632ac8e27987b5cf6c099f6aeda6ec2a
7
- data.tar.gz: 316856e55388a2baf6b919da7c017a7bf3fcdabbac396a3adeabad8842ae675d57a53a5ee1c03a932d38f6e4c97955bd6c1b23b9c5c9f43742c50b53bdae576c
6
+ metadata.gz: 8f999677ac2de3f9e9760cfebe7180d1cb91215060a6f424f0c856f981ba9818715105b13dc1353d1b43d1fb9382b6c2189a0f31f64d50b21999b8ecb4bd4e23
7
+ data.tar.gz: 1f674c4b2593df191a9d036b0f458cf1aee46f342066667f5df33504bd70e5cfb30858f3fdc208229f0a87741d36fd9b7785e5a05234bb2a0e4f85556c8ffb18
data/.gitignore CHANGED
@@ -6,3 +6,5 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+
10
+ .vscode
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- speq (0.2.0)
4
+ speq (0.2.1)
5
5
  colorize (~> 0.8.1)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -16,21 +16,24 @@ gem 'speq'
16
16
 
17
17
  And then execute:
18
18
 
19
- $ bundle
19
+ bundle
20
20
 
21
21
  Or install it yourself as:
22
22
 
23
- $ gem install speq
23
+ gem install speq
24
+
25
+ ## Design
26
+
27
+ Speq's design choices are influenced by the competing motivations of having tests be as short and simple as possible while maintaining the flexibility to be as descriptive as needed.
28
+
29
+ Speq is loosely based on the given-when-then or arrange-act-assert testing pattern. Whereas one would typically need to make each step explicit, Speq tests focus on making it easy to simply assert the expected behavior with an implicit arrangement and action.
24
30
 
25
31
  ## Syntax
26
32
 
27
- Speq excels at running many similar tests and checks. It omits explicit descriptions and outputs simple reports.
33
+ Speq's syntax is still in flux and likely to change dramatically until an effective setup is established.
28
34
 
29
35
  ```ruby
30
- does :prime? do
31
- given 0, 1, 8, match: false
32
- given 2, 3, 97, match: true
33
- end
36
+ test_unit :sort, on: [3, 2, 1], eq: [1, 2, 3]
34
37
  ```
35
38
 
36
39
  ## Usage
@@ -40,30 +43,24 @@ end
40
43
  ```ruby
41
44
  require 'speq'
42
45
 
43
- class Array
44
- def my_map
45
- Array.new(length) { |index| yield(self[index])}
46
- end
46
+ Speq.test do
47
+ # Tests here can access local variables.
48
+ # Test results are printed to $stdout.
49
+ # The method returns true if all tests pass, false otherwise.
47
50
  end
48
-
49
- # Speq.test...
50
51
  ```
51
52
 
52
53
  ### With dedicated spec files
53
54
 
54
55
  Speq also offers a simple CLI that lets you run tests written in dedicated spec files.
55
56
 
56
- Executing the following command:
57
-
58
- $ bundle exec speq
59
-
60
- will recursively search the working directory and run all files that end with `_speq.rb`.
57
+ Executing `bundle exec speq` will recursively search the working directory and run all files that end with `_speq.rb`.
61
58
 
62
59
  To run individual files, specify a list of speq file prefixes. For example, to run tests that are within the files `example_speq.rb` and `sample_speq.rb`, simply execute:
63
60
 
64
- $ bundle exec speq example sample
61
+ bundle exec speq example sample
65
62
 
66
- Speq files are not expected to require `speq`, but they should require other files that may be needed to run the speqs.
63
+ Speq files are not expected to require `speq`, but they should require other files that may be needed to run the specs.
67
64
 
68
65
  ## Contributing
69
66
 
data/bin/console CHANGED
@@ -4,6 +4,5 @@ require 'bundler/setup'
4
4
  require 'pry'
5
5
 
6
6
  require 'speq'
7
- include Speq
8
7
 
9
8
  Pry.start
data/exe/speq CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'speq/cli'
3
+ require 'speq'
4
4
  Speq::CLI.new(ARGV).run
data/lib/speq/cli.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require 'find'
2
2
  require 'colorize'
3
- require 'speq/test'
4
3
 
5
4
  # Provides a CLI for running Speq
6
5
  module Speq
@@ -18,12 +17,8 @@ module Speq
18
17
  Dir.glob("#{Dir.pwd}/**/{#{file_prefixes.join(',')}}_speq.rb")
19
18
  end
20
19
 
21
- def does(subject, &block)
22
- tests << Test.new(subject, self, &block)
23
- end
24
-
25
20
  def run
26
- @files.each { |file| instance_eval(File.read(file), file) }
21
+ @files.each { |file| Speq.module_eval(File.read(file), file) }
27
22
  @tests.each(&:report)
28
23
  @tests.all?(&:passed?)
29
24
  end
data/lib/speq/fake.rb CHANGED
@@ -1,5 +1,18 @@
1
1
  # The Fake class inludes a variety of doubles, mocks, stubs, etc.
2
2
  module Speq
3
3
  class Fake
4
+ def initialize(mapping)
5
+ mapping.each do |method_name, return_value|
6
+ define_singleton_method(method_name, &infer_method_body(return_value))
7
+ end
8
+ end
9
+
10
+ def infer_method_body(return_value)
11
+ if return_value.respond_to?(:call)
12
+ return_value
13
+ else
14
+ -> { return_value }
15
+ end
16
+ end
4
17
  end
5
18
  end
@@ -0,0 +1,50 @@
1
+ # The Match class includes factory methods for generating objects that
2
+ # respond to match, returning true for an expected return value of a unit test
3
+ module Speq
4
+ class Matcher
5
+ def initialize(expected)
6
+ @expected = expected
7
+ end
8
+
9
+ def match(actual)
10
+ @expected[actual]
11
+ end
12
+
13
+ def self.truthy
14
+ Matcher.new(->(actual_value) { actual_value ? true : false })
15
+ end
16
+
17
+ def self.falsey
18
+ Matcher.new(->(actual_value) { actual_value ? false : true })
19
+ end
20
+
21
+ def self.eq(expected_value)
22
+ Matcher.new(->(actual_value) { expected_value.eql?(actual_value) })
23
+ end
24
+
25
+ def self.is(expected_object)
26
+ Matcher.new(->(actual_object) { expected_object.equal?(actual_object) })
27
+ end
28
+
29
+ def self.raises(expected_except)
30
+ case expected_except
31
+ when Class
32
+ raise_class(expected_except)
33
+ when String
34
+ raise_message(expected_except)
35
+ else
36
+ raise ArgumentError
37
+ end
38
+ end
39
+
40
+ def self.raise_class(expected_error)
41
+ Matcher.new(->(actual_except) { actual_except.class <= expected_error })
42
+ end
43
+
44
+ def self.raise_message(expected_message)
45
+ Matcher.new(
46
+ ->(actual_except) { actual_except.message == expected_message }
47
+ )
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,31 @@
1
+ # The Report class produces and prints a report per test group
2
+ module Speq
3
+ class Report
4
+ def initialize(units)
5
+ @units = units
6
+ end
7
+
8
+ def print_report
9
+ report_string = ''
10
+
11
+ @units.each do |unit|
12
+ if unit.passed?
13
+ outcome = 'PASSED: '
14
+ color = :green
15
+ else
16
+ outcome = 'FAILED: '
17
+ color = :red
18
+ end
19
+
20
+ method = "calling '#{unit.message}' "
21
+ arguments = unit.arguments ? "with arguments: '#{unit.arguments}'" : ''
22
+ receiver = unit.receiver == Object ? '' : "on: #{unit.receiver} "
23
+
24
+ report_string <<
25
+ [outcome, method, arguments, receiver, "\n"].join.colorize(color)
26
+ end
27
+
28
+ puts report_string
29
+ end
30
+ end
31
+ end
data/lib/speq/test.rb CHANGED
@@ -1,61 +1,12 @@
1
- require 'speq/match'
2
-
3
1
  # The Test class is a simple implementation of unit test block
4
2
  module Speq
5
3
  class Test
6
- attr_reader :method, :reciever, :report
7
-
8
- def initialize(method_symbol, class_name = Object, &block)
9
- @method = method_symbol
10
- @reciever = class_name
4
+ def initialize
11
5
  @units = []
12
-
13
- instance_eval(&block)
14
- print_report
15
- end
16
-
17
- def given(*args, match:)
18
- args.each do |arg|
19
- return_value = reciever.send(method, *arg)
20
-
21
- @units << Match.new(return_value, :eql?, arg, match)
22
- end
23
- end
24
-
25
- def on(*receivers, match:)
26
- receivers.each do |receiver|
27
- return_value = receiver.send(method)
28
-
29
- @units << Match.new(return_value, :eql?, arg, match)
30
- end
31
6
  end
32
7
 
33
8
  def passed?
34
9
  @units.all?(&:passed?)
35
10
  end
36
-
37
- def print_report
38
- report_string = "Testing: #{method}\n"
39
-
40
- @units.each do |one_test|
41
- if one_test.passed?
42
- outcome_text = 'PASSED'
43
- color = :green
44
- else
45
- outcome_text = 'FAILED'
46
- color = :red
47
- end
48
-
49
- indent = ' ' * @method.to_s.length
50
-
51
- report_string <<
52
- ["\n#{outcome_text} when given: #{one_test.args}\n".colorize(color),
53
- " returned: #{one_test.actual}\n".colorize(color),
54
- " expected: #{one_test.expected}\n".colorize(color)].join
55
- end
56
- puts report_string
57
-
58
- passed?
59
- end
60
11
  end
61
12
  end
data/lib/speq/unit.rb ADDED
@@ -0,0 +1,20 @@
1
+ # The Unit class is responsible for running a test and storing the result
2
+ module Speq
3
+ class Unit
4
+ attr_reader :message, :receiver, :arguments
5
+
6
+ def initialize(message, receiver = Object, arguments = [], matcher)
7
+ @result = matcher.match(receiver.send(message, *arguments))
8
+ rescue StandardError => exception
9
+ @result = matcher.match(exception)
10
+ ensure
11
+ @message = message
12
+ @receiver = receiver
13
+ @arguments = arguments
14
+ end
15
+
16
+ def passed?
17
+ @result
18
+ end
19
+ end
20
+ end
data/lib/speq/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Speq
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '0.2.1'.freeze
3
3
  end
data/lib/speq.rb CHANGED
@@ -1,13 +1,29 @@
1
1
  require 'speq/version'
2
2
  require 'speq/test'
3
- require 'speq/match'
3
+ require 'speq/matcher'
4
+ require 'speq/report'
5
+ require 'speq/unit'
4
6
  require 'speq/fake'
5
7
  require 'speq/cli'
6
8
 
7
9
  module Speq
8
10
  module_function
9
11
 
10
- def does(subject, &block)
11
- Test.new(subject, self, &block).report
12
+ def method_missing(method, *args)
13
+ if Matcher.respond_to?(method)
14
+ Matcher.send(method, *args)
15
+ else
16
+ super
17
+ end
18
+ end
19
+
20
+ def unit_test(message, **kwargs)
21
+ matcher_method = kwargs.keys.find { |key| Matcher.respond_to?(key) }
22
+ matcher = send(matcher_method, kwargs[matcher_method])
23
+
24
+ unit = Unit.new(message, kwargs[:on], kwargs[:with], matcher)
25
+ Report.new([unit]).print_report
26
+
27
+ unit.passed?
12
28
  end
13
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: speq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - zaniar moradian
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-13 00:00:00.000000000 Z
11
+ date: 2018-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -86,8 +86,10 @@ files:
86
86
  - lib/speq.rb
87
87
  - lib/speq/cli.rb
88
88
  - lib/speq/fake.rb
89
- - lib/speq/match.rb
89
+ - lib/speq/matcher.rb
90
+ - lib/speq/report.rb
90
91
  - lib/speq/test.rb
92
+ - lib/speq/unit.rb
91
93
  - lib/speq/version.rb
92
94
  - speq.gemspec
93
95
  homepage: https://github.com/znrm/speq
data/lib/speq/match.rb DELETED
@@ -1,26 +0,0 @@
1
- # The Match class includes a variety of matchers
2
- module Speq
3
- class Match
4
- attr_reader :actual, :expected, :passed, :args
5
-
6
- def initialize(actual, match_sym, args, expected = nil)
7
- @actual = actual
8
- @expected = expected
9
- @passed = false
10
- @args = args
11
-
12
- evaluate_match(match_sym)
13
- end
14
-
15
- def evaluate_match(match_sym)
16
- case match_sym
17
- when :eql?, :equal?
18
- @passed = actual.send(match_sym, expected)
19
- end
20
- end
21
-
22
- def passed?
23
- @passed
24
- end
25
- end
26
- end