fix 1.0.0.beta4 → 1.0.0.beta5

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: 6245525d719965043d4187cbcce446e21c2b946303048159a13cc37161851ada
4
- data.tar.gz: c5b10da14f591df283e832f15f4839b420ecfbcbca4af6ed2974b28c20815d15
3
+ metadata.gz: 6f9b6d58547e6b78494ab484447f08c43a2fd233db5ef946c977b0f21fc0311d
4
+ data.tar.gz: 0fb204fd7cb1ccf56ddfacfe6737e137c387d5734855e629edae6a5289d2e291
5
5
  SHA512:
6
- metadata.gz: 9ba29c713607b3cfe280c7eb82e9eee07adc69b8d0c58c0ab9cf54117befc5a0f35c76c32d93cd0e5c4bf911a5c09786109ecc336d4866ada3e7d79f0296551b
7
- data.tar.gz: 6267c5c89cd4a6cf4a7573bb4866e4855ed10a403cd2cb606fbe9a18f6ff3f3206559e01f8c349f0ca82d6b8a60fed13546dce80744b0967ca9ac3aeda2d381b
6
+ metadata.gz: 67bd36e9816e7f92c0a2534d3d7055a73c5c249182b6b0e7842441c856e0fb6d47e0fb59dbe89b9fbe3124212b98e765cf5f312a14e276017b1dcd29d120002f
7
+ data.tar.gz: e58648ee25f43b7d964a2f0782a05724c935b2661dc4c2afa5c71bff51af0baac694ef86a12c911266bb1d4e4ebc50d3f499e05531722d0362be5fc1f1f6bd5e
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2014-2020 Cyril Kato
3
+ Copyright (c) 2014-2021 Cyril Kato
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,29 +1,33 @@
1
1
  # Fix
2
2
 
3
- [![Build Status](https://api.travis-ci.org/fixrb/fix.svg?branch=master)][travis]
4
- [![Code Climate](https://codeclimate.com/github/fixrb/fix/badges/gpa.svg)][codeclimate]
5
- [![Gem Version](https://badge.fury.io/rb/fix.svg)][gem]
6
- [![Inline docs](https://inch-ci.org/github/fixrb/fix.svg?branch=master)][inchpages]
7
- [![Documentation](https://img.shields.io/:yard-docs-38c800.svg)][rubydoc]
8
- [![Gitter](https://badges.gitter.im/Join%20Chat.svg)][gitter]
3
+ [![Home](https://img.shields.io/badge/Home-fixrb.dev-00af8b)](https://fixrb.dev/)
4
+ [![Version](https://img.shields.io/github/v/tag/fixrb/fix?label=Version&logo=github)](https://github.com/fixrb/fix/releases)
5
+ [![Yard documentation](https://img.shields.io/badge/Yard-documentation-blue.svg?logo=github)](https://rubydoc.info/github/fixrb/fix/main)
6
+ [![CI](https://github.com/fixrb/fix/workflows/CI/badge.svg?branch=main)](https://github.com/fixrb/fix/actions?query=workflow%3Aci+branch%3Amain)
7
+ [![RuboCop](https://github.com/fixrb/fix/workflows/RuboCop/badge.svg?branch=main)](https://github.com/fixrb/fix/actions?query=workflow%3Arubocop+branch%3Amain)
8
+ [![License](https://img.shields.io/github/license/fixrb/fix?label=License&logo=github)](https://github.com/fixrb/fix/raw/main/LICENSE.md)
9
9
 
10
- > Specing framework for Ruby.
10
+ ![Fix specing framework for Ruby](https://github.com/fixrb/fix/raw/main/img/fix.jpg)
11
11
 
12
12
  ## Installation
13
13
 
14
14
  Add this line to your application's Gemfile:
15
15
 
16
16
  ```ruby
17
- gem 'fix', '>= 1.0.0.beta4'
17
+ gem "fix", ">= 1.0.0.beta5"
18
18
  ```
19
19
 
20
20
  And then execute:
21
21
 
22
- $ bundle
22
+ ```sh
23
+ bundle
24
+ ```
23
25
 
24
26
  Or install it yourself as:
25
27
 
26
- $ gem install fix --pre
28
+ ```sh
29
+ gem install fix --pre
30
+ ```
27
31
 
28
32
  ## Example
29
33
 
@@ -33,31 +37,29 @@ Given this app:
33
37
  # examples/duck/app.rb
34
38
  class Duck
35
39
  def walks
36
- 'Klop klop!'
40
+ "Klop klop!"
37
41
  end
38
42
 
39
43
  def swims
40
- 'Swoosh...'
44
+ "Swoosh..."
41
45
  end
42
46
 
43
47
  def quacks
44
- puts 'Quaaaaaack!'
48
+ puts "Quaaaaaack!"
45
49
  end
46
50
  end
47
51
  ```
48
52
 
49
- When you run this:
53
+ And this fixed behavior:
50
54
 
51
55
  ```ruby
52
56
  # examples/duck/fix.rb
53
- require_relative 'app'
54
- require_relative '../../lib/fix'
55
57
 
56
- @bird = Duck.new
58
+ relative "fix"
57
59
 
58
- Fix(@bird) do
60
+ Fix :Duck do
59
61
  on :swims do
60
- it { MUST eql 'Swoosh...' }
62
+ it { MUST eql "Swoosh..." }
61
63
  end
62
64
 
63
65
  on :speaks do
@@ -65,27 +67,45 @@ Fix(@bird) do
65
67
  end
66
68
 
67
69
  on :sings do
68
- it { MAY eql '♪... ♫...' }
70
+ it { MAY eql "♪... ♫..." }
69
71
  end
70
72
  end
71
73
  ```
72
74
 
73
- Then the output should look like this:
75
+ When I run this test:
76
+
77
+ ```ruby
78
+ # examples/duck/test.rb
79
+
80
+ require_relative "app"
81
+ require_relative "fix"
82
+
83
+ Fix[:Duck].call(Duck.new)
84
+ ```
74
85
 
75
86
  ```sh
76
- ruby examples/duck/fix.rb
87
+ ruby examples/duck/test.rb
77
88
  ```
78
89
 
90
+ I should see this output:
91
+
79
92
  ```txt
80
- examples/duck/fix.rb:8: Success: expected to eql "Swoosh...".
81
- examples/duck/fix.rb:12: Success: undefined method `speaks' for #<Duck:0x00007fe3be868ea0>.
82
- examples/duck/fix.rb:16: NoMethodError: undefined method `sings' for #<Duck:0x00007fe3be868ea0>.
93
+ Test #<Duck:0x00007fc5289bcf68> against Duck:
94
+ - NoMethodError: undefined method `sings' for #<Duck:0x00007fc5289bcf68>.
95
+ - Success: expected to eql "Swoosh...".
96
+ - Success: undefined method `speaks' for #<Duck:0x00007fc5289bcf68>.
83
97
  ```
84
98
 
99
+ ## Test suite
100
+
101
+ __Fix__'s specifications are [fixed here](https://github.com/fixrb/fix/blob/main/fix/) and can be tested against __Fix__'s codebase executing [test/](https://github.com/fixrb/fix/blob/main/test/)'s files.
102
+
85
103
  ## Contact
86
104
 
87
- * Home page: https://fixrb.dev/
88
- * Source code: https://github.com/fixrb/fix
105
+ * Home page: [https://fixrb.dev/](https://fixrb.dev/)
106
+ * Source code: [https://github.com/fixrb/fix](https://github.com/fixrb/fix)
107
+ * API Doc: [https://rubydoc.info/gems/fix](https://rubydoc.info/gems/fix)
108
+ * Twitter: [https://twitter.com/fix\_rb](https://twitter.com/fix\_rb)
89
109
 
90
110
  ## Versioning
91
111
 
@@ -93,20 +113,13 @@ __Fix__ follows [Semantic Versioning 2.0](https://semver.org/).
93
113
 
94
114
  ## License
95
115
 
96
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
116
+ The [gem](https://rubygems.org/gems/fix) is available as open source under the terms of the [MIT License](https://github.com/fixrb/fix/raw/main/LICENSE.md).
97
117
 
98
118
  ***
99
119
 
100
120
  <p>
101
121
  This project is sponsored by:<br />
102
122
  <a href="https://sashite.com/"><img
103
- src="https://github.com/fixrb/fix/raw/master/img/sashite.png"
123
+ src="https://github.com/fixrb/fix/raw/main/img/sashite.png"
104
124
  alt="Sashite" /></a>
105
125
  </p>
106
-
107
- [travis]: https://travis-ci.org/fixrb/fix
108
- [codeclimate]: https://codeclimate.com/github/fixrb/fix
109
- [gem]: https://rubygems.org/gems/fix
110
- [inchpages]: https://inch-ci.org/github/fixrb/fix
111
- [rubydoc]: https://rubydoc.info/gems/fix/frames
112
- [gitter]: https://gitter.im/fixrb/fix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
data/lib/fix.rb CHANGED
@@ -1,25 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative File.join("fix", "test")
4
+
5
+ require_relative "kernel"
6
+
3
7
  # Namespace for the Fix framework.
4
- #
5
8
  module Fix
6
- # Specs are built with this method.
9
+ # Test a built specification.
7
10
  #
8
- # @example 42 must be equal to 42
9
- # describe(42) do
10
- # it { MUST equal 42 }
11
- # end
11
+ # @example Run _Answer_ specification against `42`.
12
+ # Fix[:Answer].call(42)
12
13
  #
13
- # @param front_object [BasicObject] The front object.
14
- # @param options [Hash] Some options.
15
- # @param specs [Proc] The set of specs.
14
+ # @example Test _Answer_ specification against `42`.
15
+ # Fix[:Answer].matches? { 42 }
16
16
  #
17
- # @raise [SystemExit] The result of the test.
18
- def self.describe(front_object, **lets, &block)
19
- c = Context.new(front_object, ::Defi.send(:itself), **lets)
20
- c.instance_eval(&block)
17
+ # @param name [String, Symbol] The name of the specification document.
18
+ #
19
+ # @return [::Fix::Dsl] The specification document.
20
+ def self.[](name)
21
+ Test.new(name)
21
22
  end
22
23
  end
23
-
24
- require_relative 'kernel'
25
- require_relative File.join('fix', 'context')
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fix
4
+ # Send log messages to the console.
5
+ module Console
6
+ # @param name [String, Symbol] The name of the specification document.
7
+ # @param subject [#object_id] The front object to be tested.
8
+ #
9
+ # @return [nil] Add a message to `$stdout`.
10
+ def self.title(name, subject)
11
+ puts "Run #{name} specs against #{subject.inspect}:"
12
+ end
13
+
14
+ # @param report [::Expresenter::Pass] Passed expectation result presenter.
15
+ #
16
+ # @see https://github.com/fixrb/expresenter
17
+ #
18
+ # @return [nil] Add a colored message to `$stdout`.
19
+ def self.passed_spec(report)
20
+ puts "- #{report.colored_string}"
21
+ end
22
+
23
+ # @param report [::Expresenter::Fail] Failed expectation result presenter.
24
+ #
25
+ # @see https://github.com/fixrb/expresenter
26
+ #
27
+ # @raise [SystemExit] Terminate execution immediately with colored message.
28
+ def self.failed_spec(report)
29
+ abort "- #{report.colored_string}"
30
+ end
31
+ end
32
+ end
data/lib/fix/doc.rb ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fix
4
+ # Module for storing spec documents.
5
+ module Doc
6
+ end
7
+ end
data/lib/fix/dsl.rb ADDED
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "defi"
4
+ require "matchi/helper"
5
+ require "spectus"
6
+
7
+ require_relative "console"
8
+
9
+ module Fix
10
+ # Abstract class for handling the domain-specific language.
11
+ class Dsl
12
+ include ::Matchi::Helper
13
+
14
+ # Sets a user-defined property.
15
+ #
16
+ # @example
17
+ # require "fix"
18
+ #
19
+ # Fix.describe "Name stories" do
20
+ # let(:name) { "Bob" }
21
+ #
22
+ # it { expect(name).to eq "Bob" }
23
+ #
24
+ # context "with last name" do
25
+ # let(:name) { "#{super()} Smith" }
26
+ #
27
+ # it { expect(name).to eq "Bob Smith" }
28
+ # end
29
+ # end
30
+ #
31
+ # # Output to the console
32
+ # # Success: expected to eq "Bob".
33
+ # # Success: expected to eq "Bob Smith".
34
+ #
35
+ # @param name [String, Symbol] The name of the property.
36
+ # @param block [Proc] The content of the method to define.
37
+ #
38
+ # @return [Symbol] A private method that define the block content.
39
+ #
40
+ # @api public
41
+ def self.let(name, &block)
42
+ private_class_method define_singleton_method(name, &block)
43
+ end
44
+
45
+ def self.with(**kwargs, &block)
46
+ klass = ::Class.new(self)
47
+ kwargs.each { |name, value| klass.let(name) { value } }
48
+ klass.instance_eval(&block)
49
+ klass
50
+ end
51
+
52
+ # Defines an example group that describes a unit to be tested.
53
+ #
54
+ # @example
55
+ # require "fix"
56
+ #
57
+ # Fix.on String do
58
+ # on "+" do
59
+ # it("concats") { expect("foo" + "bar").to eq "foobar" }
60
+ # end
61
+ # end
62
+ #
63
+ # # Output to the console
64
+ # # Success: expected to eq "foobar".
65
+ #
66
+ # @param const [Module, String] A module to include in block context.
67
+ # @param block [Proc] The block to define the specs.
68
+ #
69
+ # @api public
70
+ def self.on(method_name, *args, **kwargs, &block)
71
+ klass = ::Class.new(self)
72
+ klass.const_get(:SPECS) << klass
73
+ const_set("Child#{block.object_id}", klass)
74
+
75
+ klass.define_singleton_method(:challenges) do
76
+ super() + [::Defi.send(method_name, *args, **kwargs)]
77
+ end
78
+
79
+ klass.instance_eval(&block)
80
+ klass
81
+ end
82
+
83
+ # Defines a concrete test case.
84
+ #
85
+ # The test is performed by the block supplied to `&block`.
86
+ #
87
+ # @example The integer after 41
88
+ # require "fix"
89
+ #
90
+ # Fix(:AnswerToEverything) { it { MUST be 42 } }.call(42)
91
+ #
92
+ # # Output to the console
93
+ # # Success: expected to be 42.
94
+ #
95
+ # @example A division by zero
96
+ # require "fix"
97
+ #
98
+ # Fix :Integer do
99
+ # it { MUST be_an_instance_of Integer }
100
+ #
101
+ # on :/, 0 do
102
+ # it { MUST raise_exception ZeroDivisionError }
103
+ # end
104
+ # end
105
+ #
106
+ # Fix[:Integer].call(41)
107
+ #
108
+ # # Output to the console
109
+ # # Success: expected 41 to be an instance of Integer.
110
+ # # Success: divided by 0.
111
+ #
112
+ # It can be used inside a {.describe} or {.context} section.
113
+ #
114
+ # @param block [Proc] An expectation to evaluate.
115
+ #
116
+ # @raise (see ExpectationTarget::Base#result)
117
+ # @return (see ExpectationTarget::Base#result)
118
+ #
119
+ # @api public
120
+ def self.it(&block)
121
+ define_method("test_#{block.object_id}", &block)
122
+ end
123
+
124
+ def self.its(method_name, *args, **kwargs, &block)
125
+ klass = ::Class.new(self)
126
+ klass.const_get(:SPECS) << klass
127
+ const_set("Child#{block.object_id}", klass)
128
+
129
+ klass.define_singleton_method(:challenges) do
130
+ super() + [::Defi.send(method_name, *args, **kwargs)]
131
+ end
132
+
133
+ klass.it(&block)
134
+ end
135
+
136
+ def self.challenges
137
+ []
138
+ end
139
+
140
+ private_class_method :challenges
141
+
142
+ private
143
+
144
+ def initialize(subject)
145
+ @subject = subject
146
+ end
147
+
148
+ ::Spectus.methods(false).each do |method_name|
149
+ define_method(method_name.upcase) do |matcher|
150
+ ::Spectus.public_send(method_name, matcher).call do
151
+ self.class.send(:challenges).inject(@subject) do |object, challenge|
152
+ challenge.to(object).call
153
+ end
154
+ end
155
+ end
156
+ end
157
+
158
+ def method_missing(method_name, *args, &block)
159
+ self.class.send(method_name)
160
+ rescue ::NoMethodError
161
+ super
162
+ end
163
+
164
+ def respond_to_missing?(method_name, include_private = false)
165
+ self.class.respond_to?(method_name) || super
166
+ end
167
+ end
168
+ end
data/lib/fix/test.rb ADDED
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "expresenter/fail"
4
+
5
+ require_relative "console"
6
+ require_relative "doc"
7
+
8
+ module Fix
9
+ # Module for testing spec documents.
10
+ class Test
11
+ attr_reader :name
12
+
13
+ def initialize(name)
14
+ @name = name
15
+ end
16
+
17
+ def call(subject)
18
+ Console.title(name, subject)
19
+ requirements(subject).each { |requirement| test(requirement) }
20
+ exit(true)
21
+ end
22
+
23
+ private
24
+
25
+ def requirements(subject)
26
+ specs.flat_map do |spec|
27
+ example = spec.new(subject)
28
+ example.public_methods(false).map do |public_method|
29
+ example.method(public_method)
30
+ end
31
+ end.shuffle
32
+ end
33
+
34
+ def specs
35
+ Doc.const_get(name).const_get(:SPECS)
36
+ end
37
+
38
+ def test(requirement)
39
+ Console.passed_spec requirement.call
40
+ rescue ::Expresenter::Fail => e
41
+ Console.failed_spec e
42
+ end
43
+ end
44
+ end
data/lib/kernel.rb CHANGED
@@ -1,9 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative File.join("fix", "doc")
4
+ require_relative File.join("fix", "dsl")
5
+ require_relative File.join("fix", "test")
6
+
7
+ # The Kernel module.
3
8
  module Kernel
9
+ # Specifications are built with this method.
10
+ #
11
+ # @example Fix 42 such as it must be equal to 42.
12
+ # Fix :Answer do
13
+ # it { MUST equal 42 }
14
+ # end
15
+ #
16
+ # @param name [String, Symbol] The name of the specification document.
17
+ # @param block [Proc] The specifications.
18
+ #
19
+ # @return [Class] The specification document.
20
+ #
4
21
  # rubocop:disable Naming/MethodName
5
- def Fix(subject = nil, **lets, &block)
6
- ::Fix.describe(subject, **lets, &block)
22
+ def Fix(name, &block)
23
+ klass = ::Class.new(::Fix::Dsl)
24
+ klass.const_set(:SPECS, [klass])
25
+ klass.instance_eval(&block)
26
+ ::Fix::Doc.const_set(name, klass)
27
+ ::Fix::Test.new(name)
7
28
  end
8
29
  # rubocop:enable Naming/MethodName
9
30
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fix
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta4
4
+ version: 1.0.0.beta5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyril Kato
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-16 00:00:00.000000000 Z
11
+ date: 2021-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: defi
@@ -16,70 +16,84 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.0.4
19
+ version: 2.0.5
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 2.0.4
26
+ version: 2.0.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: matchi
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.1.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.1.1
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: spectus
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: 3.1.2
47
+ version: 4.0.0
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: 3.1.2
54
+ version: 4.0.0
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
- - - "~>"
59
+ - - ">="
46
60
  - !ruby/object:Gem::Version
47
- version: '2.1'
61
+ version: '0'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
- - - "~>"
66
+ - - ">="
53
67
  - !ruby/object:Gem::Version
54
- version: '2.1'
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - "~>"
73
+ - - ">="
60
74
  - !ruby/object:Gem::Version
61
- version: '13.0'
75
+ version: '0'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
- - - "~>"
80
+ - - ">="
67
81
  - !ruby/object:Gem::Version
68
- version: '13.0'
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
- name: rubocop
84
+ name: rubocop-md
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - "~>"
87
+ - - ">="
74
88
  - !ruby/object:Gem::Version
75
- version: '0.79'
89
+ version: '0'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - "~>"
94
+ - - ">="
81
95
  - !ruby/object:Gem::Version
82
- version: '0.79'
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rubocop-performance
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -94,34 +108,76 @@ dependencies:
94
108
  - - ">="
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop-rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop-rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rubocop-thread_safety
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
97
153
  - !ruby/object:Gem::Dependency
98
154
  name: simplecov
99
155
  requirement: !ruby/object:Gem::Requirement
100
156
  requirements:
101
- - - "~>"
157
+ - - ">="
102
158
  - !ruby/object:Gem::Version
103
- version: '0.17'
159
+ version: '0'
104
160
  type: :development
105
161
  prerelease: false
106
162
  version_requirements: !ruby/object:Gem::Requirement
107
163
  requirements:
108
- - - "~>"
164
+ - - ">="
109
165
  - !ruby/object:Gem::Version
110
- version: '0.17'
166
+ version: '0'
111
167
  - !ruby/object:Gem::Dependency
112
168
  name: yard
113
169
  requirement: !ruby/object:Gem::Requirement
114
170
  requirements:
115
- - - "~>"
171
+ - - ">="
116
172
  - !ruby/object:Gem::Version
117
- version: '0.9'
173
+ version: '0'
118
174
  type: :development
119
175
  prerelease: false
120
176
  version_requirements: !ruby/object:Gem::Requirement
121
177
  requirements:
122
- - - "~>"
178
+ - - ">="
123
179
  - !ruby/object:Gem::Version
124
- version: '0.9'
180
+ version: '0'
125
181
  description: Specing framework for Ruby.
126
182
  email: contact@cyril.email
127
183
  executables: []
@@ -131,16 +187,19 @@ files:
131
187
  - LICENSE.md
132
188
  - README.md
133
189
  - lib/fix.rb
134
- - lib/fix/context.rb
135
- - lib/fix/expectation_result_not_found_error.rb
136
- - lib/fix/it.rb
137
- - lib/fix/suspicious_success_error.rb
190
+ - lib/fix/console.rb
191
+ - lib/fix/doc.rb
192
+ - lib/fix/dsl.rb
193
+ - lib/fix/test.rb
138
194
  - lib/kernel.rb
139
195
  homepage: https://fixrb.dev/
140
196
  licenses:
141
197
  - MIT
142
198
  metadata:
199
+ bug_tracker_uri: https://github.com/fixrb/fix/issues
200
+ documentation_uri: https://rubydoc.info/gems/r_spec-clone
143
201
  source_code_uri: https://github.com/fixrb/fix
202
+ wiki_uri: https://github.com/fixrb/fix/wiki
144
203
  post_install_message:
145
204
  rdoc_options: []
146
205
  require_paths:
@@ -149,14 +208,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
149
208
  requirements:
150
209
  - - ">="
151
210
  - !ruby/object:Gem::Version
152
- version: 2.3.0
211
+ version: 2.7.0
153
212
  required_rubygems_version: !ruby/object:Gem::Requirement
154
213
  requirements:
155
214
  - - ">"
156
215
  - !ruby/object:Gem::Version
157
216
  version: 1.3.1
158
217
  requirements: []
159
- rubygems_version: 3.1.2
218
+ rubygems_version: 3.1.6
160
219
  signing_key:
161
220
  specification_version: 4
162
221
  summary: Specing framework for Ruby.
data/lib/fix/context.rb DELETED
@@ -1,160 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'aw'
4
- require 'defi'
5
-
6
- module Fix
7
- # Wraps the target of challenge.
8
- class Context
9
- RESERVED_KEYWORDS = %i[
10
- alias
11
- and
12
- begin
13
- break
14
- case
15
- catch
16
- class
17
- def
18
- defined?
19
- do
20
- else
21
- elsif
22
- end
23
- ensure
24
- fail
25
- false
26
- for
27
- if
28
- in
29
- module
30
- next
31
- nil
32
- not
33
- or
34
- raise
35
- redo
36
- rescue
37
- retry
38
- return
39
- self
40
- super
41
- then
42
- throw
43
- true
44
- undef
45
- unless
46
- until
47
- when
48
- while
49
- yield
50
- ].freeze
51
-
52
- attr_reader :callable
53
-
54
- def initialize(subject, challenge, before_hooks_counter = 0, *hooks, **lets)
55
- @subject = subject
56
- @callable = challenge.to(subject)
57
- @before_hooks = hooks[0, before_hooks_counter]
58
- @after_hooks = hooks[before_hooks_counter..-1]
59
- @lets = lets
60
- end
61
-
62
- def before(&block)
63
- @before_hooks << block
64
- end
65
-
66
- def after(&block)
67
- @after_hooks << block
68
- end
69
-
70
- def let(name, &block)
71
- raise ::TypeError, "expected a Symbol, got #{name.class}" unless name.is_a?(::Symbol)
72
- raise ::NameError, "wrong method name `#{name}'" unless name.match(/\A[a-z][a-z0-9_]+[?!]?\z/)
73
- raise ::NameError, "reserved keyword name `#{name}'" if RESERVED_KEYWORDS.include?(name)
74
- raise ::NameError, "reserved method name `#{name}'" if respond_to?(name, true) && !@lets.key?(name)
75
-
76
- @lets.update(name => block.call)
77
- rescue ::SystemExit => e
78
- raise SuspiciousSuccessError, "attempt `#{name}' to bypass the tests" if e.success?
79
- raise e
80
- end
81
-
82
- def let!(name, &block)
83
- raise ::TypeError, "expected a Symbol, got #{name.class}" unless name.is_a?(::Symbol)
84
- raise ::NameError, "wrong method name `#{name}'" unless name.match(/\A[a-z][a-z0-9_]+[?!]?\z/)
85
- raise ::NameError, "reserved keyword name `#{name}'" if RESERVED_KEYWORDS.include?(name)
86
- raise ::NameError, "reserved method name `#{name}'" if respond_to?(name, true) && !@lets.key?(name)
87
-
88
- @lets.update(name => ::Aw.fork! { block.call })
89
- rescue ::SystemExit => e
90
- raise SuspiciousSuccessError, "attempt `#{name}' to bypass the tests" if e.success?
91
- raise e
92
- end
93
-
94
- # Verify the expectation.
95
- #
96
- # @param block [Proc] A spec to compare against the computed actual value.
97
- #
98
- # @return [::Spectus::Result::Pass, ::Spectus::Result::Fail] Pass or fail.
99
- def it(_message = nil, &block)
100
- print "#{block.source_location.join(':')}: "
101
- i = It.new(callable, **@lets)
102
- @before_hooks.each { |hook| i.instance_eval(&hook) }
103
- result = i.instance_eval(&block)
104
- puts result.colored_string
105
- rescue ::Spectus::Result::Fail => result
106
- abort result.colored_string
107
- ensure
108
- @after_hooks.each { |hook| i.instance_eval(&hook) }
109
- raise ExpectationResultNotFoundError, result.class.inspect unless result.is_a?(::Spectus::Result::Common)
110
- end
111
-
112
- def its(name, *args, **options, &block)
113
- if callable.raised?
114
- actual = callable
115
- challenge = ::Defi.send(:call)
116
- else
117
- actual = callable.object
118
- challenge = ::Defi.send(name, *args, **options)
119
- end
120
-
121
- o = Context.new(actual, challenge, @before_hooks.length, *@before_hooks + @after_hooks, **@lets)
122
- o.it(&block)
123
- end
124
-
125
- def on(name, *args, **options, &block)
126
- if callable.raised?
127
- actual = callable
128
- challenge = ::Defi.send(:call)
129
- else
130
- actual = callable.object
131
- challenge = ::Defi.send(name, *args, **options)
132
- end
133
-
134
- o = Context.new(actual, challenge, @before_hooks.length, *@before_hooks + @after_hooks, **@lets)
135
- o.instance_eval(&block)
136
- end
137
-
138
- def with(_message = nil, **new_lets, &block)
139
- actual = callable.object
140
- challenge = ::Defi.send(:itself)
141
-
142
- c = Context.new(actual, challenge, @before_hooks.length, *@before_hooks + @after_hooks, **@lets.merge(new_lets))
143
- c.instance_eval(&block)
144
- end
145
-
146
- private
147
-
148
- def method_missing(name, *args, &block)
149
- @lets.fetch(name) { super }
150
- end
151
-
152
- def respond_to_missing?(name, include_private = false)
153
- @lets.key?(name) || super
154
- end
155
- end
156
- end
157
-
158
- require_relative 'it'
159
- require_relative 'expectation_result_not_found_error'
160
- require_relative 'suspicious_success_error'
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Fix
4
- class ExpectationResultNotFoundError < ::RuntimeError; end
5
- end
data/lib/fix/it.rb DELETED
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spectus/expectation_target'
4
- require 'matchi/helper'
5
-
6
- module Fix
7
- # Wraps the target of an expectation.
8
- class It < ::Spectus::ExpectationTarget
9
- include ::Matchi::Helper
10
-
11
- # Create a new expection target
12
- #
13
- # @param callable [#call] The object to test.
14
- def initialize(callable, **lets)
15
- raise unless callable.respond_to?(:call)
16
-
17
- @callable = callable
18
- @lets = lets
19
- end
20
-
21
- private
22
-
23
- def method_missing(name, *args, &block)
24
- @lets.fetch(name) { super }
25
- end
26
-
27
- def respond_to_missing?(name, include_private = false)
28
- @lets.key?(name) || super
29
- end
30
- end
31
- end
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Fix
4
- class SuspiciousSuccessError < ::StandardError; end
5
- end