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.
- 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
|