axiom-types 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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