hash_cast 0.4.0 → 0.5.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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +3 -0
  3. data/Gemfile.lock +1 -1
  4. data/README.md +5 -5
  5. data/{hcast.gemspec → hash_cast.gemspec} +2 -2
  6. data/lib/{hcast → hash_cast}/attributes_caster.rb +6 -6
  7. data/lib/{hcast → hash_cast}/attributes_parser.rb +9 -9
  8. data/lib/{hcast → hash_cast}/caster.rb +12 -12
  9. data/lib/{hcast → hash_cast}/casters/array_caster.rb +4 -4
  10. data/lib/{hcast → hash_cast}/casters/boolean_caster.rb +2 -2
  11. data/lib/{hcast → hash_cast}/casters/date_caster.rb +3 -3
  12. data/lib/{hcast → hash_cast}/casters/datetime_caster.rb +3 -3
  13. data/lib/{hcast → hash_cast}/casters/float_caster.rb +3 -3
  14. data/lib/{hcast → hash_cast}/casters/hash_caster.rb +2 -2
  15. data/lib/{hcast → hash_cast}/casters/integer_caster.rb +3 -3
  16. data/lib/hash_cast/casters/string_caster.rb +26 -0
  17. data/lib/{hcast → hash_cast}/casters/symbol_caster.rb +3 -3
  18. data/lib/{hcast → hash_cast}/casters/time_caster.rb +3 -3
  19. data/lib/hash_cast/casters.rb +13 -0
  20. data/lib/{hcast → hash_cast}/concern.rb +1 -1
  21. data/lib/hash_cast/config.rb +17 -0
  22. data/lib/{hcast → hash_cast}/errors.rb +8 -8
  23. data/lib/{hcast → hash_cast}/metadata/attribute.rb +1 -1
  24. data/lib/hash_cast/version.rb +3 -0
  25. data/lib/hash_cast.rb +46 -0
  26. data/spec/{hcast → hash_cast}/caster_spec.rb +42 -17
  27. data/spec/{hcast/hcast_spec.rb → hash_cast/hash_cast_spec.rb} +2 -2
  28. data/spec/spec_helper.rb +1 -1
  29. metadata +28 -27
  30. data/lib/hcast/casters/string_caster.rb +0 -13
  31. data/lib/hcast/casters.rb +0 -13
  32. data/lib/hcast/config.rb +0 -11
  33. data/lib/hcast/version.rb +0 -3
  34. data/lib/hcast.rb +0 -46
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71b3bcf7f98727c99228d5fb0ceaba02b87767721c251ba69d5c91079f936b5a
4
- data.tar.gz: 1cd37fcce0009d5895dc72a4af32bd0c2dd2ea6ce5abee97b7e6b190a33c1655
3
+ metadata.gz: 68e050b609ffe18b09ada29f3606534113be56827b161bae6e917cbeadc82a57
4
+ data.tar.gz: 76b1ba697a03d6edcccb6f5196d3411d8af423ff5e0e0b1661b81db3e02846e6
5
5
  SHA512:
6
- metadata.gz: e607f921e463af6ff705ad3cfd86c9ca5532d7813913f6c795bfec73879b02cc4a8101b44ab9f475f45576ccbadd8b47d5d71e57ca3565b98813e4a3e5c6427c
7
- data.tar.gz: a7297e7a81c4165dcda83135131e68817e29c043fd20594f5ce3ec9ab8b37eef07afd16bd9d606bf2a6ab0a8bb041e0cf17067ddc0b46212749e56b2a55afe34
6
+ metadata.gz: e7fc1162f788fd180c0cd1a080bb2dbbcaaeb7b28fa1d59b3d490a0bd3f744a3457998d65fc1ce6d2e9819ce898416d6832c658d8bd5e3d47486980d6a4a1db3
7
+ data.tar.gz: 1d9d02707117f5619902867966c4e0a1f542e0e9aedd2b183557aaf25c6fc85704d488db2c52c22534a377779a68b1bc9d09b31420ad77af54576d701358f9fe
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ **Version 0.5.1**
2
+ - String caster should validate for null byte by default
3
+ - skip_unexpected_attributes option is true by default
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hash_cast (0.4.0)
4
+ hash_cast (0.5.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,14 +1,14 @@
1
- # HCast
2
- [![Rspec](https://github.com/droidlabs/hcast/workflows/Rspec/badge.svg)](https://github.com/droidlabs/hcast/actions?query=workflow%3ARspec)
1
+ # HashCast
2
+ [![Rspec](https://github.com/droidlabs/hash_cast/workflows/Rspec/badge.svg)](https://github.com/droidlabs/hash_cast/actions?query=workflow%3ARspec)
3
3
 
4
- HCast is a library for casting hash attributes
4
+ HashCast is a library for casting hash attributes
5
5
 
6
6
  ### Usage
7
7
 
8
8
  Create caster class and declare hash attributes inside:
9
9
  ```ruby
10
10
  class ContactCaster
11
- include HCast::Caster
11
+ include HashCast::Caster
12
12
 
13
13
  attributes do
14
14
  hash :contact do
@@ -86,7 +86,7 @@ The caster will cast your hash attributes to:
86
86
  }
87
87
  ```
88
88
 
89
- if some of the attributes can't be casted the HCast::Errors::CastingError is raised
89
+ if some of the attributes can't be casted the HashCast::Errors::CastingError is raised
90
90
 
91
91
 
92
92
  ## Author
@@ -1,11 +1,11 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'hcast/version'
4
+ require 'hash_cast/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "hash_cast"
8
- spec.version = HCast::VERSION
8
+ spec.version = HashCast::VERSION
9
9
  spec.authors = ["Albert Gazizov"]
10
10
  spec.email = ["deeper4k@gmail.com"]
11
11
  spec.description = %q{Declarative Hash Caster}
@@ -1,4 +1,4 @@
1
- class HCast::AttributesCaster
1
+ class HashCast::AttributesCaster
2
2
  attr_reader :attributes, :options
3
3
 
4
4
  def initialize(attributes, options)
@@ -15,15 +15,15 @@ class HCast::AttributesCaster
15
15
  begin
16
16
  casted_value = cast_attribute(attribute, input_hash)
17
17
  casted_hash[attribute.name] = casted_value
18
- rescue HCast::Errors::AttributeError => e
18
+ rescue HashCast::Errors::AttributeError => e
19
19
  handle_attribute_error(e, attribute)
20
20
  end
21
21
  else
22
- raise HCast::Errors::MissingAttributeError.new("should be given", attribute.name)if attribute.required?
22
+ raise HashCast::Errors::MissingAttributeError.new("should be given", attribute.name)if attribute.required?
23
23
  end
24
24
  end
25
25
 
26
- if !options[:skip_unexpected_attributes]
26
+ if options.has_key?(:skip_unexpected_attributes) && !options[:skip_unexpected_attributes]
27
27
  check_unexpected_attributes_not_given!(hash_keys, casted_hash.keys)
28
28
  end
29
29
 
@@ -59,7 +59,7 @@ class HCast::AttributesCaster
59
59
  end
60
60
 
61
61
  def cast_children_with_caster(value, attribute, caster)
62
- if attribute.caster == HCast::Casters::ArrayCaster
62
+ if attribute.caster == HashCast::Casters::ArrayCaster
63
63
  value.map do |val|
64
64
  caster.cast(val)
65
65
  end
@@ -95,7 +95,7 @@ class HCast::AttributesCaster
95
95
  def check_unexpected_attributes_not_given!(input_hash_keys, casted_hash_keys)
96
96
  unexpected_keys = input_hash_keys - casted_hash_keys
97
97
  unless unexpected_keys.empty?
98
- raise HCast::Errors::UnexpectedAttributeError.new("is not valid attribute name", unexpected_keys.first)
98
+ raise HashCast::Errors::UnexpectedAttributeError.new("is not valid attribute name", unexpected_keys.first)
99
99
  end
100
100
  end
101
101
 
@@ -1,11 +1,11 @@
1
1
  # Parses caster rules
2
- # and returns list of HCast::Metadata::Attribute instances
2
+ # and returns list of HashCast::Metadata::Attribute instances
3
3
  # which contains casting rules
4
- class HCast::AttributesParser
4
+ class HashCast::AttributesParser
5
5
 
6
6
  # Performs casting
7
7
  # @param block [Proc] block with casting rules
8
- # @return Array(HCast::Metadata::Attribute) list of casting rules
8
+ # @return Array(HashCast::Metadata::Attribute) list of casting rules
9
9
  def self.parse(&block)
10
10
  dsl = DSL.new
11
11
  dsl.instance_exec(&block)
@@ -27,15 +27,15 @@ class HCast::AttributesParser
27
27
  def method_missing(caster_name, *args, &block)
28
28
  attr_name = args[0]
29
29
  options = args[1] || {}
30
- caster = HCast.casters[caster_name]
30
+ caster = HashCast.casters[caster_name]
31
31
 
32
32
  check_caster_exists!(caster, caster_name)
33
33
  check_attr_name_valid!(attr_name)
34
34
  check_options_is_hash!(options)
35
35
 
36
- attribute = HCast::Metadata::Attribute.new(attr_name, caster, options)
36
+ attribute = HashCast::Metadata::Attribute.new(attr_name, caster, options)
37
37
  if block_given?
38
- attribute.children = HCast::AttributesParser.parse(&block)
38
+ attribute.children = HashCast::AttributesParser.parse(&block)
39
39
  end
40
40
  attributes << attribute
41
41
  end
@@ -44,19 +44,19 @@ class HCast::AttributesParser
44
44
 
45
45
  def check_caster_exists!(caster, caster_name)
46
46
  if !caster
47
- raise HCast::Errors::CasterNotFoundError, "caster with name '#{caster_name}' is not found"
47
+ raise HashCast::Errors::CasterNotFoundError, "caster with name '#{caster_name}' is not found"
48
48
  end
49
49
  end
50
50
 
51
51
  def check_attr_name_valid!(attr_name)
52
52
  if !attr_name.is_a?(Symbol) && !attr_name.is_a?(String)
53
- raise HCast::Errors::ArgumentError, "attribute name should be a symbol or string"
53
+ raise HashCast::Errors::ArgumentError, "attribute name should be a symbol or string"
54
54
  end
55
55
  end
56
56
 
57
57
  def check_options_is_hash!(options)
58
58
  if !options.is_a?(Hash)
59
- raise HCast::Errors::ArgumentError, "attribute options should be a Hash"
59
+ raise HashCast::Errors::ArgumentError, "attribute options should be a Hash"
60
60
  end
61
61
  end
62
62
  end
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Example caster:
4
4
  # class ContactCaster
5
- # include HCast::Caster
5
+ # include HashCast::Caster
6
6
  #
7
7
  # attributes do
8
8
  # hash :contact do
@@ -76,8 +76,8 @@
76
76
  # ]
77
77
  # }
78
78
  # }
79
- module HCast::Caster
80
- extend HCast::Concern
79
+ module HashCast::Caster
80
+ extend HashCast::Concern
81
81
 
82
82
  module ClassMethods
83
83
 
@@ -91,7 +91,7 @@ module HCast::Caster
91
91
  def attributes(&block)
92
92
  raise ArgumentError, "You should provide block" unless block_given?
93
93
 
94
- attributes = HCast::AttributesParser.parse(&block)
94
+ attributes = HashCast::AttributesParser.parse(&block)
95
95
  self.class_variable_set(:@@attributes, attributes)
96
96
  end
97
97
 
@@ -104,7 +104,7 @@ module HCast::Caster
104
104
  check_options!(options)
105
105
  set_default_options(options)
106
106
 
107
- attributes_caster = HCast::AttributesCaster.new(class_variable_get(:@@attributes), options)
107
+ attributes_caster = HashCast::AttributesCaster.new(class_variable_get(:@@attributes), options)
108
108
  attributes_caster.cast(hash)
109
109
  end
110
110
 
@@ -112,31 +112,31 @@ module HCast::Caster
112
112
 
113
113
  def check_attributes_defined!
114
114
  unless class_variable_defined?(:@@attributes)
115
- raise HCast::Errors::ArgumentError, "Attributes block should be defined"
115
+ raise HashCast::Errors::ArgumentError, "Attributes block should be defined"
116
116
  end
117
117
  end
118
118
 
119
119
  def check_options!(options)
120
120
  unless options.is_a?(Hash)
121
- raise HCast::Errors::ArgumentError, "Options should be a hash"
121
+ raise HashCast::Errors::ArgumentError, "Options should be a hash"
122
122
  end
123
123
  if options[:input_keys] && ![:string, :symbol].include?(options[:input_keys])
124
- raise HCast::Errors::ArgumentError, "input_keys should be :string or :symbol"
124
+ raise HashCast::Errors::ArgumentError, "input_keys should be :string or :symbol"
125
125
  end
126
126
  if options[:output_keys] && ![:string, :symbol].include?(options[:output_keys])
127
- raise HCast::Errors::ArgumentError, "output_keys should be :string or :symbol"
127
+ raise HashCast::Errors::ArgumentError, "output_keys should be :string or :symbol"
128
128
  end
129
129
  end
130
130
 
131
131
  def check_hash_given!(hash)
132
132
  unless hash.is_a?(Hash)
133
- raise HCast::Errors::ArgumentError, "Hash should be given"
133
+ raise HashCast::Errors::ArgumentError, "Hash should be given"
134
134
  end
135
135
  end
136
136
 
137
137
  def set_default_options(options)
138
- options[:input_keys] ||= HCast.config.input_keys
139
- options[:output_keys] ||= HCast.config.output_keys
138
+ options[:input_keys] ||= HashCast.config.input_keys
139
+ options[:output_keys] ||= HashCast.config.output_keys
140
140
  end
141
141
  end
142
142
  end
@@ -1,4 +1,4 @@
1
- class HCast::Casters::ArrayCaster
1
+ class HashCast::Casters::ArrayCaster
2
2
 
3
3
  def self.cast(value, attr_name, options = {})
4
4
  if value.is_a?(Array)
@@ -8,7 +8,7 @@ class HCast::Casters::ArrayCaster
8
8
  value
9
9
  end
10
10
  else
11
- raise HCast::Errors::CastingError, "should be an array"
11
+ raise HashCast::Errors::CastingError, "should be an array"
12
12
  end
13
13
  end
14
14
 
@@ -16,7 +16,7 @@ class HCast::Casters::ArrayCaster
16
16
 
17
17
  def self.cast_array_items(array, attr_name, options)
18
18
  caster_name = options[:each]
19
- caster = HCast.casters[caster_name]
19
+ caster = HashCast.casters[caster_name]
20
20
  check_caster_exists!(caster, caster_name)
21
21
  array.map do |item|
22
22
  caster.cast(item, "#{attr_name} item", options)
@@ -25,7 +25,7 @@ class HCast::Casters::ArrayCaster
25
25
 
26
26
  def self.check_caster_exists!(caster, caster_name)
27
27
  unless caster
28
- raise HCast::Errors::CasterNotFoundError, "caster with name #{caster_name} is not found"
28
+ raise HashCast::Errors::CasterNotFoundError, "caster with name #{caster_name} is not found"
29
29
  end
30
30
  end
31
31
 
@@ -1,4 +1,4 @@
1
- class HCast::Casters::BooleanCaster
1
+ class HashCast::Casters::BooleanCaster
2
2
 
3
3
  def self.cast(value, attr_name, options = {})
4
4
  if [TrueClass, FalseClass].include?(value.class)
@@ -8,7 +8,7 @@ class HCast::Casters::BooleanCaster
8
8
  elsif ['0', 'false', 'off', 0].include?(value)
9
9
  false
10
10
  else
11
- raise HCast::Errors::CastingError, "should be a boolean"
11
+ raise HashCast::Errors::CastingError, "should be a boolean"
12
12
  end
13
13
  end
14
14
 
@@ -1,6 +1,6 @@
1
1
  require 'date'
2
2
 
3
- class HCast::Casters::DateCaster
3
+ class HashCast::Casters::DateCaster
4
4
 
5
5
  def self.cast(value, attr_name, options = {})
6
6
  if value.is_a?(Date)
@@ -9,10 +9,10 @@ class HCast::Casters::DateCaster
9
9
  begin
10
10
  Date.parse(value)
11
11
  rescue ArgumentError => e
12
- raise HCast::Errors::CastingError, "is invalid date"
12
+ raise HashCast::Errors::CastingError, "is invalid date"
13
13
  end
14
14
  else
15
- raise HCast::Errors::CastingError, "should be a date"
15
+ raise HashCast::Errors::CastingError, "should be a date"
16
16
  end
17
17
  end
18
18
 
@@ -1,4 +1,4 @@
1
- class HCast::Casters::DateTimeCaster
1
+ class HashCast::Casters::DateTimeCaster
2
2
 
3
3
  def self.cast(value, attr_name, options = {})
4
4
  if value.is_a?(DateTime)
@@ -9,10 +9,10 @@ class HCast::Casters::DateTimeCaster
9
9
  begin
10
10
  DateTime.parse(value)
11
11
  rescue ArgumentError => e
12
- raise HCast::Errors::CastingError, "is invalid datetime"
12
+ raise HashCast::Errors::CastingError, "is invalid datetime"
13
13
  end
14
14
  else
15
- raise HCast::Errors::CastingError, "should be a datetime"
15
+ raise HashCast::Errors::CastingError, "should be a datetime"
16
16
  end
17
17
  end
18
18
 
@@ -1,4 +1,4 @@
1
- class HCast::Casters::FloatCaster
1
+ class HashCast::Casters::FloatCaster
2
2
 
3
3
  def self.cast(value, attr_name, options = {})
4
4
  if value.is_a?(Float)
@@ -7,10 +7,10 @@ class HCast::Casters::FloatCaster
7
7
  begin
8
8
  Float(value)
9
9
  rescue ArgumentError => e
10
- raise HCast::Errors::CastingError, "is invalid float"
10
+ raise HashCast::Errors::CastingError, "is invalid float"
11
11
  end
12
12
  else
13
- raise HCast::Errors::CastingError, "should be a float"
13
+ raise HashCast::Errors::CastingError, "should be a float"
14
14
  end
15
15
  end
16
16
 
@@ -1,10 +1,10 @@
1
- class HCast::Casters::HashCaster
1
+ class HashCast::Casters::HashCaster
2
2
 
3
3
  def self.cast(value, attr_name, options = {})
4
4
  if value.is_a?(Hash)
5
5
  value
6
6
  else
7
- raise HCast::Errors::CastingError, "should be a hash"
7
+ raise HashCast::Errors::CastingError, "should be a hash"
8
8
  end
9
9
  end
10
10
 
@@ -1,4 +1,4 @@
1
- class HCast::Casters::IntegerCaster
1
+ class HashCast::Casters::IntegerCaster
2
2
 
3
3
  def self.cast(value, attr_name, options = {})
4
4
  if value.is_a?(Integer)
@@ -7,10 +7,10 @@ class HCast::Casters::IntegerCaster
7
7
  begin
8
8
  Integer(value)
9
9
  rescue ArgumentError => e
10
- raise HCast::Errors::CastingError, "is invalid integer"
10
+ raise HashCast::Errors::CastingError, "is invalid integer"
11
11
  end
12
12
  else
13
- raise HCast::Errors::CastingError, "should be a integer"
13
+ raise HashCast::Errors::CastingError, "should be a integer"
14
14
  end
15
15
  end
16
16
 
@@ -0,0 +1,26 @@
1
+ class HashCast::Casters::StringCaster
2
+ NULL_BYTE_CHARACTER = "\u0000".freeze
3
+
4
+ def self.cast(value, attr_name, options = {})
5
+ casted_value = cast_string(value, attr_name, options)
6
+
7
+ if HashCast.config.validate_string_null_byte && casted_value.match?(NULL_BYTE_CHARACTER)
8
+ raise HashCast::Errors::CastingError, 'contains invalid characters'
9
+ end
10
+
11
+ casted_value
12
+ end
13
+
14
+ private
15
+
16
+ def self.cast_string(value, attr_name, options = {})
17
+ if value.is_a?(String)
18
+ value
19
+ elsif value.is_a?(Symbol)
20
+ value.to_s
21
+ else
22
+ raise HashCast::Errors::CastingError, "should be a string"
23
+ end
24
+ end
25
+
26
+ end
@@ -1,4 +1,4 @@
1
- class HCast::Casters::SymbolCaster
1
+ class HashCast::Casters::SymbolCaster
2
2
  MAX_SYMBOL_LENGTH = 1000
3
3
 
4
4
  def self.cast(value, attr_name, options = {})
@@ -6,12 +6,12 @@ class HCast::Casters::SymbolCaster
6
6
  value
7
7
  elsif value.is_a?(String)
8
8
  if value.length > MAX_SYMBOL_LENGTH
9
- raise HCast::Errors::CastingError, "is too long to be a symbol"
9
+ raise HashCast::Errors::CastingError, "is too long to be a symbol"
10
10
  else
11
11
  value.to_sym
12
12
  end
13
13
  else
14
- raise HCast::Errors::CastingError, "should be a symbol"
14
+ raise HashCast::Errors::CastingError, "should be a symbol"
15
15
  end
16
16
  end
17
17
 
@@ -1,6 +1,6 @@
1
1
  require 'time'
2
2
 
3
- class HCast::Casters::TimeCaster
3
+ class HashCast::Casters::TimeCaster
4
4
 
5
5
  def self.cast(value, attr_name, options = {})
6
6
  if value.is_a?(Time)
@@ -9,10 +9,10 @@ class HCast::Casters::TimeCaster
9
9
  begin
10
10
  Time.parse(value)
11
11
  rescue ArgumentError => e
12
- raise HCast::Errors::CastingError, "is invalid time"
12
+ raise HashCast::Errors::CastingError, "is invalid time"
13
13
  end
14
14
  else
15
- raise HCast::Errors::CastingError, "should be a time"
15
+ raise HashCast::Errors::CastingError, "should be a time"
16
16
  end
17
17
  end
18
18
 
@@ -0,0 +1,13 @@
1
+ # List of build in casters
2
+ module HashCast::Casters
3
+ require 'hash_cast/casters/array_caster'
4
+ require 'hash_cast/casters/boolean_caster'
5
+ require 'hash_cast/casters/date_caster'
6
+ require 'hash_cast/casters/datetime_caster'
7
+ require 'hash_cast/casters/float_caster'
8
+ require 'hash_cast/casters/hash_caster'
9
+ require 'hash_cast/casters/integer_caster'
10
+ require 'hash_cast/casters/string_caster'
11
+ require 'hash_cast/casters/symbol_caster'
12
+ require 'hash_cast/casters/time_caster'
13
+ end
@@ -1,4 +1,4 @@
1
- module HCast
1
+ module HashCast
2
2
  # Copied from here https://github.com/rails/rails/blob/master/activesupport/lib/active_support/concern.rb
3
3
  #
4
4
  # A typical module looks like this:
@@ -0,0 +1,17 @@
1
+ class HashCast::Config
2
+ attr_accessor :input_keys, :output_keys, :validate_string_null_byte
3
+
4
+ def input_keys
5
+ @input_keys || :symbol
6
+ end
7
+
8
+ def output_keys
9
+ @output_keys || :symbol
10
+ end
11
+
12
+ def validate_string_null_byte
13
+ return true if @validate_string_null_byte.nil?
14
+
15
+ @validate_string_null_byte
16
+ end
17
+ end
@@ -1,15 +1,15 @@
1
- module HCast::Errors
1
+ module HashCast::Errors
2
2
 
3
- # Base error class for all HCast errors
4
- class HCastError < StandardError; end
3
+ # Base error class for all HashCast errors
4
+ class HashCastError < StandardError; end
5
5
 
6
- # Raised when caster with given name is not registered in HCast
7
- class CasterNotFoundError < HCastError; end
6
+ # Raised when caster with given name is not registered in HashCast
7
+ class CasterNotFoundError < HashCastError; end
8
8
 
9
- # Raised when some of the given to HCast argument is not valid
10
- class ArgumentError < HCastError; end
9
+ # Raised when some of the given to HashCast argument is not valid
10
+ class ArgumentError < HashCastError; end
11
11
 
12
- class AttributeError < HCastError
12
+ class AttributeError < HashCastError
13
13
  attr_reader :namespaces
14
14
 
15
15
  def initialize(message, namespace = nil)
@@ -1,4 +1,4 @@
1
- module HCast::Metadata
1
+ module HashCast::Metadata
2
2
  class Attribute
3
3
  attr_reader :name, :caster, :options
4
4
  attr_accessor :children
@@ -0,0 +1,3 @@
1
+ module HashCast
2
+ VERSION = "0.5.1"
3
+ end
data/lib/hash_cast.rb ADDED
@@ -0,0 +1,46 @@
1
+ require 'hash_cast/version'
2
+ require 'hash_cast/errors'
3
+ require 'hash_cast/config'
4
+ require 'hash_cast/casters'
5
+ require 'hash_cast/concern.rb'
6
+ require 'hash_cast/metadata/attribute'
7
+ require 'hash_cast/attributes_parser'
8
+ require 'hash_cast/attributes_caster'
9
+ require 'hash_cast/caster'
10
+
11
+ module HashCast
12
+ @@casters = {}
13
+
14
+ # Defines caster without adding own class
15
+ # @note Not yet implemented
16
+ def self.create(&block)
17
+ end
18
+
19
+ # Returns list of defined casters
20
+ def self.casters
21
+ @@casters
22
+ end
23
+
24
+ # Adds new casters to HashCast
25
+ # Allow extend HashCast with your own casters
26
+ # @param caster_name [Symbol] caster name
27
+ # @param caster [Class] caster
28
+ def self.add_caster(caster_name, caster)
29
+ @@casters[caster_name] = caster
30
+ end
31
+
32
+ def self.config
33
+ @@config ||= HashCast::Config.new
34
+ end
35
+ end
36
+
37
+ HashCast.add_caster(:array, HashCast::Casters::ArrayCaster)
38
+ HashCast.add_caster(:boolean, HashCast::Casters::BooleanCaster)
39
+ HashCast.add_caster(:date, HashCast::Casters::DateCaster)
40
+ HashCast.add_caster(:datetime, HashCast::Casters::DateTimeCaster)
41
+ HashCast.add_caster(:float, HashCast::Casters::FloatCaster)
42
+ HashCast.add_caster(:hash, HashCast::Casters::HashCaster)
43
+ HashCast.add_caster(:integer, HashCast::Casters::IntegerCaster)
44
+ HashCast.add_caster(:string, HashCast::Casters::StringCaster)
45
+ HashCast.add_caster(:symbol, HashCast::Casters::SymbolCaster)
46
+ HashCast.add_caster(:time, HashCast::Casters::TimeCaster)
@@ -1,10 +1,10 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe HCast::Caster do
3
+ describe HashCast::Caster do
4
4
  describe "#cast" do
5
5
 
6
6
  class ContactCaster
7
- include HCast::Caster
7
+ include HashCast::Caster
8
8
 
9
9
  attributes do
10
10
  hash :contact do
@@ -82,7 +82,7 @@ describe HCast::Caster do
82
82
 
83
83
  describe "Custom casters" do
84
84
  class SettingsCaster
85
- include HCast::Caster
85
+ include HashCast::Caster
86
86
 
87
87
  attributes do
88
88
  string :account
@@ -90,7 +90,7 @@ describe HCast::Caster do
90
90
  end
91
91
 
92
92
  class EmailCaster
93
- include HCast::Caster
93
+ include HashCast::Caster
94
94
 
95
95
  attributes do
96
96
  string :address
@@ -98,7 +98,7 @@ describe HCast::Caster do
98
98
  end
99
99
 
100
100
  class CompanyCaster
101
- include HCast::Caster
101
+ include HashCast::Caster
102
102
 
103
103
  attributes do
104
104
  string :name
@@ -158,7 +158,7 @@ describe HCast::Caster do
158
158
 
159
159
  expect do
160
160
  ContactCaster.cast(input_hash)
161
- end.to raise_error(HCast::Errors::CastingError, "contact[name] should be a string")
161
+ end.to raise_error(HashCast::Errors::CastingError, "contact[name] should be a string")
162
162
  end
163
163
 
164
164
  it "should raise error if some attribute wasn't given" do
@@ -188,7 +188,7 @@ describe HCast::Caster do
188
188
 
189
189
  expect do
190
190
  ContactCaster.cast(input_hash)
191
- end.to raise_error(HCast::Errors::MissingAttributeError, "contact[name] should be given")
191
+ end.to raise_error(HashCast::Errors::MissingAttributeError, "contact[name] should be given")
192
192
  end
193
193
 
194
194
  it "should not raise error if attribute is optional" do
@@ -221,7 +221,7 @@ describe HCast::Caster do
221
221
  end.to_not raise_error
222
222
  end
223
223
 
224
- it "should raise error if unexpected attribute was given" do
224
+ it "raises error if skip_unexpected_attributes=false and unexpected attribute was given" do
225
225
  input_hash = {
226
226
  contact: {
227
227
  wrong_attribute: 'foo',
@@ -248,11 +248,11 @@ describe HCast::Caster do
248
248
  }
249
249
 
250
250
  expect do
251
- ContactCaster.cast(input_hash)
252
- end.to raise_error(HCast::Errors::UnexpectedAttributeError, "contact[wrong_attribute] is not valid attribute name")
251
+ ContactCaster.cast(input_hash, skip_unexpected_attributes: false)
252
+ end.to raise_error(HashCast::Errors::UnexpectedAttributeError, "contact[wrong_attribute] is not valid attribute name")
253
253
  end
254
254
 
255
- it "shouldn't unexpected attributes error if skip_unexpected_attributes flag is set to true" do
255
+ it "doesn't raise unexpected attributes error by default" do
256
256
  input_hash = {
257
257
  contact: {
258
258
  wrong_attribute: 'foo',
@@ -279,8 +279,8 @@ describe HCast::Caster do
279
279
  }
280
280
 
281
281
  expect do
282
- ContactCaster.cast(input_hash, skip_unexpected_attributes: true)
283
- end.not_to raise_error(HCast::Errors::UnexpectedAttributeError)
282
+ ContactCaster.cast(input_hash)
283
+ end.not_to raise_error(HashCast::Errors::UnexpectedAttributeError)
284
284
 
285
285
  end
286
286
 
@@ -343,20 +343,20 @@ describe HCast::Caster do
343
343
  it "should raise CaterNotFound exception if caster name is invalid" do
344
344
  expect do
345
345
  class WrongCaster
346
- include HCast::Caster
346
+ include HashCast::Caster
347
347
 
348
348
  attributes do
349
349
  integr :name
350
350
  end
351
351
  end
352
- end.to raise_error(HCast::Errors::CasterNotFoundError)
352
+ end.to raise_error(HashCast::Errors::CasterNotFoundError)
353
353
  end
354
354
  end
355
355
 
356
356
  context "allow nil values" do
357
357
  before(:all) do
358
358
  class HomeCaster
359
- include HCast::Caster
359
+ include HashCast::Caster
360
360
 
361
361
  attributes do
362
362
  string :city
@@ -378,7 +378,32 @@ describe HCast::Caster do
378
378
  city: nil,
379
379
  zip: nil
380
380
  )
381
- end.to raise_error(HCast::Errors::CastingError, "city should be a string")
381
+ end.to raise_error(HashCast::Errors::CastingError, "city should be a string")
382
+ end
383
+ end
384
+
385
+ context "string caster" do
386
+ before(:all) do
387
+ class HomeCaster
388
+ include HashCast::Caster
389
+
390
+ attributes do
391
+ string :city
392
+ end
393
+ end
394
+ end
395
+
396
+ after{ HashCast.config.validate_string_null_byte = nil }
397
+
398
+ it "should allow null byte if validate_string_null_byte config is set to false" do
399
+ HashCast.config.validate_string_null_byte = false
400
+ HomeCaster.cast(city: "\u0000")
401
+ end
402
+
403
+ it "should not allow null byte if validate_string_null_byte config by default" do
404
+ expect do
405
+ HomeCaster.cast(city: "\u0000")
406
+ end.to raise_error(HashCast::Errors::CastingError, "city contains invalid characters")
382
407
  end
383
408
  end
384
409
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe HCast do
3
+ describe HashCast do
4
4
 
5
5
  describe ".create" do
6
6
  it "should cast hash attributes" do
@@ -15,7 +15,7 @@ describe HCast do
15
15
  }
16
16
  }
17
17
 
18
- caster = HCast.create do
18
+ caster = HashCast.create do
19
19
  hash :contact do
20
20
  string :name
21
21
  integer :age
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'bundler/setup'
3
- require 'hcast'
3
+ require 'hash_cast'
4
4
 
5
5
  RSpec.configure do |config|
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hash_cast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Albert Gazizov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-28 00:00:00.000000000 Z
11
+ date: 2024-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -50,34 +50,35 @@ files:
50
50
  - ".rspec"
51
51
  - ".ruby-gemset"
52
52
  - ".ruby-version"
53
+ - CHANGELOG.md
53
54
  - Gemfile
54
55
  - Gemfile.lock
55
56
  - LICENSE.txt
56
57
  - README.md
57
58
  - Rakefile
58
- - hcast.gemspec
59
- - lib/hcast.rb
60
- - lib/hcast/attributes_caster.rb
61
- - lib/hcast/attributes_parser.rb
62
- - lib/hcast/caster.rb
63
- - lib/hcast/casters.rb
64
- - lib/hcast/casters/array_caster.rb
65
- - lib/hcast/casters/boolean_caster.rb
66
- - lib/hcast/casters/date_caster.rb
67
- - lib/hcast/casters/datetime_caster.rb
68
- - lib/hcast/casters/float_caster.rb
69
- - lib/hcast/casters/hash_caster.rb
70
- - lib/hcast/casters/integer_caster.rb
71
- - lib/hcast/casters/string_caster.rb
72
- - lib/hcast/casters/symbol_caster.rb
73
- - lib/hcast/casters/time_caster.rb
74
- - lib/hcast/concern.rb
75
- - lib/hcast/config.rb
76
- - lib/hcast/errors.rb
77
- - lib/hcast/metadata/attribute.rb
78
- - lib/hcast/version.rb
79
- - spec/hcast/caster_spec.rb
80
- - spec/hcast/hcast_spec.rb
59
+ - hash_cast.gemspec
60
+ - lib/hash_cast.rb
61
+ - lib/hash_cast/attributes_caster.rb
62
+ - lib/hash_cast/attributes_parser.rb
63
+ - lib/hash_cast/caster.rb
64
+ - lib/hash_cast/casters.rb
65
+ - lib/hash_cast/casters/array_caster.rb
66
+ - lib/hash_cast/casters/boolean_caster.rb
67
+ - lib/hash_cast/casters/date_caster.rb
68
+ - lib/hash_cast/casters/datetime_caster.rb
69
+ - lib/hash_cast/casters/float_caster.rb
70
+ - lib/hash_cast/casters/hash_caster.rb
71
+ - lib/hash_cast/casters/integer_caster.rb
72
+ - lib/hash_cast/casters/string_caster.rb
73
+ - lib/hash_cast/casters/symbol_caster.rb
74
+ - lib/hash_cast/casters/time_caster.rb
75
+ - lib/hash_cast/concern.rb
76
+ - lib/hash_cast/config.rb
77
+ - lib/hash_cast/errors.rb
78
+ - lib/hash_cast/metadata/attribute.rb
79
+ - lib/hash_cast/version.rb
80
+ - spec/hash_cast/caster_spec.rb
81
+ - spec/hash_cast/hash_cast_spec.rb
81
82
  - spec/spec_helper.rb
82
83
  homepage: http://github.com/droidlabs/hash_cast
83
84
  licenses:
@@ -103,6 +104,6 @@ signing_key:
103
104
  specification_version: 4
104
105
  summary: Declarative Hash Caster
105
106
  test_files:
106
- - spec/hcast/caster_spec.rb
107
- - spec/hcast/hcast_spec.rb
107
+ - spec/hash_cast/caster_spec.rb
108
+ - spec/hash_cast/hash_cast_spec.rb
108
109
  - spec/spec_helper.rb
@@ -1,13 +0,0 @@
1
- class HCast::Casters::StringCaster
2
-
3
- def self.cast(value, attr_name, options = {})
4
- if value.is_a?(String)
5
- value
6
- elsif value.is_a?(Symbol)
7
- value.to_s
8
- else
9
- raise HCast::Errors::CastingError, "should be a string"
10
- end
11
- end
12
-
13
- end
data/lib/hcast/casters.rb DELETED
@@ -1,13 +0,0 @@
1
- # List of build in casters
2
- module HCast::Casters
3
- require 'hcast/casters/array_caster'
4
- require 'hcast/casters/boolean_caster'
5
- require 'hcast/casters/date_caster'
6
- require 'hcast/casters/datetime_caster'
7
- require 'hcast/casters/float_caster'
8
- require 'hcast/casters/hash_caster'
9
- require 'hcast/casters/integer_caster'
10
- require 'hcast/casters/string_caster'
11
- require 'hcast/casters/symbol_caster'
12
- require 'hcast/casters/time_caster'
13
- end
data/lib/hcast/config.rb DELETED
@@ -1,11 +0,0 @@
1
- class HCast::Config
2
- attr_accessor :input_keys, :output_keys
3
-
4
- def input_keys
5
- @input_keys || :symbol
6
- end
7
-
8
- def output_keys
9
- @output_keys || :symbol
10
- end
11
- end
data/lib/hcast/version.rb DELETED
@@ -1,3 +0,0 @@
1
- module HCast
2
- VERSION = "0.4.0"
3
- end
data/lib/hcast.rb DELETED
@@ -1,46 +0,0 @@
1
- require 'hcast/version'
2
- require 'hcast/errors'
3
- require 'hcast/config'
4
- require 'hcast/casters'
5
- require 'hcast/concern.rb'
6
- require 'hcast/metadata/attribute'
7
- require 'hcast/attributes_parser'
8
- require 'hcast/attributes_caster'
9
- require 'hcast/caster'
10
-
11
- module HCast
12
- @@casters = {}
13
-
14
- # Defines caster without adding own class
15
- # @note Not yet implemented
16
- def self.create(&block)
17
- end
18
-
19
- # Returns list of defined casters
20
- def self.casters
21
- @@casters
22
- end
23
-
24
- # Adds new casters to HCast
25
- # Allow extend HCast with your own casters
26
- # @param caster_name [Symbol] caster name
27
- # @param caster [Class] caster
28
- def self.add_caster(caster_name, caster)
29
- @@casters[caster_name] = caster
30
- end
31
-
32
- def self.config
33
- @@config ||= HCast::Config.new
34
- end
35
- end
36
-
37
- HCast.add_caster(:array, HCast::Casters::ArrayCaster)
38
- HCast.add_caster(:boolean, HCast::Casters::BooleanCaster)
39
- HCast.add_caster(:date, HCast::Casters::DateCaster)
40
- HCast.add_caster(:datetime, HCast::Casters::DateTimeCaster)
41
- HCast.add_caster(:float, HCast::Casters::FloatCaster)
42
- HCast.add_caster(:hash, HCast::Casters::HashCaster)
43
- HCast.add_caster(:integer, HCast::Casters::IntegerCaster)
44
- HCast.add_caster(:string, HCast::Casters::StringCaster)
45
- HCast.add_caster(:symbol, HCast::Casters::SymbolCaster)
46
- HCast.add_caster(:time, HCast::Casters::TimeCaster)