no_integrity 0.4.0 → 0.5.0

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