bitty 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 oleg dashevskii
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,7 @@
1
+ = bitty
2
+
3
+ Description goes here.
4
+
5
+ == Copyright
6
+
7
+ Copyright (c) 2009 oleg dashevskii. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "bitty"
8
+ gem.summary = %Q{ActiveRecord plugin for rich bitfields}
9
+ gem.email = "olegdashevskii@gmail.com"
10
+ gem.homepage = "http://github.com/be9/bitty"
11
+ gem.authors = ["oleg dashevskii"]
12
+ gem.files.exclude '.gitignore', '.document'
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ end
15
+
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
18
+ end
19
+
20
+ require 'rake/testtask'
21
+ Rake::TestTask.new(:test) do |test|
22
+ test.libs << 'lib' << 'test'
23
+ test.pattern = 'test/**/*_test.rb'
24
+ test.verbose = true
25
+ end
26
+
27
+ begin
28
+ require 'rcov/rcovtask'
29
+ Rcov::RcovTask.new do |test|
30
+ test.libs << 'test'
31
+ test.pattern = 'test/**/*_test.rb'
32
+ test.verbose = true
33
+ end
34
+ rescue LoadError
35
+ task :rcov do
36
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
37
+ end
38
+ end
39
+
40
+ task :default => :test
41
+
42
+ require 'rake/rdoctask'
43
+ Rake::RDocTask.new do |rdoc|
44
+ if File.exist?('VERSION.yml')
45
+ config = YAML.load(File.read('VERSION.yml'))
46
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
47
+ else
48
+ version = ""
49
+ end
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "bitty #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
56
+
57
+ Jeweler::GemcutterTasks.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/bitty.gemspec ADDED
@@ -0,0 +1,55 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{bitty}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["oleg dashevskii"]
12
+ s.date = %q{2009-12-08}
13
+ s.email = %q{olegdashevskii@gmail.com}
14
+ s.extra_rdoc_files = [
15
+ "LICENSE",
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ "LICENSE",
20
+ "README.rdoc",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "bitty.gemspec",
24
+ "lib/bitty.rb",
25
+ "lib/bitty/bit_proxy.rb",
26
+ "test/bitty_test.rb",
27
+ "test/proxy_test.rb",
28
+ "test/support/models.rb",
29
+ "test/support/schema.rb",
30
+ "test/test_helper.rb"
31
+ ]
32
+ s.homepage = %q{http://github.com/be9/bitty}
33
+ s.rdoc_options = ["--charset=UTF-8"]
34
+ s.require_paths = ["lib"]
35
+ s.rubygems_version = %q{1.3.5}
36
+ s.summary = %q{ActiveRecord plugin for rich bitfields}
37
+ s.test_files = [
38
+ "test/bitty_test.rb",
39
+ "test/support/schema.rb",
40
+ "test/support/models.rb",
41
+ "test/proxy_test.rb",
42
+ "test/test_helper.rb"
43
+ ]
44
+
45
+ if s.respond_to? :specification_version then
46
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
47
+ s.specification_version = 3
48
+
49
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
50
+ else
51
+ end
52
+ else
53
+ end
54
+ end
55
+
@@ -0,0 +1,152 @@
1
+ module Bitty
2
+ # This class acts like a proxy. It presents you with all these
3
+ # bitfield methods, but it doesn't store the value itself.
4
+ def true?(val)
5
+ case val
6
+ when true, 1, /1|y|yes/i then true
7
+ else false
8
+ end
9
+ end
10
+
11
+ module_function :true?
12
+
13
+ class BitProxy
14
+ # this will be redefined in self.column=
15
+ def initialize(*args)
16
+ end
17
+
18
+ class <<self
19
+ def power2(name)
20
+ @power2[name.to_sym]
21
+ end
22
+
23
+ def bit_names=(names)
24
+ @power2 = {}
25
+ p = 1
26
+
27
+ names.each do |name|
28
+ n = name.to_sym
29
+
30
+ if @power2.include?(n)
31
+ raise ArgumentError, "Bit name #{n} repeated more that once!"
32
+ else
33
+ @power2[n] = p
34
+ p <<= 1
35
+ end
36
+ end
37
+
38
+ @power2.each do |name, bitmask|
39
+ inv = ~bitmask
40
+ class_eval <<-RUBY
41
+ def #{name}
42
+ (value & #{bitmask}) != 0
43
+ end
44
+
45
+ alias #{name}? #{name}
46
+
47
+ def #{name}=(val)
48
+ self.value = Bitty.true?(val) ? (value | #{bitmask}) : (value & #{inv})
49
+ end
50
+ RUBY
51
+ end
52
+ end
53
+
54
+ attr_reader :column
55
+
56
+ def column=(column)
57
+ @column = column
58
+
59
+ class_eval <<-RUBY
60
+ attr_accessor :model_object
61
+
62
+ def initialize(model_object)
63
+ self.model_object = model_object
64
+
65
+ super
66
+ end
67
+
68
+ def value
69
+ model_object[:#{column}]
70
+ end
71
+
72
+ def value=(newval)
73
+ model_object[:#{column}] = newval
74
+ end
75
+ RUBY
76
+ end
77
+
78
+ def named_scope(*args)
79
+ bits = args.extract_options!
80
+ args.each { |arg| bits[arg] = true }
81
+
82
+ masks = [0, 0]
83
+
84
+ bits.each do |name, val|
85
+ mask = power2(name)
86
+ raise ArgumentError, "invalid bit name #{name}" unless mask
87
+
88
+ masks[Bitty.true?(val) ? 1 : 0] |= mask
89
+ end
90
+
91
+ cond = [nil, nil]
92
+
93
+ if masks[0] != 0
94
+ cond[0] = "#{column} & #{masks[0]} = 0"
95
+ end
96
+
97
+ if masks[1] != 0
98
+ cond[1] = "#{column} & #{masks[1]} = #{masks[1]}"
99
+ end
100
+
101
+ { :conditions => cond.compact.map { |c| "(#{c})" } * ' AND ' }
102
+ end
103
+ end
104
+
105
+ def [](key)
106
+ bitmask = power2(key)
107
+
108
+ if bitmask
109
+ (value & bitmask) != 0
110
+ else
111
+ nil
112
+ end
113
+ end
114
+
115
+ def []=(key, val)
116
+ bitmask = power2(key)
117
+ raise ArgumentError, "unknown bitname: #{key}" unless bitmask
118
+
119
+ self.value = Bitty.true?(val) ? (value | bitmask) : (value & ~bitmask)
120
+ end
121
+
122
+ def set!(value)
123
+ case value
124
+ when Array
125
+ value.each { |key| self[key] = true }
126
+ when Hash
127
+ value.each { |key, val| self[key] = val }
128
+ when Fixnum
129
+ self.value = value
130
+ else
131
+ raise ArgumentError, "invalid value (must be Array/Hash/Fixnum)"
132
+ end
133
+ end
134
+
135
+ protected
136
+
137
+ # this will be redefined in self.column=
138
+ def value
139
+ raise
140
+ end
141
+
142
+ # this will be redefined in self.column=
143
+ def value=(newval)
144
+ raise
145
+ end
146
+
147
+ # power of 2, corresponding to key
148
+ def power2(key)
149
+ self.class.power2(key)
150
+ end
151
+ end
152
+ end
data/lib/bitty.rb ADDED
@@ -0,0 +1,45 @@
1
+ require File.join(File.dirname(__FILE__), 'bitty', 'bit_proxy')
2
+
3
+ module Bitty
4
+ module ActiveRecordExtensions
5
+ def bitty(field, *args)
6
+ field = field.to_sym
7
+
8
+ opts = args.extract_options!
9
+
10
+ proxy = Class.new(Bitty::BitProxy)
11
+ proxy.bit_names = args
12
+ proxy.column = opts[:column] || field
13
+
14
+ # TODO: opts[:default]
15
+ # TODO: opts[:named_scope]
16
+ # TODO: check if field has already been defined in superclass
17
+ write_inheritable_hash(:_bitty_fields, { field => proxy } )
18
+
19
+ class_eval <<-RUBY
20
+ def #{field}
21
+ @_bitty_#{field} ||=
22
+ self.class.read_inheritable_attribute(:_bitty_fields)[:#{field}].new(self)
23
+ end
24
+
25
+ def #{field}=(value)
26
+ #{field}.set!(value)
27
+ end
28
+ RUBY
29
+ end
30
+
31
+ def bitty_named_scope(name, bitty_field, *args)
32
+ proxy_class = read_inheritable_attribute(:_bitty_fields)[bitty_field]
33
+
34
+ if proxy_class
35
+ named_scope name, proxy_class.named_scope(*args)
36
+ else
37
+ raise ArgumentError, "There's no bitfield '#{bitty_field}' defined!"
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ if defined? ActiveRecord::Base
44
+ ActiveRecord::Base.send(:extend, Bitty::ActiveRecordExtensions)
45
+ end
@@ -0,0 +1,91 @@
1
+ require 'test_helper'
2
+ require 'support/models'
3
+ load 'support/schema.rb'
4
+
5
+ class Foo < ActiveRecord::Base
6
+ bitty :bitval, :uno, :dos, :tres, :quatro
7
+ end
8
+
9
+ class BittyTest < Test::Unit::TestCase
10
+ context "Foo" do
11
+ before { @foo = Foo.new }
12
+
13
+ it "should have :bitval attribute" do
14
+ @foo.should respond_to :bitval
15
+ @foo.should respond_to :bitval=
16
+ end
17
+
18
+ it "attribute method should return an instance of BitProxy" do
19
+ @foo.bitval.should be_kind_of(Bitty::BitProxy)
20
+ end
21
+
22
+ it "proxy value should correspond to model object column value" do
23
+ @foo2 = Foo.new
24
+ [0, 1, 200].each do |ival|
25
+ @foo[:bitval] = ival
26
+ @foo.bitval.send(:value).should == ival
27
+ @foo2.bitval.send(:value).should be_nil
28
+ end
29
+ end
30
+
31
+ it "proxy :value= should set model object's value" do
32
+ [0, 1, 200].each do |ival|
33
+ @foo.bitval.send(:value=, ival)
34
+ @foo[:bitval].should == ival
35
+ end
36
+ end
37
+
38
+ it "proxy :value= should not spoil other objects of the same type" do
39
+ @foo2 = Foo.new
40
+ @foo2.bitval.send(:value=, 333)
41
+ @foo.bitval.send(:value=, 1000)
42
+ @foo2.bitval.value.should == 333
43
+ end
44
+ end
45
+ end
46
+
47
+ class FooWithScope < Foo
48
+ bitty_named_scope :with_uno, :bitval, :uno
49
+ bitty_named_scope :without_4, :bitval, :quatro => 0
50
+ bitty_named_scope :with_110_, :bitval, :quatro => 1, :tres => 1, :dos => 0
51
+ end
52
+
53
+ class BittyNamedScopeTest < Test::Unit::TestCase
54
+ before :all do
55
+ @foos = (0..15).to_a.map do |v|
56
+ FooWithScope.create!(:bitval => v)
57
+ end
58
+ end
59
+
60
+ it ".with_uno should find values with :uno set" do
61
+ FooWithScope.with_uno.all.should == fs(1,3,5,7,9,11,13,15)
62
+ end
63
+
64
+ it ".with_4 should find values with :quatro unset" do
65
+ FooWithScope.without_4.all.should == fs(*(0..7).to_a)
66
+ end
67
+
68
+ it ".with_110_ should find by bit prefix 110" do
69
+ FooWithScope.with_110_.all.should == fs(12,13)
70
+ end
71
+
72
+ it "raises ArgumentError given invalid bitfield" do
73
+ lambda do
74
+ FooWithScope.class_eval do
75
+ bitty_named_scope :test_1, :nonexistent, :foo
76
+ end
77
+ end.should raise_error(ArgumentError)
78
+ end
79
+
80
+ it "raises ArgumentError given invalid bitname" do
81
+ lambda do
82
+ FooWithScope.class_eval do
83
+ bitty_named_scope :test_2, :bitval, :foo
84
+ end
85
+ end.should raise_error(ArgumentError)
86
+ end
87
+
88
+ def fs(*args)
89
+ args.map { |i| @foos[i] }
90
+ end
91
+ end
@@ -0,0 +1,196 @@
1
+ require 'test_helper'
2
+
3
+ class ValueTester < Hash
4
+ def value; self[:value] end
5
+ def value=(newval)
6
+ self[:value] = newval
7
+ end
8
+ end
9
+
10
+ class BittyProxyTest < Test::Unit::TestCase
11
+ before :all do
12
+ @proxy_class = Class.new(Bitty::BitProxy)
13
+ @proxy_class.bit_names = [:uno, :dos, :tres, :quatro]
14
+ @proxy_class.column = :value
15
+ end
16
+
17
+ before do
18
+ @mobject = ValueTester.new
19
+ @mobject.value = 0b1010
20
+ @foo = @proxy_class.new(@mobject)
21
+ end
22
+
23
+ [:to_sym, :to_s].each do |conv|
24
+ it "should allow to query values with [bitname.#{conv}]" do
25
+ @foo['uno'.send(conv)].should == false
26
+ @foo['dos'.send(conv)].should == true
27
+ @foo['tres'.send(conv)].should == false
28
+ @foo['quatro'.send(conv)].should == true
29
+ end
30
+
31
+ [true, '1', 1, 'yes', 'y', 'YES'].each do |yesval|
32
+ it "should set 1st bit with bitval['uno'.#{conv}] = #{yesval.inspect}" do
33
+ @foo['uno'.send(conv)] = yesval
34
+ @mobject.value.should == 0b1011
35
+ end
36
+
37
+ it "should set 2nd bit with bitval['dos'.#{conv}] = #{yesval.inspect}" do
38
+ @foo['dos'.send(conv)] = yesval
39
+ @mobject.value.should == 0b1010
40
+ end
41
+
42
+ it "should set 3rd bit with bitval['tres'.#{conv}] = #{yesval.inspect}" do
43
+ @foo['tres'.send(conv)] = yesval
44
+ @mobject.value.should == 0b1110
45
+ end
46
+ end
47
+
48
+ [false, '0', 0, 'no', 'n', 'NO'].each do |noval|
49
+ it "should reset 1st bit with bitval['uno'.#{conv}] = #{noval.inspect}" do
50
+ @foo['uno'.send(conv)] = noval
51
+ @mobject.value.should == 0b1010
52
+ end
53
+
54
+ it "should reset 2nd bit with bitval['dos'.#{conv}] = #{noval.inspect}" do
55
+ @foo['dos'.send(conv)] = noval
56
+ @mobject.value.should == 0b1000
57
+ end
58
+
59
+ it "should reset 4th bit with bitval['quatro'.#{conv}] = #{noval.inspect}" do
60
+ @foo['quatro'.send(conv)] = noval
61
+ @mobject.value.should == 0b0010
62
+ end
63
+ end
64
+ end
65
+
66
+ describe "#set!" do
67
+ it "should set value given integer" do
68
+ @foo.set! 0b1111
69
+ @mobject.value.should == 0b1111
70
+ end
71
+
72
+ it "should set value given a hash of values" do
73
+ @mobject.value = 0
74
+ @foo.set! :uno => 1, :quatro => 'yeah'
75
+ @mobject.value.should == 0b1001
76
+
77
+ @mobject.value = 0b1111
78
+ @foo.set! :dos => 0, :tres => 'N'
79
+ @mobject.value.should == 0b1001
80
+ end
81
+
82
+ it "should raise ArgumentError given hash with unknown bitname" do
83
+ @mobject.value = 0
84
+ lambda do
85
+ @foo.set! :uno => 1, :unknown => 'yeah'
86
+ end.should raise_error(ArgumentError)
87
+ end
88
+
89
+ it "should set value given an array of set bits" do
90
+ @mobject.value = 0
91
+ @foo.set! [:uno, :quatro]
92
+ @mobject.value.should == 0b1001
93
+
94
+ @mobject.value = 0
95
+ @foo.set! %w(dos tres)
96
+ @mobject.value.should == 0b0110
97
+ end
98
+
99
+ it "should raise ArgumentError given array with unknown bitnames" do
100
+ @mobject.value = 0
101
+ lambda do
102
+ @foo.set! [:uno, :unknown]
103
+ end.should raise_error(ArgumentError)
104
+ end
105
+
106
+ ["yeah", 123.321, nil, true, false, 1..10].each do |crap|
107
+ it "should raise ArgumentError given unsupported type (#{crap.inspect})" do
108
+ lambda do
109
+ @foo.set! crap
110
+ end.should raise_error(ArgumentError)
111
+ end
112
+ end
113
+ end
114
+
115
+ describe "named access" do
116
+ it "should allow to query bits directly" do
117
+ @foo.uno.should == false
118
+ @foo.dos.should == true
119
+ @foo.tres.should == false
120
+ @foo.quatro.should == true
121
+ end
122
+
123
+ it "should allow to query bits with question mark methods" do
124
+ @foo.uno?.should == false
125
+ @foo.dos?.should == true
126
+ @foo.tres?.should == false
127
+ @foo.quatro?.should == true
128
+ end
129
+
130
+ it "should allow to set bits directly" do
131
+ @mobject.value = 0b1010
132
+ @foo.uno = true
133
+ @mobject.value.should == 0b1011
134
+
135
+ @mobject.value = 0b1010
136
+ @foo.dos = 1
137
+ @mobject.value.should == 0b1010
138
+
139
+ @mobject.value = 0b1010
140
+ @foo.tres = 'YES'
141
+ @mobject.value.should == 0b1110
142
+ end
143
+
144
+ it "should allow to reset bits directly" do
145
+ @mobject.value = 0b1010
146
+ @foo.uno = false
147
+ @mobject.value.should == 0b1010
148
+
149
+ @mobject.value = 0b1010
150
+ @foo.dos = 'N'
151
+ @mobject.value.should == 0b1000
152
+
153
+ @mobject.value = 0b1010
154
+ @foo.quatro = 0
155
+ @mobject.value.should == 0b0010
156
+ end
157
+ end
158
+
159
+ describe "#named_scope" do
160
+ it "should generate valid condition for 0 bits" do
161
+ ns(:uno => 0).should == cond("(value & 1 = 0)")
162
+ ns(:uno => 0, :quatro => 0).should == cond("(value & 9 = 0)")
163
+ end
164
+
165
+ it "should generate valid condition for 1 bits" do
166
+ ns(:uno => 1).should == cond("(value & 1 = 1)")
167
+ ns(:uno => 1, :quatro => 1).should == cond("(value & 9 = 9)")
168
+ end
169
+
170
+ it "should generate valid condition for 1 bits given as array" do
171
+ ns(:uno).should == cond("(value & 1 = 1)")
172
+ ns(:uno, :quatro).should == cond("(value & 9 = 9)")
173
+ end
174
+
175
+ it "should generate valid condition for mixed bit values" do
176
+ ns(:uno => 1, :dos => 0, :tres => 1, :quatro => 0).should ==
177
+ cond("(value & 10 = 0) AND (value & 5 = 5)")
178
+ ns(:uno, :tres, :dos => 0, :quatro => 0).should ==
179
+ cond("(value & 10 = 0) AND (value & 5 = 5)")
180
+ end
181
+
182
+ it "should raise ArgumentError given invalid bitnames" do
183
+ lambda { ns(:bzz) }.should raise_error(ArgumentError)
184
+ lambda { ns(:bzz => 0) }.should raise_error(ArgumentError)
185
+ lambda { ns(:foo, :bzz => 0) }.should raise_error(ArgumentError)
186
+ end
187
+
188
+ def ns(*args)
189
+ @proxy_class.named_scope(*args)
190
+ end
191
+
192
+ def cond(str)
193
+ { :conditions => str }
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,3 @@
1
+ class Bar < ActiveRecord::Base
2
+ bitty :bar, :uno, :dos, :tres, :quatro, :column => :bitval
3
+ end
@@ -0,0 +1,9 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+ create_table "foos", :force => true do |t|
3
+ t.integer "bitval"
4
+ end
5
+
6
+ create_table "bars", :force => true do |t|
7
+ t.integer "bitval"
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'context'
4
+ require 'matchy'
5
+ require 'active_support'
6
+ require 'active_record'
7
+
8
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
9
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
10
+ require 'bitty'
11
+
12
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :dbfile => 'test.sqlite3')
13
+
14
+ #class Test::Unit::TestCase
15
+ #end
16
+
17
+ ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bitty
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - oleg dashevskii
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-08 00:00:00 +06:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: olegdashevskii@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.rdoc
25
+ files:
26
+ - LICENSE
27
+ - README.rdoc
28
+ - Rakefile
29
+ - VERSION
30
+ - bitty.gemspec
31
+ - lib/bitty.rb
32
+ - lib/bitty/bit_proxy.rb
33
+ - test/bitty_test.rb
34
+ - test/proxy_test.rb
35
+ - test/support/models.rb
36
+ - test/support/schema.rb
37
+ - test/test_helper.rb
38
+ has_rdoc: true
39
+ homepage: http://github.com/be9/bitty
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options:
44
+ - --charset=UTF-8
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.3.5
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: ActiveRecord plugin for rich bitfields
66
+ test_files:
67
+ - test/bitty_test.rb
68
+ - test/support/schema.rb
69
+ - test/support/models.rb
70
+ - test/proxy_test.rb
71
+ - test/test_helper.rb