hanami-utils 0.8.0 → 0.9.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
  SHA1:
3
- metadata.gz: e0ec07bde18ad072abdc5ba80712ccf9976d4139
4
- data.tar.gz: 98916abdaf10d4a18848745fe00ba6b497a3e521
3
+ metadata.gz: 93e8362df57ad7209539ecd8383ee1f1b60ea68e
4
+ data.tar.gz: 854db004fcc6912bef61404d58feda11e6589d2e
5
5
  SHA512:
6
- metadata.gz: 459b2bcf58fd4416d95421ed9d0af9995096caef9a32975a51ca69ebd771a8ba4352935f76f26702a1c248a7af256c01e0683101410800f02808761da548eaf7
7
- data.tar.gz: 475a12099d5f21b95ccc7965571351e98f8b6eb55a46343952483eac7fdb3cb3f51daaa6818b99c5e991696caeda3a2bcb3910c078deb64e14a82e91f7612f0c
6
+ metadata.gz: f30cb4ccc8c96a99808534957ec785f8036cd1baf9362bca8e9f8f15cfad044406c5bb34820b6c6b64faf4cc20e3cbd6ef36e08193754adf2c6980ef9a6f5862
7
+ data.tar.gz: 734d3c0994e2ccba6e9176c497c17c8093693da2b434dbd2476383128a57f83819c7f63382ba39a22057cbd6b72361dd6ec9e51a4989d0c5d070d3c2837f7b1c
@@ -1,6 +1,20 @@
1
1
  # Hanami::Utils
2
2
  Ruby core extentions and class utilities for Hanami
3
3
 
4
+ ## v0.9.0 - 2016-11-15
5
+ ### Added
6
+ – [Luca Guidi] Introduced `Utils.require!` to recursively require Ruby files with an order that is consistent across platforms
7
+ – [Luca Guidi] Introduced `Utils::FileList` as cross-platform ordered list of files, alternative to `Dir.glob`
8
+ - [Luca Guidi] Make `Utils::BasicObject` pretty printable
9
+ - [Grachev Mikhail] Added `Interactor::Result#successful?` and `#failing?`
10
+
11
+ ### Fixed
12
+ - [Pascal Betz] Ensure `Utils::Class.load!` to lookup constant only within the given namespace
13
+
14
+ ### Changed
15
+ - [Luca Guidi] Make `Utils::Hash` only compatible with objects that respond to `#to_hash`
16
+ - [Luca Guidi] Official support for Ruby: MRI 2.3+ and JRuby 9.1.5.0+
17
+
4
18
  ## v0.8.0 - 2016-07-22
5
19
  ### Added
6
20
  - [Andrey Morskov] Introduced `Hanami::Utils::Blank`
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Hanami::Utils
2
2
 
3
- Ruby core extentions and class utilities for [Hanami](http://hanamirb.org)
3
+ Ruby core extensions and class utilities for [Hanami](http://hanamirb.org)
4
4
 
5
5
  ## Status
6
6
 
@@ -22,7 +22,7 @@ Ruby core extentions and class utilities for [Hanami](http://hanamirb.org)
22
22
 
23
23
  ## Rubies
24
24
 
25
- __Hanami::Utils__ supports Ruby (MRI) 2.2+, JRuby 9.0.5.0+
25
+ __Hanami::Utils__ supports Ruby (MRI) 2.3+, JRuby 9.1.5.0+
26
26
 
27
27
  ## Installation
28
28
 
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
- spec.required_ruby_version = '>= 2.2.0'
20
+ spec.required_ruby_version = '>= 2.3.0'
21
21
 
22
22
  spec.add_development_dependency 'bundler', '~> 1.6'
23
23
  spec.add_development_dependency 'rake', '~> 11'
@@ -17,7 +17,14 @@ module Hanami
17
17
  # @api private
18
18
  #
19
19
  # @see Hanami::Interactor::Result#respond_to_missing?
20
- METHODS = ::Hash[initialize: true, success?: true, fail!: true, prepare!: true, errors: true, error: true].freeze
20
+ METHODS = ::Hash[initialize: true,
21
+ success?: true,
22
+ successful?: true,
23
+ failing?: true,
24
+ fail!: true,
25
+ prepare!: true,
26
+ errors: true,
27
+ error: true].freeze
21
28
 
22
29
  # Initialize a new result
23
30
  #
@@ -37,11 +44,23 @@ module Hanami
37
44
  #
38
45
  # @return [TrueClass,FalseClass] the result of the check
39
46
  #
40
- # @since 0.3.5
41
- def success?
47
+ # @since 0.8.1
48
+ def successful?
42
49
  @success && errors.empty?
43
50
  end
44
51
 
52
+ # @since 0.3.5
53
+ alias success? successful?
54
+
55
+ # Check if the current status is not successful
56
+ #
57
+ # @return [TrueClass,FalseClass] the result of the check
58
+ #
59
+ # @since 0.8.1
60
+ def failing?
61
+ !successful?
62
+ end
63
+
45
64
  # Force the status to be a failure
46
65
  #
47
66
  # @since 0.3.5
@@ -202,7 +221,8 @@ module Hanami
202
221
  # end
203
222
  #
204
223
  # result = Signup.new(name: 'Luca').call
205
- # result.success? # => true
224
+ # result.failing? # => false
225
+ # result.successful? # => true
206
226
  #
207
227
  # result.user # => #<User:0x007fa311105778 @id=1 @name="Luca">
208
228
  # result.params # => { :name=>"Luca" }
@@ -232,7 +252,8 @@ module Hanami
232
252
  # end
233
253
  #
234
254
  # result = Signup.new(name: nil).call
235
- # result.success? # => false
255
+ # result.successful? # => false
256
+ # result.failing? # => true
236
257
  #
237
258
  # result.user # => #<User:0x007fa311105778 @id=nil @name="Luca">
238
259
  #
@@ -299,7 +320,7 @@ module Hanami
299
320
  # end
300
321
  #
301
322
  # result = CreateEmailTest.new(account_id: 1).call
302
- # result.success? # => false
323
+ # result.successful? # => false
303
324
  def fail!
304
325
  @__result.fail!
305
326
  throw :fail
@@ -351,7 +372,7 @@ module Hanami
351
372
  # end
352
373
  #
353
374
  # result = CreateRecord.new.call
354
- # result.success? # => false
375
+ # result.successful? # => false
355
376
  #
356
377
  # result.errors # => ["Prepare data error", "Persist error"]
357
378
  # result.logger # => [:prepare_data!, :persist!, :sync!]
@@ -405,7 +426,7 @@ module Hanami
405
426
  # end
406
427
  #
407
428
  # result = CreateRecord.new.call
408
- # result.success? # => false
429
+ # result.successful? # => false
409
430
  #
410
431
  # result.errors # => ["Prepare data error", "Persist error"]
411
432
  # result.logger # => [:prepare_data!, :persist!]
@@ -1,6 +1,10 @@
1
- require 'hanami/utils/version'
2
-
1
+ # Hanami - The web, with simplicity
2
+ #
3
+ # @since 0.1.0
3
4
  module Hanami
5
+ require 'hanami/utils/version'
6
+ require 'hanami/utils/file_list'
7
+
4
8
  # Ruby core extentions and Hanami utilities
5
9
  #
6
10
  # @since 0.1.0
@@ -32,5 +36,24 @@ module Hanami
32
36
  def self.rubinius?
33
37
  RUBY_ENGINE == HANAMI_RUBINIUS
34
38
  end
39
+
40
+ # Recursively require Ruby files under the given directory.
41
+ #
42
+ # If the directory is relative, it implies it's the path from current directory.
43
+ # If the directory is absolute, it uses as it is.
44
+ #
45
+ # It respects file separator of the current operating system.
46
+ # A pattern like <tt>"path/to/files"</tt> will work both on *NIX and Windows machines.
47
+ #
48
+ # @param directory [String, Pathname] the directory
49
+ #
50
+ # @since 0.9.0
51
+ def self.require!(directory)
52
+ directory = directory.to_s.gsub(%r{(\/|\\)}, File::SEPARATOR)
53
+ directory = Pathname.new(Dir.pwd).join(directory).to_s
54
+ directory = File.join(directory, '**', '*.rb') unless directory =~ /(\*\*)/
55
+
56
+ FileList[directory].each { |file| require_relative file }
57
+ end
35
58
  end
36
59
  end
@@ -24,6 +24,28 @@ module Hanami
24
24
  "#<#{self.class}:#{'%x' % (__id__ << 1)}#{__inspect}>" # rubocop:disable Style/FormatString
25
25
  end
26
26
 
27
+ # Alias for __id__
28
+ #
29
+ # @return [Fixnum] the object id
30
+ #
31
+ # @since 0.9.0
32
+ #
33
+ # @see http://ruby-doc.org/core/Object.html#method-i-object_id
34
+ def object_id
35
+ __id__
36
+ end
37
+
38
+ # Interface for <tt>pp</pp>
39
+ #
40
+ # @return [String] the pretty printable inspection of the object
41
+ #
42
+ # @since 0.9.0
43
+ #
44
+ # @see https://ruby-doc.org/stdlib/libdoc/pp/rdoc/PP.html
45
+ def pretty_print(*)
46
+ inspect
47
+ end
48
+
27
49
  # Returns true if responds to the given method.
28
50
  #
29
51
  # @return [TrueClass,FalseClass] the result of the check
@@ -37,7 +37,7 @@ module Hanami
37
37
  when FalseClass, NilClass
38
38
  true
39
39
  else
40
- object.respond_to?(:empty?) ? !!object.empty? : !self
40
+ object.respond_to?(:empty?) ? object.empty? : !self
41
41
  end
42
42
  end
43
43
  end
@@ -38,7 +38,7 @@ module Hanami
38
38
  # # with missing constant
39
39
  # Hanami::Utils::Class.load!('Unknown') # => raises NameError
40
40
  def self.load!(name, namespace = Object)
41
- namespace.const_get(name.to_s)
41
+ namespace.const_get(name.to_s, false)
42
42
  end
43
43
 
44
44
  # Loads a class for the given name, only if it's defined.
@@ -69,7 +69,7 @@ module Hanami
69
69
  # # with explicit namespace
70
70
  # Hanami::Utils::Class.load('Service', App) # => App::Service
71
71
  def self.load(name, namespace = Object)
72
- load!(name, namespace) if namespace.const_defined?(name.to_s)
72
+ load!(name, namespace) if namespace.const_defined?(name.to_s, false)
73
73
  end
74
74
 
75
75
  # Loads a class from the given pattern name and namespace
@@ -112,7 +112,7 @@ module Hanami
112
112
  def self.load_from_pattern!(pattern, namespace = Object)
113
113
  String.new(pattern).tokenize do |token|
114
114
  begin
115
- return namespace.const_get(token)
115
+ return namespace.const_get(token, false)
116
116
  rescue NameError # rubocop:disable Lint/HandleExceptions
117
117
  end
118
118
  end
@@ -0,0 +1,20 @@
1
+ module Hanami
2
+ module Utils
3
+ # Ordered file list, consistent across operating systems
4
+ #
5
+ # @since 0.9.0
6
+ module FileList
7
+ # Return an ordered list of files, consistent across operating systems
8
+ #
9
+ # It has the same signature of <tt>Dir.glob</tt>, it just guarantees to
10
+ # order the results before to return them.
11
+ #
12
+ # @since 0.9.0
13
+ #
14
+ # @see https://ruby-doc.org/core/Dir.html#method-c-glob
15
+ def self.[](*args)
16
+ Dir.glob(*args).sort!
17
+ end
18
+ end
19
+ end
20
+ end
@@ -44,7 +44,7 @@ module Hanami
44
44
  #
45
45
  # hash.to_h # => { 'foo' => ['bar'] }
46
46
  def initialize(hash = {}, &blk)
47
- @hash = hash.to_h
47
+ @hash = hash.to_hash
48
48
  @hash.default_proc = blk
49
49
  end
50
50
 
@@ -65,7 +65,7 @@ module Hanami
65
65
  def symbolize!
66
66
  keys.each do |k|
67
67
  v = delete(k)
68
- v = self.class.new(v).symbolize! if v.is_a?(::Hash) || v.is_a?(self.class)
68
+ v = self.class.new(v).symbolize! if v.respond_to?(:to_hash)
69
69
 
70
70
  self[k.to_sym] = v
71
71
  end
@@ -90,7 +90,7 @@ module Hanami
90
90
  def stringify!
91
91
  keys.each do |k|
92
92
  v = delete(k)
93
- v = self.class.new(v).stringify! if v.is_a?(::Hash) || v.is_a?(self.class)
93
+ v = self.class.new(v).stringify! if v.respond_to?(:to_hash)
94
94
 
95
95
  self[k.to_s] = v
96
96
  end
@@ -224,7 +224,7 @@ module Hanami
224
224
  # @see http://www.ruby-doc.org/core/Hash.html#method-i-to_h
225
225
  def to_h
226
226
  @hash.each_with_object({}) do |(k, v), result|
227
- v = v.to_h if v.is_a?(self.class)
227
+ v = v.to_h if v.respond_to?(:to_hash)
228
228
  result[k] = v
229
229
  end
230
230
  end
@@ -278,13 +278,11 @@ module Hanami
278
278
  #
279
279
  # @raise [NoMethodError] If doesn't respond to the given method
280
280
  def method_missing(m, *args, &blk)
281
- if respond_to?(m)
282
- h = @hash.__send__(m, *args, &blk)
283
- h = self.class.new(h) if h.is_a?(::Hash)
284
- h
285
- else
286
- raise NoMethodError.new(%(undefined method `#{m}' for #{@hash}:#{self.class}))
287
- end
281
+ raise NoMethodError.new(%(undefined method `#{m}' for #{@hash}:#{self.class})) unless respond_to?(m)
282
+
283
+ h = @hash.__send__(m, *args, &blk)
284
+ h = self.class.new(h) if h.is_a?(::Hash)
285
+ h
288
286
  end
289
287
 
290
288
  # Override Ruby's respond_to_missing? in order to support ::Hash interface
@@ -10,8 +10,10 @@ require 'hanami/utils/string'
10
10
  # in coercions DSLs
11
11
  #
12
12
  # @since 0.3.0
13
- class Boolean
14
- end unless defined?(Boolean)
13
+ unless defined?(Boolean)
14
+ class Boolean
15
+ end
16
+ end
15
17
 
16
18
  module Hanami
17
19
  module Utils
@@ -110,7 +110,7 @@ module Hanami
110
110
  # paths = Hanami::Utils::LoadPaths.new
111
111
  # paths << '.' << '../..'
112
112
  def push(*paths)
113
- @paths.push(*paths) # rubocop:disable Performance/PushSplat
113
+ @paths.push(*paths)
114
114
  @paths = Kernel.Array(@paths)
115
115
  self
116
116
  end
@@ -399,13 +399,11 @@ module Hanami
399
399
  #
400
400
  # @raise [NoMethodError] If doesn't respond to the given method
401
401
  def method_missing(m, *args, &blk)
402
- if respond_to?(m)
403
- s = @string.__send__(m, *args, &blk)
404
- s = self.class.new(s) if s.is_a?(::String)
405
- s
406
- else
407
- raise NoMethodError.new(%(undefined method `#{m}' for "#{@string}":#{self.class}))
408
- end
402
+ raise NoMethodError.new(%(undefined method `#{m}' for "#{@string}":#{self.class})) unless respond_to?(m)
403
+
404
+ s = @string.__send__(m, *args, &blk)
405
+ s = self.class.new(s) if s.is_a?(::String)
406
+ s
409
407
  end
410
408
 
411
409
  # Override Ruby's respond_to_missing? in order to support ::String interface
@@ -3,6 +3,6 @@ module Hanami
3
3
  # Defines the version
4
4
  #
5
5
  # @since 0.1.0
6
- VERSION = '0.8.0'.freeze
6
+ VERSION = '0.9.0'.freeze
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-07-22 00:00:00.000000000 Z
13
+ date: 2016-11-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -66,6 +66,7 @@ files:
66
66
  - lib/hanami/utils/deprecation.rb
67
67
  - lib/hanami/utils/duplicable.rb
68
68
  - lib/hanami/utils/escape.rb
69
+ - lib/hanami/utils/file_list.rb
69
70
  - lib/hanami/utils/hash.rb
70
71
  - lib/hanami/utils/inflector.rb
71
72
  - lib/hanami/utils/io.rb
@@ -87,7 +88,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
87
88
  requirements:
88
89
  - - ">="
89
90
  - !ruby/object:Gem::Version
90
- version: 2.2.0
91
+ version: 2.3.0
91
92
  required_rubygems_version: !ruby/object:Gem::Requirement
92
93
  requirements:
93
94
  - - ">="