no_integrity 0.4.0 → 0.5.0

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.
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gemfile
3
+ gemspec
data/README.md CHANGED
@@ -9,35 +9,52 @@ Simple hash serialization with loose type coercion. Built for ActiveRecord mode
9
9
  For starters, throw this in your Gemfile:
10
10
 
11
11
  gem "no_integrity"
12
-
12
+
13
13
  Then, add this to your class:
14
14
 
15
15
  class MrArbitrary < ActiveRecord::Base
16
16
  include NoIntegrity
17
-
17
+
18
18
  attr_accessor :some_random_hash
19
-
20
- no_attr_store :some_random_hash
19
+
21
20
  no_attribute :misc
22
- no_attribute :hair => 'String'
23
- no_attribute :age => 'Integer'
24
- no_attribute :height => 'String', :eyes => 'String', :friendly => 'Boolean'
25
- no_attribute [:cheese, :ham, :balogne]
21
+ no_attribute :hair, type: 'String'
22
+ no_attribute :age, type: 'Integer'
23
+ no_attribute :height, type: 'String'
24
+ no_attribute :eyes, type: 'String'
25
+ no_attribute :friendly, type: 'Boolean', default: true
26
+ no_attribute :cheese
27
+ no_attribute :ham
28
+ no_attribute :balogne
26
29
  end
27
-
30
+
28
31
  Finally, you can make calls like this:
29
32
 
30
33
  arbs = MrArbitrary.new
31
34
  arbs.friendly? # => false
32
35
  arbs.friendly = true
33
36
  arbs.friendly? # => true
34
-
37
+
35
38
  You can define as many attributes as you want, and you can specify any of the following coercion types:
36
39
 
37
40
  1. `String`
38
41
  2. `Integer`
39
42
  3. `Boolean`
40
43
 
44
+ ## Upgrading From 0.4.0
45
+
46
+ For `0.5.0` I added the ability to store default values for each of the attributes. This required some changes to the way that attributes were setup and stored for each object.
47
+
48
+ In your classes you'll need to convert from:
49
+
50
+ no_attribute hair: 'String'
51
+
52
+ To:
53
+
54
+ no_attribute :hair, type: 'String'
55
+
56
+ Also if you relied on any of the undocumented method calls, you'll need to update them so they can handle the new internal structure.
57
+
41
58
  ## Why?
42
59
 
43
60
  A while back, I needed serialized attributes but it either didn't work for my use case or it wasn't made yet. So, I wrote this gem.
@@ -1,54 +1,48 @@
1
1
  module NoIntegrity
2
-
2
+
3
3
  def self.included(a_module)
4
4
  a_module.module_eval do
5
5
  extend ClassMethods
6
6
  end
7
7
  end
8
-
8
+
9
9
  module ClassMethods
10
10
  def no_attr_store(storage_attribute = nil)
11
11
  if storage_attribute && @no_attr_store.nil?
12
12
  alias_no_attr_store(storage_attribute)
13
13
  @no_attr_store = storage_attribute
14
14
  end
15
-
15
+
16
16
  return @no_attr_store
17
17
  end
18
-
18
+
19
19
  def no_attributes
20
20
  @no_attributes || { }
21
21
  end
22
-
23
- def no_attribute(options)
22
+
23
+ def no_attribute(attribs, options = { })
24
24
  @no_attributes ||= { }
25
- if options.is_a?(Hash)
26
- options.keys.each do |attrib|
27
- @no_attributes[attrib] = options[attrib]
28
- setup_no_attribute_accessors(attrib, options[attrib])
29
- update_no_attribute_mappings(attrib, options[attrib])
30
- end
31
- elsif options.is_a?(Array)
32
- options.each do |attrib|
33
- @no_attributes[attrib] = nil
34
- setup_no_attribute_accessors(attrib, nil)
35
- end
36
- elsif options.is_a?(Symbol)
37
- setup_no_attribute_accessors(options)
25
+
26
+ attribs = [attribs] unless attribs.is_a?(Array)
27
+
28
+ attribs.each do |attrib|
29
+ @no_attributes[attrib.to_sym] = options
30
+ setup_no_attribute_accessors(attrib, options[:type])
31
+ update_no_attribute_mappings(attrib, options)
38
32
  end
39
33
  end
40
-
34
+
41
35
  def no_attribute_mappings
42
36
  @no_attribute_mappings
43
37
  end
44
-
38
+
45
39
  private
46
-
47
- def update_no_attribute_mappings(attrib, type)
40
+
41
+ def update_no_attribute_mappings(attrib, options)
48
42
  @no_attribute_mappings ||= { }
49
- @no_attribute_mappings[attrib.to_s] = type
43
+ @no_attribute_mappings[attrib.to_sym] = options
50
44
  end
51
-
45
+
52
46
  def setup_no_attribute_accessors(attrib, coercion_type = nil)
53
47
  module_eval <<-STR
54
48
  def #{attrib}; get_no_attribute('#{attrib}'); end
@@ -56,7 +50,7 @@ module NoIntegrity
56
50
  def #{attrib}=(v); set_no_attribute('#{attrib}', coerce_no_attribute_type(v, '#{coercion_type}')); end
57
51
  STR
58
52
  end
59
-
53
+
60
54
  def alias_no_attr_store(old_name)
61
55
  module_eval <<-STR, __FILE__, __LINE__ + 1
62
56
  def __no_attr_store; self.#{old_name}; end
@@ -64,13 +58,17 @@ module NoIntegrity
64
58
  def __no_attr_store=(v); self.#{old_name} = v; end
65
59
  STR
66
60
  end
67
-
61
+
68
62
  end
69
-
63
+
70
64
  def no_attributes
71
65
  self.class.no_attributes
72
66
  end
73
-
67
+
68
+ def no_attribute_mappings
69
+ self.class.no_attribute_mappings
70
+ end
71
+
74
72
  def update_no_attributes(new_attributes)
75
73
  raise "Type mismatch: I received a #{new_attributes.class} when I was expecting a Hash." unless new_attributes.is_a?(Hash)
76
74
  new_attributes.each do |key, value|
@@ -78,31 +76,33 @@ module NoIntegrity
78
76
  end
79
77
  return self.send(self.class.no_attr_store)
80
78
  end
81
-
79
+
82
80
  private
83
-
81
+
84
82
  def get_no_attribute(attribute_name)
85
83
  return nil unless self.__no_attr_store.is_a?(Hash)
86
84
  self.__no_attr_store = normalize_keys(__no_attr_store)
87
- self.__no_attr_store[attribute_name.to_s]
85
+ no_val = self.__no_attr_store[attribute_name.to_sym]
86
+
87
+ no_val.nil? ? no_attribute_mappings[attribute_name.to_sym][:default] : no_val
88
88
  end
89
-
89
+
90
90
  def set_no_attribute(attribute_name, value)
91
91
  self.__no_attr_store = normalize_keys(__no_attr_store)
92
92
  if self.__no_attr_store.is_a?(Hash)
93
- self.__no_attr_store[attribute_name.to_s] = value
93
+ self.__no_attr_store[attribute_name.to_sym] = value
94
94
  else
95
- self.__no_attr_store = { attribute_name.to_s => value }
95
+ self.__no_attr_store = { attribute_name.to_sym => value }
96
96
  end
97
97
  end
98
-
98
+
99
99
  def normalize_keys(store)
100
100
  return store if @__performed_key_normalization || !store.is_a?(Hash)
101
- store.keys.each { |key| store[key.to_s] = store.delete(key) }
101
+ store.keys.each { |key| store[key.to_sym] = store.delete(key) }
102
102
  @__performed_key_normalization = true
103
103
  return store
104
104
  end
105
-
105
+
106
106
  def coerce_no_attribute_type(value, type)
107
107
  return value if (type == nil) || (type == '')
108
108
  value = case type
@@ -117,8 +117,8 @@ module NoIntegrity
117
117
  else
118
118
  raise "Unsure of what to do with #{type}!!"
119
119
  end
120
-
120
+
121
121
  return value
122
122
  end
123
-
123
+
124
124
  end
@@ -1,3 +1,3 @@
1
1
  module NoIntegrity
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -16,7 +16,6 @@ Gem::Specification.new do |gem|
16
16
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
  gem.require_paths = ["lib"]
19
-
20
- gem.add_development_dependency(%q<rspec>, ["= 2.9.0"])
21
- gem.add_development_dependency(%q<ZenTest>, ["= 4.5.0"])
19
+
20
+ gem.add_development_dependency(%q<rspec>, ["~> 3.4.0"])
22
21
  end
@@ -5,12 +5,12 @@ describe NoIntegrity do
5
5
  context "class methods" do
6
6
 
7
7
  it "stores mappings of the various types of attributes" do
8
- MrArbitrary.no_attribute_mappings['hair'].should == 'String'
9
- MrArbitrary.no_attribute_mappings['friendly'].should == 'Boolean'
8
+ expect(MrArbitrary.no_attribute_mappings[:hair][:type]).to eq('String')
9
+ expect(MrArbitrary.no_attribute_mappings[:friendly][:type]).to eq('Boolean')
10
10
  end
11
11
 
12
12
  end
13
-
13
+
14
14
  context "An object with NoIntegrity" do
15
15
 
16
16
  before(:each) do
@@ -21,97 +21,101 @@ describe NoIntegrity do
21
21
  end
22
22
 
23
23
  it "should know where the attributes are being stored" do
24
- @arbs.class.no_attr_store.should be_an_instance_of Symbol
24
+ expect(@arbs.class.no_attr_store).to be_an_instance_of Symbol
25
25
  end
26
-
26
+
27
27
  it "should be able to get all of the attributes" do
28
- @arbs.__no_attr_store.should be_an_instance_of Hash
28
+ expect(@arbs.__no_attr_store).to be_an_instance_of Hash
29
29
  end
30
-
30
+
31
31
  it "should be able to list the attributes it is familiar with" do
32
- @arbs.no_attributes.should be_an_instance_of Hash
32
+ expect(@arbs.no_attributes).to be_an_instance_of Hash
33
33
  end
34
34
 
35
35
  it "should be able to retrieve attributes from the store" do
36
- @arbs.hair.should == 'brown'
36
+ expect(@arbs.hair).to eq('brown')
37
37
  end
38
38
 
39
39
  it "should be able to have an attribute assigned" do
40
40
  @arbs.hair = "black"
41
- @arbs.hair.should == 'black'
41
+ expect(@arbs.hair).to eq('black')
42
42
  end
43
-
43
+
44
44
  it "should be able to mass assign attributes" do
45
45
  @arbs.update_no_attributes( :hair => 'blonde' )
46
- @arbs.hair.should == 'blonde'
46
+ expect(@arbs.hair).to eq('blonde')
47
47
  end
48
-
48
+
49
49
  it "should coerce boolean types" do
50
50
  @arbs.friendly = 1
51
- @arbs.should be_friendly
52
- @arbs.friendly.should == true
51
+ expect(@arbs).to be_friendly
52
+ expect(@arbs.friendly).to eq(true)
53
53
  end
54
-
54
+
55
55
  it "should coerce interger types" do
56
56
  @arbs.age = "25"
57
- @arbs.age.should == 25
57
+ expect(@arbs.age).to eq(25)
58
58
  end
59
-
59
+
60
60
  it "should allow arbitrary types" do
61
61
  @arbs.misc = ['junk']
62
- @arbs.misc.should == ['junk']
62
+ expect(@arbs.misc).to eq(['junk'])
63
63
  end
64
-
64
+
65
65
  it "should allow for arrays of arbitary types" do
66
- @arbs.no_attributes.keys.should include(:cheese)
67
- @arbs.no_attributes.keys.should include(:ham)
68
- @arbs.no_attributes.keys.should include(:balogne)
66
+ expect(@arbs.no_attributes.keys).to include(:cheese)
67
+ expect(@arbs.no_attributes.keys).to include(:ham)
68
+ expect(@arbs.no_attributes.keys).to include(:balogne)
69
69
  end
70
-
70
+
71
71
  it "should allow for hashes of types" do
72
- @arbs.no_attributes.keys.should include(:height)
73
- @arbs.no_attributes.keys.should include(:eyes)
74
- @arbs.no_attributes.keys.should include(:friendly)
72
+ expect(@arbs.no_attributes.keys).to include(:height)
73
+ expect(@arbs.no_attributes.keys).to include(:eyes)
74
+ expect(@arbs.no_attributes.keys).to include(:friendly)
75
75
  end
76
-
76
+
77
77
  it "should coerce types on mass assignment" do
78
78
  @arbs.update_no_attributes(:age => "22")
79
- @arbs.age.should == 22
79
+ expect(@arbs.age).to eq(22)
80
80
  end
81
-
81
+
82
82
  it "should coerce booleans from numbers" do
83
83
  @arbs.friendly = "0"
84
- @arbs.should_not be_friendly
84
+ expect(@arbs).not_to be_friendly
85
85
  @arbs.friendly = "1"
86
- @arbs.should be_friendly
86
+ expect(@arbs).to be_friendly
87
87
  end
88
-
88
+
89
89
  it "should coerce booleans from strings" do
90
90
  @arbs.friendly = "false"
91
- @arbs.should_not be_friendly
91
+ expect(@arbs).not_to be_friendly
92
92
  @arbs.friendly = "true"
93
- @arbs.should be_friendly
93
+ expect(@arbs).to be_friendly
94
94
  end
95
-
95
+
96
96
  it "should not allow mass assignment of attributes if they are not in a hash" do
97
- lambda { @arbs.update_no_attributes("monkey") }.should raise_exception("Type mismatch: I received a String when I was expecting a Hash.")
97
+ expect { @arbs.update_no_attributes("monkey") }.to raise_exception("Type mismatch: I received a String when I was expecting a Hash.")
98
98
  end
99
-
99
+
100
100
  it "should return nil for every attribute if the store is not a hash" do
101
101
  @arbs.some_random_hash = nil
102
- @arbs.hair.should be_nil
102
+ expect(@arbs.hair).to be_nil
103
103
  end
104
-
104
+
105
105
  it "should set the store to a hash when setting an attribute" do
106
106
  @arbs.some_random_hash = "POTATO"
107
107
  @arbs.eyes = 'red'
108
- @arbs.eyes.should == 'red'
108
+ expect(@arbs.eyes).to eq('red')
109
109
  end
110
-
110
+
111
111
  it "should return an empty hash if there are no defined attributes" do
112
- @arbs.no_attributes.should be_an_instance_of(Hash)
112
+ expect(@arbs.no_attributes).to be_an_instance_of(Hash)
113
+ end
114
+
115
+ it "returns the default value" do
116
+ expect(@arbs.friendly).to eq true
113
117
  end
114
118
 
115
119
  end
116
-
120
+
117
121
  end
@@ -1,21 +1,26 @@
1
1
  require 'rubygems'
2
2
  require 'rspec'
3
- require 'lib/no_integrity'
3
+ require './lib/no_integrity'
4
4
 
5
5
  class MrArbitrary
6
6
  include NoIntegrity
7
-
7
+
8
8
  attr_accessor :some_random_hash
9
-
9
+
10
10
  no_attr_store :some_random_hash
11
+
11
12
  no_attribute :misc
12
- no_attribute :hair => 'String'
13
- no_attribute :age => 'Integer'
14
- no_attribute :height => 'String', :eyes => 'String', :friendly => 'Boolean'
15
- no_attribute [:cheese, :ham, :balogne]
16
-
13
+ no_attribute :hair, type: 'String'
14
+ no_attribute :age, type: 'Integer'
15
+ no_attribute :height, type: 'String'
16
+ no_attribute :eyes, type: 'String'
17
+ no_attribute :friendly, type: 'Boolean', default: true
18
+ no_attribute :cheese
19
+ no_attribute :ham
20
+ no_attribute :balogne
21
+
17
22
  def initialize(*args)
18
- @some_random_hash ||= { :hair => 'brown' }
23
+ @some_random_hash ||= { hair: 'brown' }
19
24
  end
20
-
25
+
21
26
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: no_integrity
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 11
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 4
8
+ - 5
9
9
  - 0
10
- version: 0.4.0
10
+ version: 0.5.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Patrick Tulskie
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2014-05-16 00:00:00 -04:00
18
+ date: 2016-02-04 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -24,32 +24,16 @@ dependencies:
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - "="
27
+ - - ~>
28
28
  - !ruby/object:Gem::Version
29
- hash: 43
30
- segments:
31
- - 2
32
- - 9
33
- - 0
34
- version: 2.9.0
35
- type: :development
36
- version_requirements: *id001
37
- - !ruby/object:Gem::Dependency
38
- name: ZenTest
39
- prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - "="
44
- - !ruby/object:Gem::Version
45
- hash: 43
29
+ hash: 23
46
30
  segments:
31
+ - 3
47
32
  - 4
48
- - 5
49
33
  - 0
50
- version: 4.5.0
34
+ version: 3.4.0
51
35
  type: :development
52
- version_requirements: *id002
36
+ version_requirements: *id001
53
37
  description: Add attributes without any sort of integrity to your ActiveRecord or other types of objects.
54
38
  email:
55
39
  - patricktulskie@gmail.com
@@ -64,7 +48,6 @@ files:
64
48
  - Gemfile
65
49
  - README.md
66
50
  - Rakefile
67
- - autotest/discover.rb
68
51
  - lib/no_integrity.rb
69
52
  - lib/no_integrity/no_integrity.rb
70
53
  - lib/no_integrity/version.rb
@@ -1 +0,0 @@
1
- Autotest.add_discovery { "rspec2" }