axiom-types 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +5 -13
  2. data/.rubocop.yml +6 -0
  3. data/.travis.yml +11 -8
  4. data/Gemfile +4 -0
  5. data/Gemfile.devtools +27 -13
  6. data/axiom-types.gemspec +6 -3
  7. data/config/flay.yml +1 -1
  8. data/config/flog.yml +1 -1
  9. data/config/reek.yml +10 -3
  10. data/config/rubocop.yml +10 -9
  11. data/lib/axiom/types.rb +5 -3
  12. data/lib/axiom/types/encodable.rb +4 -5
  13. data/lib/axiom/types/length_comparable.rb +12 -5
  14. data/lib/axiom/types/numeric.rb +2 -2
  15. data/lib/axiom/types/object.rb +9 -0
  16. data/lib/axiom/types/support/infinity.rb +31 -48
  17. data/lib/axiom/types/support/options.rb +1 -1
  18. data/lib/axiom/types/type.rb +27 -0
  19. data/lib/axiom/types/value_comparable.rb +11 -6
  20. data/lib/axiom/types/version.rb +1 -1
  21. data/spec/unit/axiom/types/class_methods/finalize_spec.rb +1 -1
  22. data/spec/unit/axiom/types/encodable/class_methods/extended_spec.rb +1 -1
  23. data/spec/unit/axiom/types/encodable/finalize_spec.rb +1 -1
  24. data/spec/unit/axiom/types/infinity/{class_methods/coerce_spec.rb → coerce_spec.rb} +5 -5
  25. data/spec/unit/axiom/types/infinity/{class_methods/spaceship_operator_spec.rb → spaceship_operator_spec.rb} +3 -3
  26. data/spec/unit/axiom/types/infinity/{class_methods/succ_spec.rb → succ_spec.rb} +2 -2
  27. data/spec/unit/axiom/types/length_comparable/class_methods/extended_spec.rb +5 -3
  28. data/spec/unit/axiom/types/length_comparable/finalize_spec.rb +1 -0
  29. data/spec/unit/axiom/types/length_comparable/range_spec.rb +25 -0
  30. data/spec/unit/axiom/types/negative_infinity/{class_methods/spaceship_operator_spec.rb → spaceship_operator_spec.rb} +3 -3
  31. data/spec/unit/axiom/types/object/class_methods/inspect_spec.rb +11 -0
  32. data/spec/unit/axiom/types/options/inherited_spec.rb +1 -1
  33. data/spec/unit/axiom/types/type/class_methods/anonymous_predicate_spec.rb +19 -0
  34. data/spec/unit/axiom/types/type/class_methods/base_predicate_spec.rb +19 -0
  35. data/spec/unit/axiom/types/type/class_methods/base_spec.rb +19 -0
  36. data/spec/unit/axiom/types/type/class_methods/includes_spec.rb +2 -2
  37. data/spec/unit/axiom/types/value_comparable/class_methods/extended_spec.rb +1 -1
  38. data/spec/unit/axiom/types/value_comparable/finalize_spec.rb +1 -0
  39. data/spec/unit/axiom/types/value_comparable/range_spec.rb +25 -0
  40. metadata +51 -24
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- OTk1ZjkwNjg3MjZkNzIwNmI5Yzc4YmNlMTQ5NjNlNDhkNWI5Y2EyZg==
5
- data.tar.gz: !binary |-
6
- NTllNTE2NWUzNDUwNGJlODJmODk2NzBiZmM1YmIwYWZlNGM3YzZjNw==
2
+ SHA1:
3
+ metadata.gz: c3f4ab34cb8059c83c6512f6f7e3eaf4516583db
4
+ data.tar.gz: 3b75505765e6c9efe0bedb546350affe457d1419
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- YjJkYjk1OWQ1MmQ5NjVkZWU4Y2FhZjVlY2VlZGFhNzMzYWE3MWZkMjc0MGY4
10
- YmQzYjNiYmIzOGYzMzdjYzUwOTg5NmU5ZTBlN2ZjYjg3MWMxMWYzNTE4ZjA3
11
- ZTQ0ZGI3N2YyM2ZjZGQ4MmQ2ZTA2ZTgwMTA3NmNiZjcxMTYyMTQ=
12
- data.tar.gz: !binary |-
13
- MGQwZmUxMDZhNjhjYWFhNTQ0NjY0ODQ2OGJmMDAwMzI0M2UwMDQ0ODg4OGRm
14
- MzA0ZTkxYjZjNWJkYjMyNjBhZmFkMzE2Yzc4YjA4Zjk0ODI0OGQ3OTcwNjBh
15
- OTIzZGRhODBjZjdlOWJjYTY2YTViYTVkMzY3ZmEyOThmMGU1YTE=
6
+ metadata.gz: f4ae3db9a977137f1d50f696f4c88846b0d9754f6cb34809f1d4772d9aa4f4f32a970a626902df4997873f4b1f059f4e9c2b9eb8988d81ac82f027ecf610d8c6
7
+ data.tar.gz: 913fea68aa5f22cf384e142710ddfeb7f53470f50a85d850d37192c5560902724ffb4c44e80d2cfdac8722ac50656cbb5c928690a27d0a2966b7a33f3fc603f5
@@ -0,0 +1,6 @@
1
+ AllCops:
2
+ Includes:
3
+ - 'Gemfile'
4
+ Excludes:
5
+ - 'Gemfile.devtools'
6
+ - 'vendor/**'
@@ -1,23 +1,26 @@
1
1
  language: ruby
2
2
  before_install: gem install bundler
3
3
  bundler_args: --without yard guard benchmarks
4
- script: "bundle exec rake ci"
4
+ script: "bundle exec rake ci:metrics"
5
5
  rvm:
6
6
  - 1.9.3
7
7
  - 2.0.0
8
+ - 2.1.0
8
9
  - ruby-head
9
- - rbx-19mode
10
+ - rbx
10
11
  matrix:
11
12
  include:
12
13
  - rvm: jruby-19mode
13
- env: JRUBY_OPTS="$JRUBY_OPTS --debug"
14
+ env: JRUBY_OPTS="$JRUBY_OPTS --debug" # for simplecov
15
+ - rvm: jruby-20mode
16
+ env: JRUBY_OPTS="$JRUBY_OPTS --debug" # for simplecov
17
+ - rvm: jruby-21mode
18
+ env: JRUBY_OPTS="$JRUBY_OPTS --debug" # for simplecov
14
19
  - rvm: jruby-head
15
- env: JRUBY_OPTS="$JRUBY_OPTS --debug"
20
+ env: JRUBY_OPTS="$JRUBY_OPTS --debug" # for simplecov
16
21
  allow_failures:
17
- - rvm: 1.9.3 # mutant fails
18
- - rvm: 2.0.0 # mutant fails
19
- - rvm: ruby-head # travis broken
20
- - rvm: rbx-19mode # mutant fails
22
+ - rvm: 2.1.0 # buggy runtime
23
+ fast_finish: true
21
24
  notifications:
22
25
  irc:
23
26
  channels:
data/Gemfile CHANGED
@@ -4,6 +4,10 @@ source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
6
 
7
+ platforms :rbx do
8
+ gem 'rubysl-bigdecimal', '~> 2.0.2'
9
+ end
10
+
7
11
  group :development, :test do
8
12
  gem 'devtools', git: 'https://github.com/rom-rb/devtools.git'
9
13
  end
@@ -4,21 +4,24 @@ group :development do
4
4
  gem 'rake', '~> 10.1.0'
5
5
  gem 'rspec', '~> 2.14.1'
6
6
  gem 'yard', '~> 0.8.7'
7
+
8
+ platform :rbx do
9
+ gem 'rubysl-singleton', '~> 2.0.0'
10
+ end
7
11
  end
8
12
 
9
13
  group :yard do
10
- gem 'kramdown', '~> 1.2.0'
14
+ gem 'kramdown', '~> 1.3.0'
11
15
  end
12
16
 
13
17
  group :guard do
14
- gem 'guard', '~> 1.8.1'
15
- gem 'guard-bundler', '~> 1.0.0'
16
- gem 'guard-rspec', '~> 3.0.2'
17
- gem 'guard-rubocop', '~> 0.2.0'
18
- gem 'guard-mutant', '~> 0.0.1'
18
+ gem 'guard', '~> 2.3.0'
19
+ gem 'guard-bundler', '~> 2.0.0'
20
+ gem 'guard-rspec', '~> 4.2.0'
21
+ gem 'guard-rubocop', '~> 1.0.0'
19
22
 
20
23
  # file system change event handling
21
- gem 'listen', '~> 1.3.0'
24
+ gem 'listen', '~> 2.4.0'
22
25
  gem 'rb-fchange', '~> 0.0.6', require: false
23
26
  gem 'rb-fsevent', '~> 0.9.3', require: false
24
27
  gem 'rb-inotify', '~> 0.9.0', require: false
@@ -30,18 +33,29 @@ group :guard do
30
33
  end
31
34
 
32
35
  group :metrics do
33
- gem 'coveralls', '~> 0.6.7'
36
+ gem 'coveralls', '~> 0.7.0'
34
37
  gem 'flay', '~> 2.4.0'
35
- gem 'flog', '~> 4.1.1'
38
+ gem 'flog', '~> 4.2.0'
36
39
  gem 'reek', '~> 1.3.2'
37
- gem 'rubocop', '~> 0.13.0'
38
- gem 'simplecov', '~> 0.7.1'
39
- gem 'yardstick', '~> 0.9.7', git: 'https://github.com/dkubb/yardstick.git'
40
+ gem 'rubocop', '~> 0.16.0'
41
+ gem 'simplecov', '~> 0.8.2'
42
+ gem 'yardstick', '~> 0.9.9'
43
+
44
+ platforms :mri do
45
+ gem 'mutant', '~> 0.3.4'
46
+ end
40
47
 
41
48
  platforms :ruby_19, :ruby_20 do
42
- gem 'mutant', git: 'https://github.com/mbj/mutant.git'
43
49
  gem 'yard-spellcheck', '~> 0.1.5'
44
50
  end
51
+
52
+ platform :rbx do
53
+ gem 'json', '~> 1.8.1'
54
+ gem 'racc', '~> 1.4'
55
+ gem 'rubysl-logger', '~> 2.0.0'
56
+ gem 'rubysl-open-uri', '~> 2.0.0'
57
+ gem 'rubysl-prettyprint', '~> 2.0.2'
58
+ end
45
59
  end
46
60
 
47
61
  group :benchmarks do
@@ -17,8 +17,11 @@ Gem::Specification.new do |gem|
17
17
  gem.test_files = `git ls-files -- spec/unit`.split($/)
18
18
  gem.extra_rdoc_files = %w[LICENSE README.md CONTRIBUTING.md TODO]
19
19
 
20
- gem.add_dependency('descendants_tracker', '~> 0.0.1')
21
- gem.add_dependency('ice_nine', '~> 0.9')
20
+ gem.required_ruby_version = '>= 1.9.3'
22
21
 
23
- gem.add_development_dependency('bundler', '~> 1.3', '>= 1.3.5')
22
+ gem.add_runtime_dependency('descendants_tracker', '~> 0.0.3')
23
+ gem.add_runtime_dependency('ice_nine', '~> 0.11.0')
24
+ gem.add_runtime_dependency('thread_safe', '~> 0.1.3')
25
+
26
+ gem.add_development_dependency('bundler', '~> 1.5', '>= 1.5.2')
24
27
  end
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 19
3
- total_score: 162
3
+ total_score: 175
@@ -1,2 +1,2 @@
1
1
  ---
2
- threshold: 10.0
2
+ threshold: 11.4
@@ -1,7 +1,9 @@
1
1
  ---
2
2
  Attribute:
3
3
  enabled: true
4
- exclude: []
4
+ exclude:
5
+ - Axiom::Types::LengthComparable
6
+ - Axiom::Types::ValueComparable
5
7
  BooleanParameter:
6
8
  enabled: true
7
9
  exclude: []
@@ -10,7 +12,12 @@ ClassVariable:
10
12
  exclude: []
11
13
  ControlParameter:
12
14
  enabled: true
13
- exclude: []
15
+ exclude:
16
+ - Axiom::Types::Boolean#self.infer_from_primitive_class
17
+ - Axiom::Types::Collection#self.infer_from
18
+ - Axiom::Types::Infinity#<=>
19
+ - Axiom::Types::Object#self.infer_from_primitive_class
20
+ - Axiom::Types::Type#self.infer
14
21
  DataClump:
15
22
  enabled: true
16
23
  exclude: []
@@ -63,7 +70,7 @@ TooManyInstanceVariables:
63
70
  TooManyMethods:
64
71
  enabled: true
65
72
  exclude: []
66
- max_methods: 0
73
+ max_methods: 4
67
74
  TooManyStatements:
68
75
  enabled: true
69
76
  exclude:
@@ -1,11 +1,4 @@
1
- AllCops:
2
- Includes:
3
- - '../**/*.rake'
4
- - 'Gemfile'
5
- - 'Gemfile.devtools'
6
- Excludes:
7
- - '**/vendor/**'
8
- - '**/benchmarks/**'
1
+ inherit_from: ../.rubocop.yml
9
2
 
10
3
  # Avoid parameter lists longer than five parameters.
11
4
  ParameterLists:
@@ -30,7 +23,7 @@ CollectionMethods:
30
23
  # sections of code and visually separate them. When the keyword is at the same
31
24
  # level I think it sort of blends in with the def keywords and makes it harder
32
25
  # to scan the code and see where the sections are.
33
- AccessControl:
26
+ AccessModifierIndentation:
34
27
  Enabled: false
35
28
 
36
29
  # Limit line length
@@ -60,3 +53,11 @@ ConstantName:
60
53
  # Not all trivial readers/writers can be defined with attr_* methods
61
54
  TrivialAccessors:
62
55
  Enabled: false
56
+
57
+ # The #<=> method argument has an underscore because it is not referenced
58
+ OpMethod:
59
+ Enabled: false
60
+
61
+ # Allow empty lines around body
62
+ EmptyLinesAroundBody:
63
+ Enabled: false
@@ -3,9 +3,11 @@
3
3
  require 'bigdecimal'
4
4
  require 'date'
5
5
  require 'set'
6
+ require 'singleton'
6
7
 
7
- require 'ice_nine'
8
8
  require 'descendants_tracker'
9
+ require 'ice_nine'
10
+ require 'thread_safe'
9
11
 
10
12
  module Axiom
11
13
 
@@ -22,7 +24,7 @@ module Axiom
22
24
  Contradiction = ->(_value) { true }.freeze
23
25
 
24
26
  # Cache the type inference lookup by object
25
- @inference_cache = Hash.new do |cache, object|
27
+ @inference_cache = ThreadSafe::Cache.new do |cache, object|
26
28
  type = nil
27
29
  Type.descendants.detect do |descendant|
28
30
  type = descendant.infer(object)
@@ -61,8 +63,8 @@ module Axiom
61
63
  end # module Types
62
64
  end # module Axiom
63
65
 
64
- require 'axiom/types/support/infinity'
65
66
  require 'axiom/types/support/options'
67
+ require 'axiom/types/support/infinity'
66
68
 
67
69
  require 'axiom/types/value_comparable'
68
70
  require 'axiom/types/length_comparable'
@@ -34,7 +34,7 @@ module Axiom
34
34
  # @api private
35
35
  def finalize
36
36
  return self if frozen?
37
- ascii_compatible? ? has_ascii_compatible_encoding : has_encoding
37
+ ascii_compatible? ? use_ascii_compatible_encoding : use_encoding
38
38
  super
39
39
  end
40
40
 
@@ -54,7 +54,7 @@ module Axiom
54
54
  # @return [undefined]
55
55
  #
56
56
  # @api private
57
- def has_ascii_compatible_encoding
57
+ def use_ascii_compatible_encoding
58
58
  constraint do |object|
59
59
  object.encoding.equal?(encoding) || object.to_s.ascii_only?
60
60
  end
@@ -65,11 +65,10 @@ module Axiom
65
65
  # @return [undefined]
66
66
  #
67
67
  # @api private
68
- def has_encoding
68
+ def use_encoding
69
69
  constraint { |object| object.encoding.equal?(encoding) }
70
70
  end
71
71
 
72
- end
73
-
72
+ end # module Encodable
74
73
  end # module Types
75
74
  end # module Axiom
@@ -6,6 +6,13 @@ module Axiom
6
6
  # Add a minimum and maximum length constraint to a type
7
7
  module LengthComparable
8
8
 
9
+ # The range of allowed lengths
10
+ #
11
+ # @return [Range]
12
+ #
13
+ # @api public
14
+ attr_reader :range
15
+
9
16
  # Hook called when module is extended
10
17
  #
11
18
  # Add #minimum_length and #maximum_length DSL methods to descendant.
@@ -19,8 +26,8 @@ module Axiom
19
26
  super
20
27
  descendant.class_eval do
21
28
  accept_options :minimum_length, :maximum_length
22
- minimum_length Infinity
23
- maximum_length NegativeInfinity
29
+ minimum_length Infinity.instance
30
+ maximum_length NegativeInfinity.instance
24
31
  end
25
32
  end
26
33
 
@@ -31,7 +38,8 @@ module Axiom
31
38
  # @api private
32
39
  def finalize
33
40
  return self if frozen?
34
- has_length_within_range
41
+ @range = IceNine.deep_freeze(minimum_length..maximum_length)
42
+ use_length_within_range
35
43
  super
36
44
  end
37
45
 
@@ -44,8 +52,7 @@ module Axiom
44
52
  # @todo freeze the minimum_length and maximum_length
45
53
  #
46
54
  # @api private
47
- def has_length_within_range
48
- range = minimum_length..maximum_length
55
+ def use_length_within_range
49
56
  constraint { |object| range.cover?(object.length) }
50
57
  end
51
58
 
@@ -10,8 +10,8 @@ module Axiom
10
10
  primitive ::Numeric
11
11
  coercion_method :to_numeric
12
12
 
13
- minimum NegativeInfinity
14
- maximum Infinity
13
+ minimum NegativeInfinity.instance
14
+ maximum Infinity.instance
15
15
 
16
16
  end # class Numeric
17
17
  end # module Types
@@ -37,6 +37,15 @@ module Axiom
37
37
  super
38
38
  end
39
39
 
40
+ # The type name and primitive
41
+ #
42
+ # @return [String]
43
+ #
44
+ # @api public
45
+ def self.inspect
46
+ "#{base} (#{primitive})"
47
+ end
48
+
40
49
  # Infer the type if the primitive class matches
41
50
  #
42
51
  # @param [Object] object
@@ -4,8 +4,13 @@ module Axiom
4
4
  module Types
5
5
 
6
6
  # Represent an infinite number
7
- class Infinity < BasicObject
8
- extend ::Comparable
7
+ class Infinity
8
+ extend Options, DescendantsTracker
9
+ include ::Comparable, ::Singleton
10
+
11
+ accept_options :inverse, :number
12
+
13
+ number ::Float::INFINITY
9
14
 
10
15
  # Test the number against infinity
11
16
  #
@@ -17,64 +22,57 @@ module Axiom
17
22
  # returned if the other object is something other than infinity
18
23
  #
19
24
  # @api private
20
- def self.<=>(other)
25
+ def <=>(other)
26
+ klass = self.class
21
27
  case other
22
- when ::BigDecimal then 1
23
- when ->(arg) { arg == number } then 0
24
- when ::Numeric, inverse.singleton_class then 1
28
+ when BigDecimal then 1
29
+ when ->(arg) { arg == klass.number } then 0
30
+ when ::Numeric, klass.inverse then 1
25
31
  end
26
32
  end
27
33
 
28
- # Coerce a number into an Infinity class for comparison
34
+ # Coerce a number into an Infinity instance for comparison
29
35
  #
30
36
  # @param [::Numeric] other
31
37
  #
32
38
  # @return [Array(Infinity, Infinity)]
33
39
  #
34
40
  # @api private
35
- def self.coerce(other)
41
+ def coerce(other)
36
42
  case other
37
- when ::BigDecimal then [inverse, self]
38
- when number then [self, self]
39
- when ::Numeric then [inverse, self]
43
+ when BigDecimal then [inverse, self]
44
+ when self.class.number then [self, self]
45
+ when ::Numeric then [inverse, self]
40
46
  else
41
- raise ::TypeError, "#{other.class} cannot be coerced"
47
+ fail TypeError, "#{other.class} cannot be coerced"
42
48
  end
43
49
  end
44
50
 
45
51
  # Return the next successive object, which is always self
46
52
  #
47
- # @return [Class<Infinity>]
53
+ # @return [Infinity]
48
54
  #
49
55
  # @api private
50
- def self.succ
56
+ def succ
51
57
  self
52
58
  end
53
59
 
54
- # The inverse of infinity
55
- #
56
- # @return [Class<NegativeInfinity>]
57
- #
58
- # @api private
59
- def self.inverse
60
- NegativeInfinity
61
- end
62
- private_class_method :inverse
60
+ private
63
61
 
64
- # The numeric representation of infinity
62
+ # The inverse instance
65
63
  #
66
- # @return [Float]
64
+ # @return [Infinity]
67
65
  #
68
66
  # @api private
69
- def self.number
70
- ::Float::INFINITY
67
+ def inverse
68
+ self.class.inverse.instance
71
69
  end
72
- private_class_method :number
73
70
 
74
71
  end # class Infinity
75
72
 
76
73
  # Represent a negative infinite number
77
74
  class NegativeInfinity < Infinity
75
+ number(-::Float::INFINITY)
78
76
 
79
77
  # Test the number against negative infinity
80
78
  #
@@ -86,31 +84,16 @@ module Axiom
86
84
  # returned if the other object is not negative infinity
87
85
  #
88
86
  # @api private
89
- def self.<=>(_other)
87
+ def <=>(_other)
90
88
  comparison = super
91
89
  -comparison if comparison
92
90
  end
93
91
 
94
- # The inverse of negative infinity
95
- #
96
- # @return [Class<Infinity>]
97
- #
98
- # @api private
99
- def self.inverse
100
- Infinity
101
- end
102
- private_class_method :inverse
92
+ end # class NegativeInfinity
103
93
 
104
- # The numeric representation of negative infinity
105
- #
106
- # @return [Float]
107
- #
108
- # @api private
109
- def self.number
110
- -::Float::INFINITY
111
- end
112
- private_class_method :number
94
+ # Define inverse classes
95
+ Infinity.inverse NegativeInfinity
96
+ NegativeInfinity.inverse Infinity
113
97
 
114
- end # class NegativeInfinity
115
98
  end # module Types
116
99
  end # module Axiom
@@ -105,7 +105,7 @@ module Axiom
105
105
  # @api private
106
106
  def assert_method_available(name)
107
107
  return unless respond_to?(name)
108
- raise(
108
+ fail(
109
109
  ReservedMethodError,
110
110
  "method named `#{name.inspect}` is already defined"
111
111
  )
@@ -131,6 +131,33 @@ module Axiom
131
131
  constraint(&set.method(:include?))
132
132
  end
133
133
 
134
+ # The base type for the type
135
+ #
136
+ # @return [Class<Axiom::Types::Type>]
137
+ #
138
+ # @api public
139
+ def self.base
140
+ base? ? self : superclass.base
141
+ end
142
+
143
+ # Test if the type is a base type
144
+ #
145
+ # @return [Boolean]
146
+ #
147
+ # @api public
148
+ def self.base?
149
+ !anonymous?
150
+ end
151
+
152
+ # Test if the type is anonymous
153
+ #
154
+ # @return [Boolean]
155
+ #
156
+ # @api public
157
+ def self.anonymous?
158
+ name.to_s.empty?
159
+ end
160
+
134
161
  # Add new constraint to existing constraint, if any
135
162
  #
136
163
  # @param [#call] constraint
@@ -6,6 +6,13 @@ module Axiom
6
6
  # Add a minimum and maximum value constraint to a type
7
7
  module ValueComparable
8
8
 
9
+ # The range of allowed values
10
+ #
11
+ # @return [Range]
12
+ #
13
+ # @api public
14
+ attr_reader :range
15
+
9
16
  # Hook called when module is extended
10
17
  #
11
18
  # Add #minimum and #maximum DSL methods to descendant.
@@ -17,9 +24,7 @@ module Axiom
17
24
  # @api private
18
25
  def self.extended(descendant)
19
26
  super
20
- descendant.class_eval do
21
- accept_options :minimum, :maximum
22
- end
27
+ descendant.accept_options :minimum, :maximum
23
28
  end
24
29
 
25
30
  # Finalize by setting up a value range constraint
@@ -29,7 +34,8 @@ module Axiom
29
34
  # @api private
30
35
  def finalize
31
36
  return self if frozen?
32
- has_value_within_range
37
+ @range = IceNine.deep_freeze(minimum..maximum)
38
+ use_value_within_range
33
39
  super
34
40
  end
35
41
 
@@ -42,8 +48,7 @@ module Axiom
42
48
  # @todo freeze the minimum and maximum
43
49
  #
44
50
  # @api private
45
- def has_value_within_range
46
- range = minimum..maximum
51
+ def use_value_within_range
47
52
  constraint(range.method(:cover?))
48
53
  end
49
54
 
@@ -4,7 +4,7 @@ module Axiom
4
4
  module Types
5
5
 
6
6
  # Gem version
7
- VERSION = '0.0.5'.freeze
7
+ VERSION = '0.1.0'.freeze
8
8
 
9
9
  end # module Types
10
10
  end # module Axiom
@@ -11,7 +11,7 @@ describe Axiom::Types, '.finalize' do
11
11
  it_should_behave_like 'a command method'
12
12
 
13
13
  it 'finalizes the descendants' do
14
- descendant.should_receive(:finalize)
14
+ expect(descendant).to receive(:finalize)
15
15
  subject
16
16
  end
17
17
  end
@@ -13,7 +13,7 @@ describe Axiom::Types::Encodable, '.extended' do
13
13
  # RSpec tracks the original method (if any), then we add our own stub that
14
14
  # actually works, and finally when the example finishes RSpec will reset
15
15
  # the Module#extended method back to it's original state.
16
- Module.any_instance.stub(:extended).with(object)
16
+ allow_any_instance_of(Module).to receive(:extended).with(object)
17
17
 
18
18
  delegated_ancestor = false
19
19
  Module.send(:undef_method, :extended)
@@ -9,7 +9,7 @@ describe Axiom::Types::Encodable, '#finalize' do
9
9
 
10
10
  # Test if Symbol encoding is supported
11
11
  let(:symbol_encoding) do
12
- ! RUBY_PLATFORM.include?('java') && begin
12
+ !RUBY_PLATFORM.include?('java') && begin
13
13
  encoding = Encoding::UTF_32BE
14
14
  ''.force_encoding(encoding).to_sym.encoding.equal?(encoding)
15
15
  end
@@ -2,10 +2,10 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Axiom::Types::Infinity, '.coerce' do
5
+ describe Axiom::Types::Infinity, '#coerce' do
6
6
  subject { object.coerce(other) }
7
7
 
8
- let(:object) { described_class }
8
+ let(:object) { described_class.instance }
9
9
 
10
10
  [
11
11
  1, # Fixnum
@@ -18,7 +18,7 @@ describe Axiom::Types::Infinity, '.coerce' do
18
18
  let(:other) { number }
19
19
 
20
20
  it 'coerces into an array containing inverse and self' do
21
- should eql([Axiom::Types::NegativeInfinity, object])
21
+ should eql([Axiom::Types::NegativeInfinity.instance, object])
22
22
  end
23
23
 
24
24
  it 'coerces when comparing' do
@@ -32,7 +32,7 @@ describe Axiom::Types::Infinity, '.coerce' do
32
32
  let(:other) { Float::INFINITY }
33
33
 
34
34
  it 'coerces into an array containing inverse and self' do
35
- should eql([Axiom::Types::Infinity, object])
35
+ should eql([Axiom::Types::Infinity.instance, object])
36
36
  end
37
37
 
38
38
  it 'coerces when comparing' do
@@ -45,7 +45,7 @@ describe Axiom::Types::Infinity, '.coerce' do
45
45
  let(:other) { -Float::INFINITY }
46
46
 
47
47
  it 'coerces into an array containing inverse and self' do
48
- should eql([Axiom::Types::NegativeInfinity, object])
48
+ should eql([Axiom::Types::NegativeInfinity.instance, object])
49
49
  end
50
50
 
51
51
  it 'coerces when comparing' do
@@ -2,10 +2,10 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Axiom::Types::Infinity, '.<=>' do
5
+ describe Axiom::Types::Infinity, '#<=>' do
6
6
  subject { object <=> other }
7
7
 
8
- let(:object) { described_class }
8
+ let(:object) { described_class.instance }
9
9
 
10
10
  [
11
11
  1, # Fixnum
@@ -26,7 +26,7 @@ describe Axiom::Types::Infinity, '.<=>' do
26
26
  end
27
27
 
28
28
  context 'when the other object is negative infinity' do
29
- let(:other) { Axiom::Types::NegativeInfinity }
29
+ let(:other) { Axiom::Types::NegativeInfinity.instance }
30
30
 
31
31
  it { should be(1) }
32
32
 
@@ -2,10 +2,10 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Axiom::Types::Infinity, '.succ' do
5
+ describe Axiom::Types::Infinity, '#succ' do
6
6
  subject { object.succ }
7
7
 
8
- let(:object) { described_class }
8
+ let(:object) { described_class.instance }
9
9
 
10
10
  it { should be(object) }
11
11
  end
@@ -13,7 +13,7 @@ describe Axiom::Types::LengthComparable, '.extended' do
13
13
  # RSpec tracks the original method (if any), then we add our own stub that
14
14
  # actually works, and finally when the example finishes RSpec will reset
15
15
  # the Module#extended method back to it's original state.
16
- Module.any_instance.stub(:extended).with(object)
16
+ allow_any_instance_of(Module).to receive(:extended).with(object)
17
17
 
18
18
  delegated_ancestor = false
19
19
  Module.send(:undef_method, :extended)
@@ -32,10 +32,12 @@ describe Axiom::Types::LengthComparable, '.extended' do
32
32
  end
33
33
 
34
34
  it 'sets the default minimum_length' do
35
- expect(subject.minimum_length).to equal(Axiom::Types::Infinity)
35
+ expect(subject.minimum_length)
36
+ .to equal(Axiom::Types::Infinity.instance)
36
37
  end
37
38
 
38
39
  it 'sets the default maximum_length' do
39
- expect(subject.maximum_length).to equal(Axiom::Types::NegativeInfinity)
40
+ expect(subject.maximum_length)
41
+ .to equal(Axiom::Types::NegativeInfinity.instance)
40
42
  end
41
43
  end
@@ -18,6 +18,7 @@ describe Axiom::Types::LengthComparable, '#finalize' do
18
18
 
19
19
  it { should be_frozen }
20
20
 
21
+ its(:range) { should be_frozen }
21
22
  its(:constraint) { should be_frozen }
22
23
 
23
24
  it 'adds a constraint that returns true for a length within range' do
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Axiom::Types::LengthComparable, '#range' do
6
+ subject { object.range }
7
+
8
+ let(:object) do
9
+ Class.new(Axiom::Types::Type) do
10
+ extend Axiom::Types::LengthComparable
11
+ minimum_length 1
12
+ maximum_length 2
13
+ end
14
+ end
15
+
16
+ before do
17
+ object.finalize
18
+ end
19
+
20
+ it_should_behave_like 'an idempotent method'
21
+
22
+ it { should be_frozen }
23
+
24
+ it { should eql(1..2) }
25
+ end
@@ -2,10 +2,10 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Axiom::Types::NegativeInfinity, '.<=>' do
5
+ describe Axiom::Types::NegativeInfinity, '#<=>' do
6
6
  subject { object <=> other }
7
7
 
8
- let(:object) { described_class }
8
+ let(:object) { described_class.instance }
9
9
 
10
10
  [
11
11
  1, # Fixnum
@@ -26,7 +26,7 @@ describe Axiom::Types::NegativeInfinity, '.<=>' do
26
26
  end
27
27
 
28
28
  context 'when the other object is infinity' do
29
- let(:other) { Axiom::Types::Infinity }
29
+ let(:other) { Axiom::Types::Infinity.instance }
30
30
 
31
31
  it { should be(-1) }
32
32
 
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Axiom::Types::Object, '.inspect' do
6
+ subject { object.inspect }
7
+
8
+ let(:object) { described_class }
9
+
10
+ it { should eql("Axiom::Types::Object (#{object.primitive})") }
11
+ end
@@ -22,7 +22,7 @@ describe Axiom::Types::Options, '#inherited' do
22
22
  end
23
23
 
24
24
  it 'delegates to the ancestor' do
25
- ancestor.should_receive(:inherited).twice
25
+ expect(ancestor).to receive(:inherited).twice
26
26
  subject
27
27
  end
28
28
 
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Axiom::Types::Type, '.anonymous?' do
6
+ subject { object.anonymous? }
7
+
8
+ context 'when the type is named' do
9
+ let(:object) { described_class }
10
+
11
+ it { should be(false) }
12
+ end
13
+
14
+ context 'when the type is anonymous' do
15
+ let(:object) { Class.new(described_class) }
16
+
17
+ it { should be(true) }
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Axiom::Types::Type, '.base?' do
6
+ subject { object.base? }
7
+
8
+ context 'when the type is named' do
9
+ let(:object) { described_class }
10
+
11
+ it { should be(true) }
12
+ end
13
+
14
+ context 'when the type is anonymous' do
15
+ let(:object) { Class.new(described_class) }
16
+
17
+ it { should be(false) }
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Axiom::Types::Type, '.base' do
6
+ subject { object.base }
7
+
8
+ context 'when the type is named' do
9
+ let(:object) { described_class }
10
+
11
+ it { should be(object) }
12
+ end
13
+
14
+ context 'when the type is anonymous' do
15
+ let(:object) { Class.new(Class.new(described_class)) }
16
+
17
+ it { should be(described_class) }
18
+ end
19
+ end
@@ -26,8 +26,8 @@ describe Axiom::Types::Type, '.includes' do
26
26
  end
27
27
 
28
28
  it 'removes duplicate members' do
29
- member.should_receive(:frozen?).and_return(true)
30
- member.should_receive(:hash).exactly(3).times.and_return(1)
29
+ expect(member).to receive(:freeze).and_return(member)
30
+ expect(member).to receive(:hash).exactly(3).times.and_return(1)
31
31
  subject
32
32
  expect(object).to include(member)
33
33
  end
@@ -13,7 +13,7 @@ describe Axiom::Types::ValueComparable, '.extended' do
13
13
  # RSpec tracks the original method (if any), then we add our own stub that
14
14
  # actually works, and finally when the example finishes RSpec will reset
15
15
  # the Module#extended method back to it's original state.
16
- Module.any_instance.stub(:extended).with(object)
16
+ allow_any_instance_of(Module).to receive(:extended).with(object)
17
17
 
18
18
  delegated_ancestor = false
19
19
  Module.send(:undef_method, :extended)
@@ -18,6 +18,7 @@ describe Axiom::Types::ValueComparable, '#finalize' do
18
18
 
19
19
  it { should be_frozen }
20
20
 
21
+ its(:range) { should be_frozen }
21
22
  its(:constraint) { should be_frozen }
22
23
 
23
24
  it 'adds a constraint that returns true for a value within range' do
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Axiom::Types::ValueComparable, '#range' do
6
+ subject { object.range }
7
+
8
+ let(:object) do
9
+ Class.new(Axiom::Types::Type) do
10
+ extend Axiom::Types::ValueComparable
11
+ minimum 1
12
+ maximum 2
13
+ end
14
+ end
15
+
16
+ before do
17
+ object.finalize
18
+ end
19
+
20
+ it_should_behave_like 'an idempotent method'
21
+
22
+ it { should be_frozen }
23
+
24
+ it { should eql(1..2) }
25
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: axiom-types
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Kubb
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-06 00:00:00.000000000 Z
11
+ date: 2014-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: descendants_tracker
@@ -16,48 +16,62 @@ dependencies:
16
16
  requirements:
17
17
  - - ~>
18
18
  - !ruby/object:Gem::Version
19
- version: 0.0.1
19
+ version: 0.0.3
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: 0.0.1
26
+ version: 0.0.3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: ice_nine
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ~>
32
32
  - !ruby/object:Gem::Version
33
- version: '0.9'
33
+ version: 0.11.0
34
34
  type: :runtime
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: '0.9'
40
+ version: 0.11.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: thread_safe
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.1.3
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.1.3
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: '1.3'
48
- - - ! '>='
61
+ version: '1.5'
62
+ - - '>='
49
63
  - !ruby/object:Gem::Version
50
- version: 1.3.5
64
+ version: 1.5.2
51
65
  type: :development
52
66
  prerelease: false
53
67
  version_requirements: !ruby/object:Gem::Requirement
54
68
  requirements:
55
69
  - - ~>
56
70
  - !ruby/object:Gem::Version
57
- version: '1.3'
58
- - - ! '>='
71
+ version: '1.5'
72
+ - - '>='
59
73
  - !ruby/object:Gem::Version
60
- version: 1.3.5
74
+ version: 1.5.2
61
75
  description: Abstract types for logic programming
62
76
  email: dan.kubb@gmail.com
63
77
  executables: []
@@ -70,6 +84,7 @@ extra_rdoc_files:
70
84
  files:
71
85
  - .gitignore
72
86
  - .rspec
87
+ - .rubocop.yml
73
88
  - .ruby-gemset
74
89
  - .travis.yml
75
90
  - .yardopts
@@ -126,19 +141,24 @@ files:
126
141
  - spec/unit/axiom/types/encodable/finalize_spec.rb
127
142
  - spec/unit/axiom/types/hash/class_methods/finalize_spec.rb
128
143
  - spec/unit/axiom/types/hash/class_methods/infer_spec.rb
129
- - spec/unit/axiom/types/infinity/class_methods/coerce_spec.rb
130
- - spec/unit/axiom/types/infinity/class_methods/spaceship_operator_spec.rb
131
- - spec/unit/axiom/types/infinity/class_methods/succ_spec.rb
144
+ - spec/unit/axiom/types/infinity/coerce_spec.rb
145
+ - spec/unit/axiom/types/infinity/spaceship_operator_spec.rb
146
+ - spec/unit/axiom/types/infinity/succ_spec.rb
132
147
  - spec/unit/axiom/types/length_comparable/class_methods/extended_spec.rb
133
148
  - spec/unit/axiom/types/length_comparable/finalize_spec.rb
134
- - spec/unit/axiom/types/negative_infinity/class_methods/spaceship_operator_spec.rb
149
+ - spec/unit/axiom/types/length_comparable/range_spec.rb
150
+ - spec/unit/axiom/types/negative_infinity/spaceship_operator_spec.rb
135
151
  - spec/unit/axiom/types/object/class_methods/coercion_method_spec.rb
136
152
  - spec/unit/axiom/types/object/class_methods/finalize_spec.rb
137
153
  - spec/unit/axiom/types/object/class_methods/infer_spec.rb
154
+ - spec/unit/axiom/types/object/class_methods/inspect_spec.rb
138
155
  - spec/unit/axiom/types/object/class_methods/primitive_spec.rb
139
156
  - spec/unit/axiom/types/options/accept_options_spec.rb
140
157
  - spec/unit/axiom/types/options/inherited_spec.rb
141
158
  - spec/unit/axiom/types/set/class_methods/infer_spec.rb
159
+ - spec/unit/axiom/types/type/class_methods/anonymous_predicate_spec.rb
160
+ - spec/unit/axiom/types/type/class_methods/base_predicate_spec.rb
161
+ - spec/unit/axiom/types/type/class_methods/base_spec.rb
142
162
  - spec/unit/axiom/types/type/class_methods/constraint_spec.rb
143
163
  - spec/unit/axiom/types/type/class_methods/finalize_spec.rb
144
164
  - spec/unit/axiom/types/type/class_methods/include_predicate_spec.rb
@@ -147,6 +167,7 @@ files:
147
167
  - spec/unit/axiom/types/type/class_methods/new_spec.rb
148
168
  - spec/unit/axiom/types/value_comparable/class_methods/extended_spec.rb
149
169
  - spec/unit/axiom/types/value_comparable/finalize_spec.rb
170
+ - spec/unit/axiom/types/value_comparable/range_spec.rb
150
171
  homepage: https://github.com/dkubb/axiom-types
151
172
  licenses:
152
173
  - MIT
@@ -157,17 +178,17 @@ require_paths:
157
178
  - lib
158
179
  required_ruby_version: !ruby/object:Gem::Requirement
159
180
  requirements:
160
- - - ! '>='
181
+ - - '>='
161
182
  - !ruby/object:Gem::Version
162
- version: '0'
183
+ version: 1.9.3
163
184
  required_rubygems_version: !ruby/object:Gem::Requirement
164
185
  requirements:
165
- - - ! '>='
186
+ - - '>='
166
187
  - !ruby/object:Gem::Version
167
188
  version: '0'
168
189
  requirements: []
169
190
  rubyforge_project:
170
- rubygems_version: 2.1.1
191
+ rubygems_version: 2.1.11
171
192
  signing_key:
172
193
  specification_version: 4
173
194
  summary: Define types with optional constraints for use within axiom and other libraries.
@@ -182,19 +203,24 @@ test_files:
182
203
  - spec/unit/axiom/types/encodable/finalize_spec.rb
183
204
  - spec/unit/axiom/types/hash/class_methods/finalize_spec.rb
184
205
  - spec/unit/axiom/types/hash/class_methods/infer_spec.rb
185
- - spec/unit/axiom/types/infinity/class_methods/coerce_spec.rb
186
- - spec/unit/axiom/types/infinity/class_methods/spaceship_operator_spec.rb
187
- - spec/unit/axiom/types/infinity/class_methods/succ_spec.rb
206
+ - spec/unit/axiom/types/infinity/coerce_spec.rb
207
+ - spec/unit/axiom/types/infinity/spaceship_operator_spec.rb
208
+ - spec/unit/axiom/types/infinity/succ_spec.rb
188
209
  - spec/unit/axiom/types/length_comparable/class_methods/extended_spec.rb
189
210
  - spec/unit/axiom/types/length_comparable/finalize_spec.rb
190
- - spec/unit/axiom/types/negative_infinity/class_methods/spaceship_operator_spec.rb
211
+ - spec/unit/axiom/types/length_comparable/range_spec.rb
212
+ - spec/unit/axiom/types/negative_infinity/spaceship_operator_spec.rb
191
213
  - spec/unit/axiom/types/object/class_methods/coercion_method_spec.rb
192
214
  - spec/unit/axiom/types/object/class_methods/finalize_spec.rb
193
215
  - spec/unit/axiom/types/object/class_methods/infer_spec.rb
216
+ - spec/unit/axiom/types/object/class_methods/inspect_spec.rb
194
217
  - spec/unit/axiom/types/object/class_methods/primitive_spec.rb
195
218
  - spec/unit/axiom/types/options/accept_options_spec.rb
196
219
  - spec/unit/axiom/types/options/inherited_spec.rb
197
220
  - spec/unit/axiom/types/set/class_methods/infer_spec.rb
221
+ - spec/unit/axiom/types/type/class_methods/anonymous_predicate_spec.rb
222
+ - spec/unit/axiom/types/type/class_methods/base_predicate_spec.rb
223
+ - spec/unit/axiom/types/type/class_methods/base_spec.rb
198
224
  - spec/unit/axiom/types/type/class_methods/constraint_spec.rb
199
225
  - spec/unit/axiom/types/type/class_methods/finalize_spec.rb
200
226
  - spec/unit/axiom/types/type/class_methods/include_predicate_spec.rb
@@ -203,4 +229,5 @@ test_files:
203
229
  - spec/unit/axiom/types/type/class_methods/new_spec.rb
204
230
  - spec/unit/axiom/types/value_comparable/class_methods/extended_spec.rb
205
231
  - spec/unit/axiom/types/value_comparable/finalize_spec.rb
232
+ - spec/unit/axiom/types/value_comparable/range_spec.rb
206
233
  has_rdoc: