bitty 0.1.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/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