bit_mask 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +15 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +89 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/bit_mask.gemspec +73 -0
- data/lib/bit_mask.rb +232 -0
- data/spec/bit_mask_spec.rb +87 -0
- data/spec/models/car_search.rb +27 -0
- data/spec/models/dealership_search.rb +5 -0
- data/spec/spec_helper.rb +13 -0
- metadata +138 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
# Add dependencies to develop your gem here.
|
6
|
+
# Include everything needed to run rake, tests, features, etc.
|
7
|
+
gem 'activesupport'
|
8
|
+
|
9
|
+
group :development do
|
10
|
+
gem "shoulda", ">= 0"
|
11
|
+
gem "bundler", "~> 1.0.0"
|
12
|
+
gem "jeweler", "~> 1.5.2"
|
13
|
+
gem "rcov", ">= 0"
|
14
|
+
gem "rspec"
|
15
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Ryan Ong
|
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,89 @@
|
|
1
|
+
= bit_mask
|
2
|
+
|
3
|
+
A simple class that allows you to store data in a bit mask. It automagically manages bit sizes and base conversion of binary bitmask.
|
4
|
+
|
5
|
+
== Usage
|
6
|
+
|
7
|
+
When writing these config maps. Try to put the mose used options first so the string can be shorter.
|
8
|
+
|
9
|
+
require 'rubygems'
|
10
|
+
require 'bit_mask'
|
11
|
+
class SearchParams < BitMask
|
12
|
+
|
13
|
+
# first set base defaults is 62
|
14
|
+
# Integer up to 62
|
15
|
+
set_base 62
|
16
|
+
|
17
|
+
field :air, :values => 2, # number of options must be 2 or greater
|
18
|
+
field :color, :values => ['blue','green','red'] # bit_mask can map arrays of data, the default setting will be the first value in the array
|
19
|
+
field :body_style, :values => [:sedan,:mini_van,:suv] # Array values can be anything that can be found using the Array#index function
|
20
|
+
field :transmission,:values => 6,
|
21
|
+
field :min_price, :values => (50..100).to_a # ( just a way to store ranges of numbers)
|
22
|
+
field :max_price, :values => (1..5).to_a.map {|n| 10000+(n*20)},
|
23
|
+
|
24
|
+
# overwrite default accessors
|
25
|
+
|
26
|
+
def body_style=(value)
|
27
|
+
self.write_attribute(:body_style,value).to_sym
|
28
|
+
end
|
29
|
+
|
30
|
+
def body_style
|
31
|
+
self.read_attribute(:body_style).to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
# initialize
|
37
|
+
@search = SearchParams.new
|
38
|
+
|
39
|
+
# set a single value
|
40
|
+
@search[:color]='red'
|
41
|
+
@search.color = 'red'
|
42
|
+
|
43
|
+
# get a single value
|
44
|
+
@search.color # the same as @search[:color]
|
45
|
+
|
46
|
+
# replace values in config with another hash
|
47
|
+
@search.replace({:air=>1})
|
48
|
+
|
49
|
+
# convert to small compact string
|
50
|
+
@search.to_s
|
51
|
+
@search.to_s(36) # choose base different from default
|
52
|
+
@search.to_s('asldkfjv') # use custom character sets for encoding
|
53
|
+
@search.dump
|
54
|
+
|
55
|
+
# load
|
56
|
+
SearchParams.load(@search.dump)
|
57
|
+
SearchParams.load(@search.to_s(36),36) # load from different base
|
58
|
+
SearchParams.load(@search.to_s('asldkfjv'),'asldkfjv')
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
== TODO
|
63
|
+
|
64
|
+
* Impliment more tests
|
65
|
+
* Storage of strings?
|
66
|
+
* If binary options and default 1, user inverse
|
67
|
+
* create javascript version for easy communication between ruby and javascript
|
68
|
+
|
69
|
+
== Contributing to bit_mask
|
70
|
+
|
71
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
72
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
73
|
+
* Fork the project
|
74
|
+
* Start a feature/bugfix branch
|
75
|
+
* Commit and push until you are happy with your contribution
|
76
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
77
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
78
|
+
|
79
|
+
== Credits
|
80
|
+
|
81
|
+
Ryan Ong - ryanong@gmail.com
|
82
|
+
|
83
|
+
Developed for and with CarZen[link:http://carzen.com]
|
84
|
+
|
85
|
+
== Copyright
|
86
|
+
|
87
|
+
Copyright (c) 2011 Ryan Ong. See LICENSE.txt for
|
88
|
+
further details.
|
89
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "bit_mask"
|
16
|
+
gem.homepage = "http://github.com/ryanong/bit_hash"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{bit_mask allows you to serialize/bitmask simple data sets into short compact ascii strings.}
|
19
|
+
gem.description = %Q{bit_mask creates a simple api to create bit mask models. By bit masking dataing you can compress the amount of data that needs to be sent between servers and clients}
|
20
|
+
gem.email = "ryanong@gmail.com"
|
21
|
+
gem.authors = ["Ryan Ong"]
|
22
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rspec/core'
|
29
|
+
require 'rspec/core/rake_task'
|
30
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
31
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
32
|
+
end
|
33
|
+
|
34
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
35
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
36
|
+
spec.rcov = true
|
37
|
+
end
|
38
|
+
|
39
|
+
task :default => :spec
|
40
|
+
|
41
|
+
require 'rake/rdoctask'
|
42
|
+
Rake::RDocTask.new do |rdoc|
|
43
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
44
|
+
|
45
|
+
rdoc.rdoc_dir = 'rdoc'
|
46
|
+
rdoc.title = "bit_mask #{version}"
|
47
|
+
rdoc.rdoc_files.include('README*')
|
48
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
49
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/bit_mask.gemspec
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{bit_mask}
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = [%q{Ryan Ong}]
|
12
|
+
s.date = %q{2011-07-18}
|
13
|
+
s.description = %q{bit_mask creates a simple api to create bit mask models. By bit masking dataing you can compress the amount of data that needs to be sent between servers and clients}
|
14
|
+
s.email = %q{ryanong@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".rspec",
|
22
|
+
"Gemfile",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"bit_mask.gemspec",
|
28
|
+
"lib/bit_mask.rb",
|
29
|
+
"spec/bit_mask_spec.rb",
|
30
|
+
"spec/models/car_search.rb",
|
31
|
+
"spec/models/dealership_search.rb",
|
32
|
+
"spec/spec_helper.rb"
|
33
|
+
]
|
34
|
+
s.homepage = %q{http://github.com/ryanong/bit_hash}
|
35
|
+
s.licenses = [%q{MIT}]
|
36
|
+
s.require_paths = [%q{lib}]
|
37
|
+
s.rubygems_version = %q{1.8.5}
|
38
|
+
s.summary = %q{bit_mask allows you to serialize/bitmask simple data sets into short compact ascii strings.}
|
39
|
+
s.test_files = [
|
40
|
+
"spec/bit_mask_spec.rb",
|
41
|
+
"spec/models/car_search.rb",
|
42
|
+
"spec/models/dealership_search.rb",
|
43
|
+
"spec/spec_helper.rb"
|
44
|
+
]
|
45
|
+
|
46
|
+
if s.respond_to? :specification_version then
|
47
|
+
s.specification_version = 3
|
48
|
+
|
49
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
50
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
51
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
52
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
53
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
54
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
55
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
56
|
+
else
|
57
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
58
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
59
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
60
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
61
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
62
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
63
|
+
end
|
64
|
+
else
|
65
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
66
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
67
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
68
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
69
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
70
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
data/lib/bit_mask.rb
ADDED
@@ -0,0 +1,232 @@
|
|
1
|
+
require 'active_support/core_ext/class/attribute'
|
2
|
+
|
3
|
+
class BitMask
|
4
|
+
CHARACTER_SET = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'
|
5
|
+
class_attribute :fields, :defaults, :base
|
6
|
+
def self.inherited(sub)
|
7
|
+
sub.fields = []
|
8
|
+
sub.defaults = {}
|
9
|
+
sub.base = 62
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(args = {})
|
13
|
+
self.replace(self.defaults.merge(args))
|
14
|
+
end
|
15
|
+
|
16
|
+
def replace(args)
|
17
|
+
args.each do |field,value|
|
18
|
+
self[field]= value
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
alias_method :attributes=, :replace
|
23
|
+
|
24
|
+
def [](field)
|
25
|
+
raise "#{field} is an invalid key" unless self.class.keys.include? field.to_sym
|
26
|
+
self.send(field)
|
27
|
+
end
|
28
|
+
|
29
|
+
def []=(field,value)
|
30
|
+
raise "#{field} is an invalid key" unless self.class.keys.include? field.to_sym
|
31
|
+
self.send("#{field}=",value)
|
32
|
+
end
|
33
|
+
|
34
|
+
def read_attribute(key)
|
35
|
+
self.instance_variable_get("@#{key}".to_sym)
|
36
|
+
end
|
37
|
+
|
38
|
+
def write_attribute(key,value)
|
39
|
+
if field = self.fields.assoc(key)
|
40
|
+
if self.class.check_value(field,value)
|
41
|
+
self.instance_variable_set("@#{key}".to_sym,value)
|
42
|
+
else
|
43
|
+
raise "Invalid input for #{key}: #{value} field: #{field}"
|
44
|
+
end
|
45
|
+
else
|
46
|
+
raise "#{key} is an invalid key"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_bin
|
51
|
+
self.fields.reverse.map do |field,conf|
|
52
|
+
val = self.read_attribute(field)
|
53
|
+
val = conf[:values].index(val) if conf[:values].respond_to? :index
|
54
|
+
val.to_i.to_s(2).rjust(conf[:bits],'0')
|
55
|
+
end.join('').sub(/\A0+/,'')
|
56
|
+
end
|
57
|
+
|
58
|
+
#converts it to an integer, Good for IDs
|
59
|
+
def to_i
|
60
|
+
self.to_bin.to_i(2)
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_s(radix=nil)
|
64
|
+
radix ||= self.base
|
65
|
+
characters = CHARACTER_SET
|
66
|
+
|
67
|
+
if radix.kind_of? String
|
68
|
+
characters = radix.dup
|
69
|
+
radix = radix.size
|
70
|
+
elsif !radix.kind_of?(Integer) || radix < 0 || radix > 64
|
71
|
+
raise '#{radix} is and invalid base to convert to. It must be a string or between 0 and 64'
|
72
|
+
end
|
73
|
+
|
74
|
+
dec = self.to_i
|
75
|
+
result = ''
|
76
|
+
while dec != 0
|
77
|
+
result += characters[dec%radix].chr
|
78
|
+
dec /= radix
|
79
|
+
end
|
80
|
+
result.reverse
|
81
|
+
end
|
82
|
+
|
83
|
+
def keys
|
84
|
+
self.class.keys
|
85
|
+
end
|
86
|
+
|
87
|
+
alias_method :dump, :to_s
|
88
|
+
|
89
|
+
def ==(other)
|
90
|
+
self.class == other.class && self.fields == other.fields && self.attributes == other.attributes
|
91
|
+
end
|
92
|
+
|
93
|
+
def attributes
|
94
|
+
fields.inject({}) do |attrs, field|
|
95
|
+
attrs[field.first] = self.send(field.first)
|
96
|
+
attrs
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def inspect
|
101
|
+
self.attributes.inspect
|
102
|
+
end
|
103
|
+
|
104
|
+
class << self
|
105
|
+
|
106
|
+
def keys
|
107
|
+
self.fields.map {|f| f[0]}
|
108
|
+
end
|
109
|
+
|
110
|
+
def from_s(string,radix = nil)
|
111
|
+
radix ||= self.base
|
112
|
+
if radix.kind_of? String
|
113
|
+
char_ref = radix
|
114
|
+
radix = radix.size
|
115
|
+
elsif !radix.kind_of?(Integer) || radix < 0 || radix > 64
|
116
|
+
raise '#{radix} is and invalid base to convert to. It must be a string or between 0 and 64'
|
117
|
+
else
|
118
|
+
char_ref = CHARACTER_SET[0..radix]
|
119
|
+
end
|
120
|
+
|
121
|
+
int_val = 0
|
122
|
+
string.reverse.split(//).each_with_index do |char,index|
|
123
|
+
raise ArgumentError, "Character #{char} at index #{index} is not a valid character for to_insane Base #{radix} String." unless char_index = char_ref.index(char)
|
124
|
+
int_val += (char_index)*(radix**(index))
|
125
|
+
end
|
126
|
+
self.from_i(int_val)
|
127
|
+
end
|
128
|
+
|
129
|
+
alias_method :load, :from_s
|
130
|
+
|
131
|
+
def from_i(integer)
|
132
|
+
self.from_bin(integer.to_s(2))
|
133
|
+
end
|
134
|
+
|
135
|
+
def from_bin(binary_string)
|
136
|
+
binary_array = binary_string.split('')
|
137
|
+
bit_hash = self.new
|
138
|
+
self.fields.each do |field,conf|
|
139
|
+
value = (conf[:bits] == -1) ? binary_array : binary_array.pop(conf[:bits])
|
140
|
+
break if value.nil?
|
141
|
+
value = value.join('').to_i(2)
|
142
|
+
if conf[:values].respond_to?(:at)
|
143
|
+
value = conf[:values].at(value)
|
144
|
+
elsif conf[:values].respond_to?(:from_i)
|
145
|
+
value = conf[:values].from_i(value)
|
146
|
+
end
|
147
|
+
bit_hash.write_attribute(field,value)
|
148
|
+
end
|
149
|
+
bit_hash
|
150
|
+
end
|
151
|
+
|
152
|
+
def set_base(base)
|
153
|
+
if base.kind_of? Integer && base <= 36
|
154
|
+
self.base = base
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def bit_length
|
159
|
+
bits = 0
|
160
|
+
self.fields.each do |field,opts|
|
161
|
+
bits += opts[:bits]
|
162
|
+
end
|
163
|
+
bits
|
164
|
+
end
|
165
|
+
|
166
|
+
def field(name,opts)
|
167
|
+
name = name.to_sym
|
168
|
+
unless opts[:bits]
|
169
|
+
unless opts[:limit]
|
170
|
+
if opts[:characters]
|
171
|
+
opts[:limit] = opts[:characters].to_i*self.base
|
172
|
+
elsif opts[:values].respond_to? :bit_length
|
173
|
+
opts[:bits] = opts[:values].bit_length
|
174
|
+
elsif opts[:values].kind_of? Integer
|
175
|
+
opts[:limit] = opts[:values]
|
176
|
+
else
|
177
|
+
opts[:limit] = opts[:values].size
|
178
|
+
end
|
179
|
+
end
|
180
|
+
opts[:bits] ||= (opts[:limit].to_i-1).to_s(2).length
|
181
|
+
end
|
182
|
+
raise "value cannot be negative" if opts[:values].class == Integer && opts[:values] < 0
|
183
|
+
options = {:values => opts[:values], :bits => opts[:bits].to_i, :nil => opts[:nil]}
|
184
|
+
if index = self.fields.index{|f| f[0] == name}
|
185
|
+
self.fields[index][1] = options
|
186
|
+
else
|
187
|
+
self.fields << [name, options]
|
188
|
+
end
|
189
|
+
self.defaults[name]=get_default(options)
|
190
|
+
|
191
|
+
define_method name do
|
192
|
+
self.read_attribute(name)
|
193
|
+
end
|
194
|
+
|
195
|
+
define_method "#{name}=" do |*args|
|
196
|
+
self.write_attribute(name,*args)
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
def get_default(opts)
|
202
|
+
return nil if opts[:nil]
|
203
|
+
values = opts[:values]
|
204
|
+
if values.kind_of? Integer
|
205
|
+
0
|
206
|
+
elsif values.respond_to? :first
|
207
|
+
values.first
|
208
|
+
elsif values.respond_to? :defaults
|
209
|
+
values.defaults
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def check_value(key,value)
|
214
|
+
field = (key.class == Array) ? key : self.fields.assoc(key)
|
215
|
+
|
216
|
+
if opts = field[1]
|
217
|
+
return true if opts[:nil] && value.nil?
|
218
|
+
if values = opts[:values]
|
219
|
+
if values.kind_of? Integer
|
220
|
+
return false if value < 0
|
221
|
+
return values == -1 || value <= values
|
222
|
+
elsif values.kind_of? BitMask
|
223
|
+
return value.kind_of? BitMask && value.fields.hash == value.fields.hash
|
224
|
+
else
|
225
|
+
return values.include?(value)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
false
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe BitMask do
|
4
|
+
|
5
|
+
it "should have values set at 2" do
|
6
|
+
CarSearch.fields.assoc(:segment_1)[1][:values].should == 2
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should have bits set to 1" do
|
10
|
+
CarSearch.fields.assoc(:segment_1)[1][:bits].should == 1
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should have bits set to 4" do
|
14
|
+
CarSearch.fields.assoc(:min_price_cents)[1][:bits].should == 4
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should raise an error if config lacks name" do
|
18
|
+
CarSearch.new.should_not be_nil
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should be able to get keys" do
|
22
|
+
CarSearch.keys.should be_a Array
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should have load same config" do
|
26
|
+
CarSearch.load(CarSearch.new.dump).inspect.should == CarSearch.new.inspect
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should equal itself" do
|
30
|
+
CarSearch.load(CarSearch.new.dump).should == CarSearch.new
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should output equal it self after being converted and parsed" do
|
34
|
+
str = CarSearch.new.dump
|
35
|
+
bin = CarSearch.new.to_bin
|
36
|
+
CarSearch.load(str).to_bin.should eql(bin)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "settings should change" do
|
40
|
+
old = CarSearch.new
|
41
|
+
new = old.dup
|
42
|
+
new[:body_style]= 'wagon'
|
43
|
+
new[:color].should eql('red')
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should replace setting" do
|
47
|
+
config = CarSearch.new
|
48
|
+
config.replace({:air=>1})
|
49
|
+
config[:air].should eql(1)
|
50
|
+
end
|
51
|
+
|
52
|
+
let(:modified_conf) {
|
53
|
+
config = CarSearch.new
|
54
|
+
config.color= 'red'
|
55
|
+
config.body_style= 'suv'
|
56
|
+
config.air= 1
|
57
|
+
config
|
58
|
+
}
|
59
|
+
|
60
|
+
it "should have binary conversion working" do
|
61
|
+
new = CarSearch.from_bin(modified_conf.to_bin)
|
62
|
+
new.attributes.should == modified_conf.attributes
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should have integer conversion working" do
|
66
|
+
new = CarSearch.from_i(modified_conf.to_i)
|
67
|
+
new.attributes.should == modified_conf.attributes
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should have string conversion working" do
|
71
|
+
modified_conf.to_s(10).should == modified_conf.to_i.to_s(10)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should have string conversion working" do
|
75
|
+
modified_conf.to_bin == CarSearch.from_s(modified_conf.to_i.to_s(36),36).to_bin
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should have string conversion working" do
|
79
|
+
new = CarSearch.from_s(modified_conf.to_s)
|
80
|
+
new.attributes.should == modified_conf.attributes
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should have string conversion working" do
|
84
|
+
new = CarSearch.from_s(modified_conf.to_s('qwerty'),'qwerty')
|
85
|
+
new.attributes.should == modified_conf.attributes
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class CarSearch < BitMask
|
2
|
+
field :min_price_cents, :values => [1000000,1500000,2000000,3000000,3500000,4000000,4500000,5000000,5500000,6000000,6500000,7000000]
|
3
|
+
field :max_price_cents, :values => [1500000,2000000,3000000,3500000,4000000,4500000,5000000,5500000,6000000,6500000,7000000,8000000]
|
4
|
+
field :segment_1, :values => 2
|
5
|
+
field :segment_2, :values => 2
|
6
|
+
field :segment_3, :values => 2
|
7
|
+
field :segment_4, :values => 2
|
8
|
+
field :segment_5, :values => 2
|
9
|
+
field :segment_6, :values => 2
|
10
|
+
field :segment_7, :values => 2
|
11
|
+
field :segment_8, :values => 2
|
12
|
+
field :segment_9, :values => 2
|
13
|
+
field :brand_pref_acura, :values => 3
|
14
|
+
field :brand_pref_aston_martin, :values => 3
|
15
|
+
field :brand_pref_audi, :values => 3
|
16
|
+
field :brand_pref_bentley, :values => 3
|
17
|
+
field :brand_pref_bmw, :values => 3
|
18
|
+
field :brand_pref_buick, :values => 3
|
19
|
+
field :brand_pref_cadillac, :values => 3
|
20
|
+
field :brand_pref_chevrolet, :values => 3
|
21
|
+
field :brand_pref_chrysler, :values => 3
|
22
|
+
field :brand_pref_dodge, :values => 3
|
23
|
+
field :brand_pref_ferrari, :values => 3
|
24
|
+
field :air, :values => 2
|
25
|
+
field :body_style, :values => ['sedan','suv','wagon']
|
26
|
+
field :color, :values => ['red','blue','green']
|
27
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'bit_mask'
|
5
|
+
|
6
|
+
# Requires supporting files with custom matchers and macros, etc,
|
7
|
+
# in ./support/ and its subdirectories.
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
|
+
Dir["#{File.dirname(__FILE__)}/models/**/*.rb"].each {|f| require f}
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bit_mask
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ryan Ong
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-07-18 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activesupport
|
17
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: "0"
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *id001
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: shoulda
|
28
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *id002
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: bundler
|
39
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 1.0.0
|
45
|
+
type: :development
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *id003
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: jeweler
|
50
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 1.5.2
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *id004
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: rcov
|
61
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
type: :development
|
68
|
+
prerelease: false
|
69
|
+
version_requirements: *id005
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rspec
|
72
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: "0"
|
78
|
+
type: :development
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: *id006
|
81
|
+
description: bit_mask creates a simple api to create bit mask models. By bit masking dataing you can compress the amount of data that needs to be sent between servers and clients
|
82
|
+
email: ryanong@gmail.com
|
83
|
+
executables: []
|
84
|
+
|
85
|
+
extensions: []
|
86
|
+
|
87
|
+
extra_rdoc_files:
|
88
|
+
- LICENSE.txt
|
89
|
+
- README.rdoc
|
90
|
+
files:
|
91
|
+
- .document
|
92
|
+
- .rspec
|
93
|
+
- Gemfile
|
94
|
+
- LICENSE.txt
|
95
|
+
- README.rdoc
|
96
|
+
- Rakefile
|
97
|
+
- VERSION
|
98
|
+
- bit_mask.gemspec
|
99
|
+
- lib/bit_mask.rb
|
100
|
+
- spec/bit_mask_spec.rb
|
101
|
+
- spec/models/car_search.rb
|
102
|
+
- spec/models/dealership_search.rb
|
103
|
+
- spec/spec_helper.rb
|
104
|
+
homepage: http://github.com/ryanong/bit_hash
|
105
|
+
licenses:
|
106
|
+
- MIT
|
107
|
+
post_install_message:
|
108
|
+
rdoc_options: []
|
109
|
+
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
hash: -3458846048979533380
|
118
|
+
segments:
|
119
|
+
- 0
|
120
|
+
version: "0"
|
121
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: "0"
|
127
|
+
requirements: []
|
128
|
+
|
129
|
+
rubyforge_project:
|
130
|
+
rubygems_version: 1.8.5
|
131
|
+
signing_key:
|
132
|
+
specification_version: 3
|
133
|
+
summary: bit_mask allows you to serialize/bitmask simple data sets into short compact ascii strings.
|
134
|
+
test_files:
|
135
|
+
- spec/bit_mask_spec.rb
|
136
|
+
- spec/models/car_search.rb
|
137
|
+
- spec/models/dealership_search.rb
|
138
|
+
- spec/spec_helper.rb
|