mumukit-core 1.13.0 → 1.18.0

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: 4f1171e9bc75ea6096afe03f8a30b15c32efafa0abbd2aef71f5ba96a32da23f
4
- data.tar.gz: fad237169e5d66e359d831f3abe2456d42e82d2765ca821ebca8a4078357afc2
3
+ metadata.gz: 194cf145fd0c4c23370ed1e13c5c57bd0547ae1a471f70dd528b7da057f95493
4
+ data.tar.gz: 96378e2042dddcb61e19f120b1c7450b46bee8883a33d4431548eff2b5171281
5
5
  SHA512:
6
- metadata.gz: 201065bf24ae05cc63f5bd631d7949a188a9f7fdcc87fce7516375b7e9e0403d007fb274d3add8561119a73efb1d10628df75eae308e679b389de692beb38251
7
- data.tar.gz: e45109ef518aa076021c23a3d04bb619b6934f6c5a05c6485373691ba88686ef07e6e99294bda722257cd26a3088a0ba30ca6ebf2ad8cd83b8b487e79b815c75
6
+ metadata.gz: 0ee16a6494525dda508e7f625783669430462ef7af1fcb998632f80e3c1bb06dd15170251087850fd4bca30bfadce31db3b7bd5daf79518a43e7c992ff9c502f
7
+ data.tar.gz: 0d41784422345397e3fe753a2ea8e9639874549af9de5918008b6c36dc035591a86f0997b523645531a74597fc75460256e451e7621175b83152cc60ad8a47d2
@@ -3,12 +3,28 @@ require 'active_support/all'
3
3
 
4
4
  module Mumukit
5
5
  module Core
6
+ class << self
7
+ def test_mode!
8
+ Class.class_eval do
9
+ break if method_defined? :__mumukit_core_contract_new__
10
+ alias_method :__mumukit_core_contract_new__, :new
11
+
12
+ def new(*args, &block)
13
+ validate_complies_with_contract!
14
+ __mumukit_core_contract_new__(*args, &block)
15
+ end
16
+ end
17
+ end
18
+ end
6
19
  end
7
20
  end
8
21
 
22
+ Mumukit::Core.test_mode! if %w(RACK_ENV RAILS_ENV).any? { |it| ENV[it] == 'test' }
23
+
9
24
  require_relative './core/status'
10
25
  require_relative './core/object'
11
26
  require_relative './core/module'
27
+ require_relative './core/class'
12
28
  require_relative './core/json'
13
29
  require_relative './core/hash'
14
30
  require_relative './core/string'
@@ -7,13 +7,9 @@ class Array
7
7
  end
8
8
  end
9
9
 
10
- def to_h
11
- Hash[self]
12
- end
13
-
14
10
  def to_csv
15
11
  CSV.generate do |csv|
16
12
  each { |hash| csv << hash.values }
17
13
  end
18
14
  end
19
- end
15
+ end
@@ -0,0 +1,8 @@
1
+ class Class
2
+ class ContractBreachError < Exception
3
+ end
4
+
5
+ def validate_complies_with_contract!
6
+ raise ContractBreachError.new "class #{name} does not implement contract #{contract_breaches}!" if breaches_contract?
7
+ end
8
+ end
@@ -6,11 +6,113 @@ class Module
6
6
  end
7
7
  end
8
8
 
9
- def patch(method_name, &block)
10
- method_proc = instance_method method_name
9
+ # Redefines a previous definition of the given method.
10
+ # It takes a block with the original arguments and the `hyper`
11
+ # reference to the original definition
12
+ def patch(selector, &block)
13
+ revamp selector do |_, this, *args, hyper|
14
+ this.instance_exec(*args, hyper, &block)
15
+ end
16
+ end
17
+
18
+ # `revamp` is a `patch` generalization
19
+ # that accepts multiple selectors and
20
+ # takes a more general callback, like the following:
21
+ #
22
+ # ```
23
+ # revamp :foo, :bar do |selector, this, *args, hyper|
24
+ # puts "sending #{selector} to #{this}..."
25
+ # result = hyper.call(*args)
26
+ # puts "done. result is #{result}"
27
+ # result
28
+ # end
29
+ # ```
30
+ #
31
+ # `revamp` should be preferred to `patch` when more control or performance
32
+ # is required
33
+ def revamp(*selectors, selector_transformer: nil, &block)
34
+ selectors.each do |selector|
35
+ method_proc = instance_method selector
36
+ selector_transform = selector_transformer ? selector_transformer.call(selector) : selector
37
+
38
+ define_method selector do |*args|
39
+ block.call(selector_transform, self, *args, method_proc.bind(self))
40
+ end
41
+ end
42
+ end
11
43
 
12
- define_method method_name do |*args|
13
- instance_exec(*args, method_proc.bind(self), &block)
44
+ # Revamps an accessor. This method is similar to `revamp`,
45
+ # but:
46
+ #
47
+ # * assumes a 0 arguments array
48
+ # * takes the accessor's original result instead of the `hyper` reference
49
+ #
50
+ # As a consequence, `revamp_accessor` can not alter the way and the moment
51
+ # the original method is evaluated.
52
+ #
53
+ # ```
54
+ # revamp_accessor :foo, :bar do |selector, this, result|
55
+ # puts "result of sending #{selector} to #{this} is #{result}"
56
+ # result
57
+ # end
58
+ # ```
59
+ #
60
+ # :warning: the block will not be called on a `nil` result
61
+ def revamp_accessor(*selectors, &block)
62
+ revamp(*selectors) do |selector, this, hyper|
63
+ result = hyper.call
64
+ result && block.call(selector, this, result)
14
65
  end
15
66
  end
67
+
68
+ # Caches an accessor, using the idiom `@__foo__ ||= foo`. For example, the following code:
69
+ #
70
+ # ```
71
+ # def foo
72
+ # @__foo__ ||= #...implementation...
73
+ # end
74
+ # ```
75
+ #
76
+ # Can be turned into:
77
+ #
78
+ # ```
79
+ # def foo
80
+ # #...implementation...
81
+ # end
82
+ #
83
+ # cache_accessor :foo
84
+ # ```
85
+ #
86
+ def cache_accessor(*selectors)
87
+ revamp(*selectors, selector_transformer: proc { |it| "@__#{it}__".to_sym }) do |attr_name, this, hyper|
88
+ this.instance_variable_get(attr_name) || this.instance_variable_set(attr_name, hyper.call)
89
+ end
90
+ end
91
+
92
+ def rewrite(selector, &block)
93
+ raise "method #{selector} was not previously defined here" unless method_defined?(selector)
94
+ define_method selector, &block
95
+ end
96
+
97
+ def contract
98
+ @contract ||= []
99
+ end
100
+
101
+ attr_writer :contract
102
+
103
+ def implements(*selectors)
104
+ self.contract += selectors
105
+ end
106
+
107
+ def full_contract
108
+ ancestors.flat_map(&:contract).uniq
109
+ end
110
+
111
+ def breaches_contract?
112
+ !contract_breaches.empty?
113
+ end
114
+
115
+ def contract_breaches
116
+ full_contract.reject { |it| method_defined? it }
117
+ end
16
118
  end
@@ -19,4 +19,8 @@ class Object
19
19
  def struct(hash = {})
20
20
  hash.to_struct
21
21
  end
22
+
23
+ def filled?
24
+ self == false || present?
25
+ end
22
26
  end
@@ -1,4 +1,4 @@
1
- [:passed, :passed_with_warnings, :failed, :errored, :aborted].each do |sym|
1
+ [:passed, :passed_with_warnings, :failed, :errored, :aborted, :skipped].each do |sym|
2
2
  s = sym.to_s.freeze
3
3
  selector = "#{s}?"
4
4
  NilClass.class_eval do
@@ -1,5 +1,5 @@
1
1
  module Mumukit
2
2
  module Core
3
- VERSION = '1.13.0'
3
+ VERSION = '1.18.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mumukit-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.13.0
4
+ version: 1.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Franco Leonardo Bulgarelli
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-24 00:00:00.000000000 Z
11
+ date: 2020-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.7'
19
+ version: '2.0'
20
20
  type: :development
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: '1.7'
26
+ version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '12.3'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '12.3'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '2'
47
+ version: '3.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '2'
54
+ version: '3.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: codeclimate-test-reporter
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -148,6 +148,7 @@ files:
148
148
  - lib/mumukit/core.rb
149
149
  - lib/mumukit/core/activemodel.rb
150
150
  - lib/mumukit/core/array.rb
151
+ - lib/mumukit/core/class.rb
151
152
  - lib/mumukit/core/configurable.rb
152
153
  - lib/mumukit/core/file.rb
153
154
  - lib/mumukit/core/hash.rb
@@ -186,8 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
187
  - !ruby/object:Gem::Version
187
188
  version: '0'
188
189
  requirements: []
189
- rubyforge_project:
190
- rubygems_version: 2.7.8
190
+ rubygems_version: 3.0.8
191
191
  signing_key:
192
192
  specification_version: 4
193
193
  summary: Ruby core extensions for mumuki on top of active support