axiom-types 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +37 -0
- data/.rspec +4 -0
- data/.rvmrc +1 -0
- data/.travis.yml +35 -0
- data/.yardopts +4 -0
- data/Gemfile +10 -0
- data/Gemfile.devtools +62 -0
- data/Guardfile +24 -0
- data/LICENSE +20 -0
- data/README.md +76 -0
- data/Rakefile +6 -0
- data/TODO +25 -0
- data/axiom-types.gemspec +26 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/mutant.yml +3 -0
- data/config/reek.yml +100 -0
- data/config/roodi.yml +16 -0
- data/config/yardstick.yml +2 -0
- data/lib/axiom-types.rb +3 -0
- data/lib/axiom/types.rb +65 -0
- data/lib/axiom/types/array.rb +13 -0
- data/lib/axiom/types/boolean.rb +14 -0
- data/lib/axiom/types/class.rb +13 -0
- data/lib/axiom/types/date.rb +18 -0
- data/lib/axiom/types/date_time.rb +21 -0
- data/lib/axiom/types/decimal.rb +13 -0
- data/lib/axiom/types/encodable.rb +75 -0
- data/lib/axiom/types/float.rb +13 -0
- data/lib/axiom/types/hash.rb +45 -0
- data/lib/axiom/types/integer.rb +13 -0
- data/lib/axiom/types/length_comparable.rb +51 -0
- data/lib/axiom/types/numeric.rb +13 -0
- data/lib/axiom/types/object.rb +36 -0
- data/lib/axiom/types/set.rb +13 -0
- data/lib/axiom/types/string.rb +18 -0
- data/lib/axiom/types/support/options.rb +129 -0
- data/lib/axiom/types/symbol.rb +18 -0
- data/lib/axiom/types/time.rb +22 -0
- data/lib/axiom/types/type.rb +136 -0
- data/lib/axiom/types/value_comparable.rb +49 -0
- data/lib/axiom/types/version.rb +10 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/unit/axiom/types/class_methods/finalize_spec.rb +22 -0
- data/spec/unit/axiom/types/encodable/class_methods/extended_spec.rb +31 -0
- data/spec/unit/axiom/types/encodable/finalize_spec.rb +55 -0
- data/spec/unit/axiom/types/hash/class_methods/finalize_spec.rb +55 -0
- data/spec/unit/axiom/types/length_comparable/class_methods/extended_spec.rb +32 -0
- data/spec/unit/axiom/types/length_comparable/finalize_spec.rb +32 -0
- data/spec/unit/axiom/types/object/class_methods/coercion_method_spec.rb +27 -0
- data/spec/unit/axiom/types/object/class_methods/finalize_spec.rb +29 -0
- data/spec/unit/axiom/types/object/class_methods/primitive_spec.rb +27 -0
- data/spec/unit/axiom/types/options/accept_options_spec.rb +98 -0
- data/spec/unit/axiom/types/options/inherited_spec.rb +38 -0
- data/spec/unit/axiom/types/type/class_methods/constraint_spec.rb +32 -0
- data/spec/unit/axiom/types/type/class_methods/finalize_spec.rb +20 -0
- data/spec/unit/axiom/types/type/class_methods/include_predicate_spec.rb +25 -0
- data/spec/unit/axiom/types/type/class_methods/includes_spec.rb +45 -0
- data/spec/unit/axiom/types/type/class_methods/new_spec.rb +79 -0
- data/spec/unit/axiom/types/value_comparable/class_methods/extended_spec.rb +32 -0
- data/spec/unit/axiom/types/value_comparable/finalize_spec.rb +32 -0
- metadata +215 -0
data/config/roodi.yml
ADDED
@@ -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 }
|
data/lib/axiom-types.rb
ADDED
data/lib/axiom/types.rb
ADDED
@@ -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,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,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,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,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,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
|