axiom-types 0.0.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.
Files changed (63) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +37 -0
  3. data/.rspec +4 -0
  4. data/.rvmrc +1 -0
  5. data/.travis.yml +35 -0
  6. data/.yardopts +4 -0
  7. data/Gemfile +10 -0
  8. data/Gemfile.devtools +62 -0
  9. data/Guardfile +24 -0
  10. data/LICENSE +20 -0
  11. data/README.md +76 -0
  12. data/Rakefile +6 -0
  13. data/TODO +25 -0
  14. data/axiom-types.gemspec +26 -0
  15. data/config/flay.yml +3 -0
  16. data/config/flog.yml +2 -0
  17. data/config/mutant.yml +3 -0
  18. data/config/reek.yml +100 -0
  19. data/config/roodi.yml +16 -0
  20. data/config/yardstick.yml +2 -0
  21. data/lib/axiom-types.rb +3 -0
  22. data/lib/axiom/types.rb +65 -0
  23. data/lib/axiom/types/array.rb +13 -0
  24. data/lib/axiom/types/boolean.rb +14 -0
  25. data/lib/axiom/types/class.rb +13 -0
  26. data/lib/axiom/types/date.rb +18 -0
  27. data/lib/axiom/types/date_time.rb +21 -0
  28. data/lib/axiom/types/decimal.rb +13 -0
  29. data/lib/axiom/types/encodable.rb +75 -0
  30. data/lib/axiom/types/float.rb +13 -0
  31. data/lib/axiom/types/hash.rb +45 -0
  32. data/lib/axiom/types/integer.rb +13 -0
  33. data/lib/axiom/types/length_comparable.rb +51 -0
  34. data/lib/axiom/types/numeric.rb +13 -0
  35. data/lib/axiom/types/object.rb +36 -0
  36. data/lib/axiom/types/set.rb +13 -0
  37. data/lib/axiom/types/string.rb +18 -0
  38. data/lib/axiom/types/support/options.rb +129 -0
  39. data/lib/axiom/types/symbol.rb +18 -0
  40. data/lib/axiom/types/time.rb +22 -0
  41. data/lib/axiom/types/type.rb +136 -0
  42. data/lib/axiom/types/value_comparable.rb +49 -0
  43. data/lib/axiom/types/version.rb +10 -0
  44. data/spec/spec_helper.rb +37 -0
  45. data/spec/unit/axiom/types/class_methods/finalize_spec.rb +22 -0
  46. data/spec/unit/axiom/types/encodable/class_methods/extended_spec.rb +31 -0
  47. data/spec/unit/axiom/types/encodable/finalize_spec.rb +55 -0
  48. data/spec/unit/axiom/types/hash/class_methods/finalize_spec.rb +55 -0
  49. data/spec/unit/axiom/types/length_comparable/class_methods/extended_spec.rb +32 -0
  50. data/spec/unit/axiom/types/length_comparable/finalize_spec.rb +32 -0
  51. data/spec/unit/axiom/types/object/class_methods/coercion_method_spec.rb +27 -0
  52. data/spec/unit/axiom/types/object/class_methods/finalize_spec.rb +29 -0
  53. data/spec/unit/axiom/types/object/class_methods/primitive_spec.rb +27 -0
  54. data/spec/unit/axiom/types/options/accept_options_spec.rb +98 -0
  55. data/spec/unit/axiom/types/options/inherited_spec.rb +38 -0
  56. data/spec/unit/axiom/types/type/class_methods/constraint_spec.rb +32 -0
  57. data/spec/unit/axiom/types/type/class_methods/finalize_spec.rb +20 -0
  58. data/spec/unit/axiom/types/type/class_methods/include_predicate_spec.rb +25 -0
  59. data/spec/unit/axiom/types/type/class_methods/includes_spec.rb +45 -0
  60. data/spec/unit/axiom/types/type/class_methods/new_spec.rb +79 -0
  61. data/spec/unit/axiom/types/value_comparable/class_methods/extended_spec.rb +32 -0
  62. data/spec/unit/axiom/types/value_comparable/finalize_spec.rb +32 -0
  63. metadata +215 -0
@@ -0,0 +1,16 @@
1
+ ---
2
+ AbcMetricMethodCheck: { score: 6.0 }
3
+ AssignmentInConditionalCheck: { }
4
+ CaseMissingElseCheck: { }
5
+ ClassLineCountCheck: { line_count: 129 }
6
+ ClassNameCheck: { pattern: !ruby/regexp '/\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/' }
7
+ ClassVariableCheck: { }
8
+ CyclomaticComplexityBlockCheck: { complexity: 3 }
9
+ CyclomaticComplexityMethodCheck: { complexity: 3 }
10
+ EmptyRescueBodyCheck: { }
11
+ ForLoopCheck: { }
12
+ MethodLineCountCheck: { line_count: 5 }
13
+ MethodNameCheck: { pattern: !ruby/regexp '/\A(?:[a-z\d](?:_?[a-z\d])+[?!=]?|\[\]=?|==|<=>|<<|[+*&|-])\z/' }
14
+ ModuleLineCountCheck: { line_count: 111 }
15
+ ModuleNameCheck: { pattern: !ruby/regexp '/\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/' }
16
+ ParameterNumberCheck: { parameter_count: 2 }
@@ -0,0 +1,2 @@
1
+ ---
2
+ threshold: 100
@@ -0,0 +1,3 @@
1
+ # encoding: utf-8
2
+
3
+ require 'axiom/types'
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bigdecimal'
4
+ require 'date'
5
+ require 'set'
6
+
7
+ require 'backports'
8
+ require 'ice_nine'
9
+ require 'descendants_tracker'
10
+
11
+ module Axiom
12
+ module Types
13
+
14
+ # Represent an undefined argument
15
+ Undefined = Object.new.freeze
16
+
17
+ # A true proposition
18
+ Tautology = proc { true }.freeze
19
+
20
+ # A false proposition
21
+ Contradiction = proc { false }.freeze
22
+
23
+ # Finalize Axiom::Types::Type subclasses
24
+ #
25
+ # @example
26
+ # Axiom::Types.finalize # => Axiom::Types
27
+ #
28
+ # @return [Axiom::Types]
29
+ #
30
+ # @api public
31
+ def self.finalize
32
+ Type.descendants.each(&:finalize)
33
+ self
34
+ end
35
+
36
+ end # module Types
37
+ end # module Axiom
38
+
39
+ require 'axiom/types/support/options'
40
+
41
+ require 'axiom/types/value_comparable'
42
+ require 'axiom/types/length_comparable'
43
+ require 'axiom/types/encodable'
44
+
45
+ require 'axiom/types/type'
46
+
47
+ require 'axiom/types/object'
48
+
49
+ require 'axiom/types/numeric'
50
+
51
+ require 'axiom/types/array'
52
+ require 'axiom/types/boolean'
53
+ require 'axiom/types/class'
54
+ require 'axiom/types/date'
55
+ require 'axiom/types/date_time'
56
+ require 'axiom/types/decimal'
57
+ require 'axiom/types/float'
58
+ require 'axiom/types/hash'
59
+ require 'axiom/types/integer'
60
+ require 'axiom/types/set'
61
+ require 'axiom/types/string'
62
+ require 'axiom/types/symbol'
63
+ require 'axiom/types/time'
64
+
65
+ require 'axiom/types/version'
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ module Types
5
+
6
+ # Represents an array type
7
+ class Array < Object
8
+ primitive ::Array
9
+ coercion_method :to_array
10
+
11
+ end # class Array
12
+ end # module Types
13
+ end # module Axiom
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ module Types
5
+
6
+ # Represents a boolean type
7
+ class Boolean < Object
8
+ coercion_method :to_boolean
9
+
10
+ includes true, false
11
+
12
+ end # class Boolean
13
+ end # module Types
14
+ end # module Axiom
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ module Types
5
+
6
+ # Represents a Class type
7
+ class Class < Object
8
+ primitive ::Class
9
+ coercion_method :to_class
10
+
11
+ end # class Class
12
+ end # module Types
13
+ end # module Axiom
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ module Types
5
+
6
+ # Represents a date type
7
+ class Date < Object
8
+ extend ValueComparable
9
+
10
+ primitive ::Date
11
+ coercion_method :to_date
12
+
13
+ minimum primitive.new(1, 1, 1)
14
+ maximum primitive.new(9999, 12, 31)
15
+
16
+ end # class Date
17
+ end # module Types
18
+ end # module Axiom
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ module Types
5
+
6
+ # Represents a date time type
7
+ class DateTime < Object
8
+ extend ValueComparable
9
+
10
+ # The maximum seconds for DateTime
11
+ MAXIMUM_SECONDS = 60 - Rational(1, 10**12)
12
+
13
+ primitive ::DateTime
14
+ coercion_method :to_datetime
15
+
16
+ minimum primitive.new(1, 1, 1)
17
+ maximum primitive.new(9999, 12, 31, 23, 59, MAXIMUM_SECONDS)
18
+
19
+ end # class DateTime
20
+ end # module Types
21
+ end # module Axiom
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ module Types
5
+
6
+ # Represents a decimal type
7
+ class Decimal < Numeric
8
+ primitive ::BigDecimal
9
+ coercion_method :to_decimal
10
+
11
+ end # class Decimal
12
+ end # module Types
13
+ end # module Axiom
@@ -0,0 +1,75 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ module Types
5
+
6
+ # Add encoding constraints to a type
7
+ module Encodable
8
+ # stub module for ruby 1.8
9
+ end
10
+
11
+ module Encodable
12
+
13
+ # Hook called when module is extended
14
+ #
15
+ # Add #encoding DSL method to descendant and set the default to UTF-8.
16
+ #
17
+ # @param [Class<Axiom::Types::Type>] descendant
18
+ #
19
+ # @return [undefined]
20
+ #
21
+ # @api private
22
+ def self.extended(descendant)
23
+ super
24
+ descendant.accept_options :encoding
25
+ descendant.encoding Encoding::UTF_8
26
+ end
27
+
28
+ private_class_method :extended
29
+
30
+ # Finalize by setting up a primitive constraint
31
+ #
32
+ # @return [Axiom::Types::Encodable]
33
+ #
34
+ # @api private
35
+ def finalize
36
+ return self if frozen?
37
+ ascii_compatible? ? has_ascii_compatible_encoding : has_encoding
38
+ super
39
+ end
40
+
41
+ private
42
+
43
+ # Test if the encoding is ascii compatible
44
+ #
45
+ # @return [Boolean]
46
+ #
47
+ # @api private
48
+ def ascii_compatible?
49
+ encoding.ascii_compatible?
50
+ end
51
+
52
+ # Add constraint for the ascii compatible encoding
53
+ #
54
+ # @return [undefined]
55
+ #
56
+ # @api private
57
+ def has_ascii_compatible_encoding
58
+ constraint do |object|
59
+ object.encoding.equal?(encoding) || object.to_s.ascii_only?
60
+ end
61
+ end
62
+
63
+ # Add constraint for the encoding
64
+ #
65
+ # @return [undefined]
66
+ #
67
+ # @api private
68
+ def has_encoding
69
+ constraint { |object| object.encoding.equal?(encoding) }
70
+ end
71
+
72
+ end if RUBY_VERSION >= '1.9'
73
+
74
+ end # module Types
75
+ end # module Axiom
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ module Types
5
+
6
+ # Represents a decimal type
7
+ class Float < Numeric
8
+ primitive ::Float
9
+ coercion_method :to_float
10
+
11
+ end # class Float
12
+ end # module Types
13
+ end # module Axiom
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ module Types
5
+
6
+ # Represents a hash type
7
+ class Hash < Object
8
+ primitive ::Hash
9
+ coercion_method :to_hash
10
+ accept_options :key_type, :value_type
11
+
12
+ key_type Object
13
+ value_type Object
14
+
15
+ # Finalize by setting up constraints for the key and value
16
+ #
17
+ # @return [Axiom::Types::Object]
18
+ #
19
+ # @api private
20
+ def self.finalize
21
+ return self if frozen?
22
+ key_type.finalize
23
+ value_type.finalize
24
+ matches_key_and_value_types
25
+ super
26
+ end
27
+
28
+ # Add a constraints for the key and value
29
+ #
30
+ # @return [undefined]
31
+ #
32
+ # @api private
33
+ def self.matches_key_and_value_types
34
+ constraint do |object|
35
+ object.all? do |key, value|
36
+ key_type.include?(key) && value_type.include?(value)
37
+ end
38
+ end
39
+ end
40
+
41
+ private_class_method :matches_key_and_value_types
42
+
43
+ end # class Hash
44
+ end # module Types
45
+ end # module Axiom
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ module Types
5
+
6
+ # Represents a decimal type
7
+ class Integer < Numeric
8
+ primitive ::Integer
9
+ coercion_method :to_integer
10
+
11
+ end # class Integer
12
+ end # module Types
13
+ end # module Axiom
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ module Types
5
+
6
+ # Add a minimum and maximum length constraint to a type
7
+ module LengthComparable
8
+
9
+ # Hook called when module is extended
10
+ #
11
+ # Add #minimum_length and #maximum_length DSL methods to descendant.
12
+ #
13
+ # @param [Class<Axiom::Types::Type>] descendant
14
+ #
15
+ # @return [undefined]
16
+ #
17
+ # @api private
18
+ def self.extended(descendant)
19
+ super
20
+ descendant.accept_options :minimum_length, :maximum_length
21
+ end
22
+
23
+ # Finalize by setting up a length range constraint
24
+ #
25
+ # @return [Axiom::Types::LengthComparable]
26
+ #
27
+ # @api private
28
+ def finalize
29
+ return self if frozen?
30
+ has_length_within_range
31
+ super
32
+ end
33
+
34
+ private
35
+
36
+ # Add a constraint for a length within a range
37
+ #
38
+ # @return [undefined]
39
+ #
40
+ # @todo freeze the minimum_length and maximum_length
41
+ #
42
+ # @api private
43
+ def has_length_within_range
44
+ constraint do |object|
45
+ object.length.between?(minimum_length, maximum_length)
46
+ end
47
+ end
48
+
49
+ end # module LengthComparable
50
+ end # module Types
51
+ end # module Axiom
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ module Types
5
+
6
+ # Represents a numeric type
7
+ class Numeric < Object
8
+ primitive ::Numeric
9
+ coercion_method :to_numeric
10
+
11
+ end # class Numeric
12
+ end # module Types
13
+ end # module Axiom
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ module Types
5
+
6
+ # Represents an object type
7
+ class Object < Type
8
+ accept_options :primitive, :coercion_method
9
+ primitive ::Object.superclass || ::Object
10
+ coercion_method :to_object
11
+
12
+ # Finalize by setting up a primitive constraint
13
+ #
14
+ # @return [Axiom::Types::Object]
15
+ #
16
+ # @api private
17
+ def self.finalize
18
+ return self if frozen?
19
+ inherits_from_primitive
20
+ super
21
+ end
22
+
23
+ # Add a constraint for the primitive
24
+ #
25
+ # @return [undefined]
26
+ #
27
+ # @api private
28
+ def self.inherits_from_primitive
29
+ constraint(&primitive.method(:===))
30
+ end
31
+
32
+ private_class_method :inherits_from_primitive
33
+
34
+ end # class Object
35
+ end # module Types
36
+ end # module Axiom