no_integrity 0.3.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.
- data/.gitignore +3 -0
- data/Gemfile +3 -0
- data/Rakefile +16 -0
- data/VERSION +1 -0
- data/autotest/discover.rb +1 -0
- data/lib/no_integrity.rb +1 -0
- data/lib/no_integrity/no_integrity.rb +114 -0
- data/lib/no_integrity/version.rb +3 -0
- data/no_integrity.gemspec +22 -0
- data/spec/no_integrity_spec.rb +108 -0
- data/spec/rcov.opts +2 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +21 -0
- metadata +114 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gemspec|
|
7
|
+
gemspec.name = "no_integrity"
|
8
|
+
gemspec.summary = "Key/value store inside of your model."
|
9
|
+
gemspec.description = "NoIntegrity adds a key/value store inside of your model and then creates the necessary getter/setter methods for accessing those keys as though they were direct attributes of the model."
|
10
|
+
gemspec.email = "patricktulskie@gmail.com"
|
11
|
+
gemspec.homepage = "http://localhost"
|
12
|
+
gemspec.authors = ["Patrick Tulskie"]
|
13
|
+
end
|
14
|
+
rescue LoadError
|
15
|
+
puts "Jeweler not available. Install it with: gem install jeweler"
|
16
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|
@@ -0,0 +1 @@
|
|
1
|
+
Autotest.add_discovery { "rspec2" }
|
data/lib/no_integrity.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'no_integrity/no_integrity'
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module NoIntegrity
|
2
|
+
|
3
|
+
def self.included(a_module)
|
4
|
+
a_module.module_eval do
|
5
|
+
extend ClassMethods
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def no_attr_store(storage_attribute = nil)
|
11
|
+
if storage_attribute && @no_attr_store.nil?
|
12
|
+
alias_no_attr_store(storage_attribute)
|
13
|
+
@no_attr_store = storage_attribute
|
14
|
+
end
|
15
|
+
|
16
|
+
return @no_attr_store
|
17
|
+
end
|
18
|
+
|
19
|
+
def no_attributes
|
20
|
+
@no_attributes || { }
|
21
|
+
end
|
22
|
+
|
23
|
+
def no_attribute(options)
|
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_functions(attrib, options[attrib])
|
29
|
+
end
|
30
|
+
elsif options.is_a?(Array)
|
31
|
+
options.each do |attrib|
|
32
|
+
@no_attributes[attrib] = nil
|
33
|
+
setup_no_attribute_functions(attrib, nil)
|
34
|
+
end
|
35
|
+
elsif options.is_a?(Symbol)
|
36
|
+
setup_no_attribute_functions(options)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def setup_no_attribute_functions(attrib, coercion_type = nil)
|
43
|
+
module_eval <<-STR
|
44
|
+
def #{attrib}; get_no_attribute('#{attrib}'); end
|
45
|
+
def #{attrib}?; !!get_no_attribute('#{attrib}'); end
|
46
|
+
def #{attrib}=(v); set_no_attribute('#{attrib}', coerce_no_attribute_type(v, '#{coercion_type}')); end
|
47
|
+
STR
|
48
|
+
end
|
49
|
+
|
50
|
+
def alias_no_attr_store(old_name)
|
51
|
+
module_eval <<-STR, __FILE__, __LINE__ + 1
|
52
|
+
def __no_attr_store; self.#{old_name}; end
|
53
|
+
def __no_attr_store?; self.#{old_name}?; end
|
54
|
+
def __no_attr_store=(v); self.#{old_name} = v; end
|
55
|
+
STR
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
def no_attributes
|
61
|
+
self.class.no_attributes
|
62
|
+
end
|
63
|
+
|
64
|
+
def update_no_attributes(new_attributes)
|
65
|
+
raise "Type mismatch: I received a #{new_attributes.class} when I was expecting a Hash." unless new_attributes.is_a?(Hash)
|
66
|
+
new_attributes.each do |key, value|
|
67
|
+
self.send("#{key}=", value)
|
68
|
+
end
|
69
|
+
return self.send(self.class.no_attr_store)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def get_no_attribute(attribute_name)
|
75
|
+
return nil unless self.__no_attr_store.is_a?(Hash)
|
76
|
+
self.__no_attr_store = normalize_keys(__no_attr_store)
|
77
|
+
self.__no_attr_store[attribute_name.to_s]
|
78
|
+
end
|
79
|
+
|
80
|
+
def set_no_attribute(attribute_name, value)
|
81
|
+
self.__no_attr_store = normalize_keys(__no_attr_store)
|
82
|
+
if self.__no_attr_store.is_a?(Hash)
|
83
|
+
self.__no_attr_store[attribute_name.to_s] = value
|
84
|
+
else
|
85
|
+
self.__no_attr_store = { attribute_name.to_s => value }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def normalize_keys(store)
|
90
|
+
return store if @__performed_key_normalization || !store.is_a?(Hash)
|
91
|
+
store.keys.each { |key| store[key.to_s] = store.delete(key) }
|
92
|
+
@__performed_key_normalization = true
|
93
|
+
return store
|
94
|
+
end
|
95
|
+
|
96
|
+
def coerce_no_attribute_type(value, type)
|
97
|
+
return value if (type == nil) || (type == '')
|
98
|
+
value = case type
|
99
|
+
when 'Boolean';
|
100
|
+
case value.to_s
|
101
|
+
when "true", "1"; true
|
102
|
+
when "false", "0"; false
|
103
|
+
else; !!value
|
104
|
+
end
|
105
|
+
when 'Integer'; value.to_i
|
106
|
+
when 'String'; value.to_s
|
107
|
+
else
|
108
|
+
raise "Unsure of what to do with #{type}!!"
|
109
|
+
end
|
110
|
+
|
111
|
+
return value
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'no_integrity/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = %q{no_integrity}
|
7
|
+
gem.version = NoIntegrity::VERSION
|
8
|
+
|
9
|
+
gem.authors = ["Patrick Tulskie"]
|
10
|
+
gem.email = ["patricktulskie@gmail.com"]
|
11
|
+
gem.summary = %q{Key/value store inside of your model.}
|
12
|
+
gem.description = %q{Add attributes without any sort of integrity to your ActiveRecord or other types of objects.}
|
13
|
+
gem.homepage = "http://github.com/PatrickTulskie/no_integrity"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
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"])
|
22
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NoIntegrity do
|
4
|
+
|
5
|
+
context "An object with NoIntegrity" do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@arbs = MrArbitrary.new
|
9
|
+
end
|
10
|
+
after(:each) do
|
11
|
+
@arbs = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should know where the attributes are being stored" do
|
15
|
+
@arbs.class.no_attr_store.should be_an_instance_of Symbol
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should be able to get all of the attributes" do
|
19
|
+
@arbs.__no_attr_store.should be_an_instance_of Hash
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should be able to list the attributes it is familiar with" do
|
23
|
+
@arbs.no_attributes.should be_an_instance_of Hash
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should be able to retrieve attributes from the store" do
|
27
|
+
@arbs.hair.should == 'brown'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should be able to have an attribute assigned" do
|
31
|
+
@arbs.hair = "black"
|
32
|
+
@arbs.hair.should == 'black'
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should be able to mass assign attributes" do
|
36
|
+
@arbs.update_no_attributes( :hair => 'blonde' )
|
37
|
+
@arbs.hair.should == 'blonde'
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should coerce boolean types" do
|
41
|
+
@arbs.friendly = 1
|
42
|
+
@arbs.should be_friendly
|
43
|
+
@arbs.friendly.should == true
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should coerce interger types" do
|
47
|
+
@arbs.age = "25"
|
48
|
+
@arbs.age.should == 25
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should allow arbitrary types" do
|
52
|
+
@arbs.misc = ['junk']
|
53
|
+
@arbs.misc.should == ['junk']
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should allow for arrays of arbitary types" do
|
57
|
+
@arbs.no_attributes.keys.should include(:cheese)
|
58
|
+
@arbs.no_attributes.keys.should include(:ham)
|
59
|
+
@arbs.no_attributes.keys.should include(:balogne)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should allow for hashes of types" do
|
63
|
+
@arbs.no_attributes.keys.should include(:height)
|
64
|
+
@arbs.no_attributes.keys.should include(:eyes)
|
65
|
+
@arbs.no_attributes.keys.should include(:friendly)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should coerce types on mass assignment" do
|
69
|
+
@arbs.update_no_attributes(:age => "22")
|
70
|
+
@arbs.age.should == 22
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should coerce booleans from numbers" do
|
74
|
+
@arbs.friendly = "0"
|
75
|
+
@arbs.should_not be_friendly
|
76
|
+
@arbs.friendly = "1"
|
77
|
+
@arbs.should be_friendly
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should coerce booleans from strings" do
|
81
|
+
@arbs.friendly = "false"
|
82
|
+
@arbs.should_not be_friendly
|
83
|
+
@arbs.friendly = "true"
|
84
|
+
@arbs.should be_friendly
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should not allow mass assignment of attributes if they are not in a hash" do
|
88
|
+
lambda { @arbs.update_no_attributes("monkey") }.should raise_exception("Type mismatch: I received a String when I was expecting a Hash.")
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should return nil for every attribute if the store is not a hash" do
|
92
|
+
@arbs.some_random_hash = nil
|
93
|
+
@arbs.hair.should be_nil
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should set the store to a hash when setting an attribute" do
|
97
|
+
@arbs.some_random_hash = "POTATO"
|
98
|
+
@arbs.eyes = 'red'
|
99
|
+
@arbs.eyes.should == 'red'
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should return an empty hash if there are no defined attributes" do
|
103
|
+
@arbs.no_attributes.should be_an_instance_of(Hash)
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
data/spec/rcov.opts
ADDED
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rspec'
|
3
|
+
require 'lib/no_integrity'
|
4
|
+
|
5
|
+
class MrArbitrary
|
6
|
+
include NoIntegrity
|
7
|
+
|
8
|
+
attr_accessor :some_random_hash
|
9
|
+
|
10
|
+
no_attr_store :some_random_hash
|
11
|
+
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
|
+
|
17
|
+
def initialize(*args)
|
18
|
+
@some_random_hash ||= { :hair => 'brown' }
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: no_integrity
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 17
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 3
|
9
|
+
- 1
|
10
|
+
version: 0.3.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Patrick Tulskie
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2013-02-27 00:00:00 -05:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - "="
|
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
|
46
|
+
segments:
|
47
|
+
- 4
|
48
|
+
- 5
|
49
|
+
- 0
|
50
|
+
version: 4.5.0
|
51
|
+
type: :development
|
52
|
+
version_requirements: *id002
|
53
|
+
description: Add attributes without any sort of integrity to your ActiveRecord or other types of objects.
|
54
|
+
email:
|
55
|
+
- patricktulskie@gmail.com
|
56
|
+
executables: []
|
57
|
+
|
58
|
+
extensions: []
|
59
|
+
|
60
|
+
extra_rdoc_files: []
|
61
|
+
|
62
|
+
files:
|
63
|
+
- .gitignore
|
64
|
+
- Gemfile
|
65
|
+
- Rakefile
|
66
|
+
- VERSION
|
67
|
+
- autotest/discover.rb
|
68
|
+
- lib/no_integrity.rb
|
69
|
+
- lib/no_integrity/no_integrity.rb
|
70
|
+
- lib/no_integrity/version.rb
|
71
|
+
- no_integrity.gemspec
|
72
|
+
- spec/no_integrity_spec.rb
|
73
|
+
- spec/rcov.opts
|
74
|
+
- spec/spec.opts
|
75
|
+
- spec/spec_helper.rb
|
76
|
+
has_rdoc: true
|
77
|
+
homepage: http://github.com/PatrickTulskie/no_integrity
|
78
|
+
licenses: []
|
79
|
+
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
hash: 3
|
91
|
+
segments:
|
92
|
+
- 0
|
93
|
+
version: "0"
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
hash: 3
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
requirements: []
|
104
|
+
|
105
|
+
rubyforge_project:
|
106
|
+
rubygems_version: 1.5.3
|
107
|
+
signing_key:
|
108
|
+
specification_version: 3
|
109
|
+
summary: Key/value store inside of your model.
|
110
|
+
test_files:
|
111
|
+
- spec/no_integrity_spec.rb
|
112
|
+
- spec/rcov.opts
|
113
|
+
- spec/spec.opts
|
114
|
+
- spec/spec_helper.rb
|