bit_hash 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+ gem "to_insane", ">=0.2.1"
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "shoulda", ">= 0"
10
+ gem "bundler", "~> 1.0.0"
11
+ gem "jeweler", "~> 1.5.2"
12
+ gem "rcov", ">= 0"
13
+ gem "rspec"
14
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,32 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.2)
5
+ git (1.2.5)
6
+ jeweler (1.5.2)
7
+ bundler (~> 1.0.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ rake (0.8.7)
11
+ rcov (0.9.9)
12
+ rspec (2.5.0)
13
+ rspec-core (~> 2.5.0)
14
+ rspec-expectations (~> 2.5.0)
15
+ rspec-mocks (~> 2.5.0)
16
+ rspec-core (2.5.1)
17
+ rspec-expectations (2.5.0)
18
+ diff-lcs (~> 1.1.2)
19
+ rspec-mocks (2.5.0)
20
+ shoulda (2.11.3)
21
+ to_insane (0.2.1)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ bundler (~> 1.0.0)
28
+ jeweler (~> 1.5.2)
29
+ rcov
30
+ rspec
31
+ shoulda
32
+ to_insane (>= 0.2.1)
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,97 @@
1
+ = bit_hash
2
+
3
+ A simple class that can convert an option hash into a compact string.
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_hash'
11
+
12
+ config_map = [
13
+ {
14
+ :name => :air, # name of option
15
+ :options => 2, # number of options must be 2 or greater
16
+ },
17
+ {
18
+ :name => :color,
19
+ :options => ['blue','green','red'] # bit_hash can map arrays of data, the default setting will be the first value in the array
20
+ },
21
+ {
22
+ :name => :body_style,
23
+ :options => [:sedan,:mini_van,:suv], # Array values can be anything that can be found using the Array#index function
24
+ :default => :mini_van # for arrays the default is any array value
25
+ },
26
+ {
27
+ :name => :transmission, # name of option
28
+ :options => 6,
29
+ :default => 5 # for numbers the default must be between 0 and the options value
30
+ },
31
+ {
32
+ :name => :min_price,
33
+ :options => (50..100).to_a, # ( just a way to store ranges of numbers)
34
+ :default => 60 # basically any default can be used as long as it is a valid option
35
+ },
36
+ {
37
+ :name => :max_price,
38
+
39
+ # intervals of 20 starting at 10000 (just a way to store ranges of numbers)
40
+ :options => (1..5).to_a.map {|n| 10000+(n*20)},
41
+
42
+ # you can use :default_index option to reference something in the option arrays but it really isn't suggested, :default take precedence
43
+ :default_index => 2
44
+ }
45
+ ]
46
+
47
+ # initialize
48
+ @config = BitHash.new(config_map)
49
+
50
+ # set a single value
51
+ @config[:color]='red'
52
+
53
+ # get a value
54
+ @config[:value]
55
+
56
+ # replace values in config with another hash
57
+ @config.replace({:air=>1})
58
+
59
+ # parse a string without saving
60
+ @config.parse('e')
61
+
62
+ # parse a string and save it
63
+ @config.save
64
+
65
+ # convert to small compact string
66
+ @config.to_s
67
+
68
+ == TODO
69
+
70
+ * Impliment more tests
71
+ * Clone more Hash functions
72
+ * Storage of strings
73
+ * If binary options and default 1, user inverse
74
+ * allow a hash for config_map for ruby 1.9
75
+ * Add some sort of ActiveRecord extender
76
+
77
+ == Contributing to bit_hash
78
+
79
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
80
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
81
+ * Fork the project
82
+ * Start a feature/bugfix branch
83
+ * Commit and push until you are happy with your contribution
84
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
85
+ * 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.
86
+
87
+ == Credits
88
+
89
+ Ryan Ong - ryanong@gmail.com
90
+
91
+ Developed for and with CarZen[link:http://carzen.com]
92
+
93
+ == Copyright
94
+
95
+ Copyright (c) 2011 Ryan Ong. See LICENSE.txt for
96
+ further details.
97
+
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_hash"
16
+ gem.homepage = "http://github.com/ryanong/bit_hash"
17
+ gem.license = "MIT"
18
+ gem.summary = %Q{bit_hash allows you to serialize simple set data into short compact URL safe strings.}
19
+ gem.description = %Q{bit_hash is a useful tool to pass through options through a string. The best usecases would be forms with binary,trinary, etc etc data sets.}
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_hash #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/bit_hash.gemspec ADDED
@@ -0,0 +1,70 @@
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_hash}
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 = ["Ryan Ong"]
12
+ s.date = %q{2011-02-16}
13
+ s.description = %q{bit_hash is a useful tool to pass through options through a string. The best usecases would be forms with binary,trinary, etc etc data sets.}
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
+ "Gemfile.lock",
24
+ "LICENSE.txt",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "bit_hash.gemspec",
29
+ "lib/bit_hash.rb",
30
+ "spec/bit_hash_spec.rb",
31
+ "spec/spec_helper.rb"
32
+ ]
33
+ s.homepage = %q{http://github.com/ryanong/bit_hash}
34
+ s.licenses = ["MIT"]
35
+ s.require_paths = ["lib"]
36
+ s.rubygems_version = %q{1.5.0}
37
+ s.summary = %q{bit_hash allows you to serialize simple set data into short compact URL safe strings.}
38
+ s.test_files = [
39
+ "spec/bit_hash_spec.rb",
40
+ "spec/spec_helper.rb"
41
+ ]
42
+
43
+ if s.respond_to? :specification_version then
44
+ s.specification_version = 3
45
+
46
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
+ s.add_runtime_dependency(%q<to_insane>, [">= 0.2.1"])
48
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
49
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
50
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
51
+ s.add_development_dependency(%q<rcov>, [">= 0"])
52
+ s.add_development_dependency(%q<rspec>, [">= 0"])
53
+ else
54
+ s.add_dependency(%q<to_insane>, [">= 0.2.1"])
55
+ s.add_dependency(%q<shoulda>, [">= 0"])
56
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
57
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
58
+ s.add_dependency(%q<rcov>, [">= 0"])
59
+ s.add_dependency(%q<rspec>, [">= 0"])
60
+ end
61
+ else
62
+ s.add_dependency(%q<to_insane>, [">= 0.2.1"])
63
+ s.add_dependency(%q<shoulda>, [">= 0"])
64
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
65
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
66
+ s.add_dependency(%q<rcov>, [">= 0"])
67
+ s.add_dependency(%q<rspec>, [">= 0"])
68
+ end
69
+ end
70
+
data/lib/bit_hash.rb ADDED
@@ -0,0 +1,272 @@
1
+ require 'to_insane'
2
+
3
+ class BitHash
4
+
5
+ attr_accessor :options, :default
6
+ # look below at load_config_map for config_map schema
7
+ # base is the base value you want to use. Defaults to a URL safe character base which is 63
8
+ # character set can also be changed but not really necessary. read to_insane doc for more details
9
+ def initialize(config_map=nil, *options)
10
+ load_options(options)
11
+ @config = Hash.new
12
+ @default = Hash.new
13
+ #validate mapping
14
+ load_config_map(config_map) if config_map.kind_of? Array
15
+ @config
16
+ end
17
+
18
+ #Example config_map
19
+ #
20
+ # config_map = [
21
+ # {
22
+ # :name => :air, # name of option
23
+ # :options => 2, # number of options must be 2 or greater
24
+ # },
25
+ # {
26
+ # :name => :color,
27
+ # :options => ['blue','green','red'] # bit_hash can map arrays of data, the default setting will be the first value in the array
28
+ # },
29
+ # {
30
+ # :name => :body_style,
31
+ # :options => [:sedan,:mini_van,:suv], # Array values can be anything that can be found using the Array#index function
32
+ # :default => :mini_van # for arrays the default is any array value
33
+ # },
34
+ # {
35
+ # :name => :transmission, # name of option
36
+ # :options => 6,
37
+ # :default => 5 # for numbers the default must be between 0 and the options value
38
+ # },
39
+ # {
40
+ # :name => :min_price,
41
+ # :options => (50..100).to_a, # ( just a way to store ranges of numbers)
42
+ # :default => 60 # basically any default can be used as long as it is a valid option
43
+ # },
44
+ # {
45
+ # :name => :max_price,
46
+
47
+ # # intervals of 20 starting at 10000 (just a way to store ranges of numbers)
48
+ # :options => (1..5).to_a.map {|n| 10000+(n*20)},
49
+
50
+ # # you can use :default_index option to reference something in the option arrays but it really isn't suggested, :default take precedence
51
+ # :default_index => 2
52
+ # }
53
+ # ]
54
+ def load_config_map(config_map)
55
+ raise ArgumentError, "Config Map must be an Array" unless config_map.kind_of? Array
56
+ config_array = []
57
+ new_config = {}
58
+ config_map.each_index do |index|
59
+ conf = config_map[index]
60
+ raise ArgumentError, "#{conf[:name]} is a duplicate" if new_config.keys.index(conf[:name])
61
+ new_config[conf[:name]] = get_check_config(index,conf)
62
+ config_array[index] = conf
63
+ end
64
+ @config = new_config.dup
65
+ @default = new_config.dup
66
+ @config_map = config_array
67
+ end
68
+
69
+ # Just get a list of keys
70
+ def keys
71
+ @config_map.map{ |c| c[:name]}
72
+ end
73
+
74
+ # Set default key
75
+ def set_default(key)
76
+ conf = get_options(key)
77
+ @config[conf[:name]] = 0
78
+ if !conf[:default].nil?
79
+ new_config[conf[:name]] = conf[:default]
80
+ elsif !conf[:default_index].nil?
81
+ new_config[conf[:name]] = conf[:options][conf.default_index]
82
+ end
83
+ end
84
+
85
+ # see set
86
+ def []=(key,value)
87
+ set(key,value)
88
+ end
89
+
90
+ # sets a key value, returns nil if value is invalid
91
+ def set(key,value)
92
+ conf = get_options(key)
93
+ if conf && check_value(conf,value)
94
+ @config[key] = value
95
+ else
96
+ nil
97
+ end
98
+ end
99
+
100
+ # sets with critical failure
101
+ def set!(key,value)
102
+ conf = get_options(key)
103
+ if conf && check_value!(conf,value)
104
+ @config[key] = value
105
+ else
106
+ raise ArgumentError, "Key: '#{key}' not found in config"
107
+ end
108
+ end
109
+
110
+ # fetches values for given key
111
+ def [](key)
112
+ @config[key]
113
+ end
114
+
115
+ # replaces internal settings with any given hash and overwrites values and returns hash. On failure returns nil
116
+ def replace(hash)
117
+ cache = @config.dup
118
+ hash.each do |key, value|
119
+ if set(key,value).nil?
120
+ @config = cache
121
+ return nil
122
+ end
123
+ end
124
+ @config
125
+ end
126
+
127
+ # returns option settings for given key
128
+ def get_options(key)
129
+ index = @config_map.index{|x|x[:name]==key}
130
+ (index) ? @config_map[index].merge({:index => index}) : nil
131
+ end
132
+
133
+ # replaces given option with name of key and replaces with options
134
+ def replace_options(key, options)
135
+ @config_map.map! do |conf|
136
+ if conf[:name] == key
137
+ options
138
+ else
139
+ conf
140
+ end
141
+ end
142
+ end
143
+
144
+ # takes a given config string and returns a mapped hash
145
+ # please read to_insane doc for info on base and char_set
146
+ def parse(config_string, *options)
147
+ load_options(options)
148
+ raise ArgumentError, "Prefix must be a string" if !@options[:prefix].nil? && !@options[:prefix].kind_of?(String)
149
+ config_string[0..@options[:prefix].size] = nil unless @options[:prefix].nil?
150
+ config_string = config_string.from_insane(@options[:base],@options[:char_set]).to_s(2)
151
+ config_array = config_string.split('')
152
+ new_config = @default.dup
153
+ @config_map.each do |conf|
154
+ value = config_array.pop(conf[:size])
155
+ break if value.nil?
156
+ value = value.join('').to_i(2)
157
+ new_config[conf[:name]] = (conf[:options].kind_of? Array ) ? conf[:options][value] : value
158
+ end
159
+ new_config
160
+ end
161
+
162
+ # pareses and saves string into internal hash
163
+ def save(config_string, *options)
164
+ @config = parse(config_string, *options)
165
+ end
166
+
167
+ #converts it into a binary string
168
+ def to_bin
169
+ bin_config = []
170
+ @config_map.each do |conf|
171
+ val = @config[conf[:name]]
172
+ val = conf[:options].index(val) if conf[:options].kind_of? Array
173
+ bin = "%0#{conf[:size]}d" % val.to_s(2).to_i
174
+ bin_config.unshift(bin)
175
+ end
176
+ bin_config.join('')
177
+ end
178
+
179
+ #converts it to an integer, Good for IDs
180
+ def to_i
181
+ to_bin.to_i(2)
182
+ end
183
+
184
+ # turns hash into a small compact string.
185
+ # see to_insane rdoc for base, and char_set definitions
186
+ def to_s(*options)
187
+ load_options(options)
188
+ str = ''
189
+ str << @options[:prefix] if @options[:prefix].kind_of? String
190
+ str << to_i.to_insane(@options[:base], @options[:char_set])
191
+ str
192
+ end
193
+
194
+ #checks key to see if value given is valid
195
+ def valid_value?(key,val)
196
+ check_value(get_options(key),val)
197
+ end
198
+
199
+ alias_method :to_hash, :inspect
200
+
201
+ # returns as a hash (alias: inspect)
202
+ def to_hash
203
+ @config
204
+ end
205
+
206
+ private
207
+
208
+ # checks value against given config
209
+ def check_value(conf,val)
210
+ if conf[:options].kind_of?(Array)
211
+ return false if conf[:options].index(val).nil?
212
+ elsif conf[:options].kind_of?(Integer) && val.kind_of?(Integer)
213
+ return false if val < 0 or val > conf[:options]
214
+ else
215
+ return false
216
+ end
217
+ true
218
+ end
219
+
220
+ # checks values with a bang
221
+ def check_value!(conf,val)
222
+ if conf[:options].kind_of? Array
223
+ raise ArgumentError, "#{conf[:name]} is #{val} and is not a valid value within the stored array. #{conf[:options].to_s}" if conf[:options].index(val).nil?
224
+ elsif conf[:options].kind_of? Integer
225
+ raise ArgumentError, "#{conf[:name]} is #{val} and should not be less than 0" if val < 0
226
+ raise ArgumentError, "#{conf[:name]} is #{val} and value is not less than #{conf[:options]}" if val > conf[:options]
227
+ else
228
+ raise ArgumentError, "#{conf[:name]} is not a valid value please associate it with an object in an array or give it an integer value"
229
+ end
230
+ true
231
+ end
232
+
233
+ def load_options(options)
234
+ if options.kind_of? Array
235
+ @options = {:base => options[0], :char_set => options[1]}
236
+ elsif options.kind_of? Hash
237
+ @options = options
238
+ end
239
+ @options[:base] ||= :url_safe
240
+ @options[:char_set] ||= nil
241
+ @options[:prefix] ||= nil
242
+ end
243
+
244
+ def get_check_config(key,conf)
245
+ raise ArgumentError, "config is not a Hash" unless conf.kind_of? Hash
246
+ raise ArgumentError, ":name cannot be nil for [#{key}]" if conf[:name].nil?
247
+ raise ArgumentError, ":options cannot be nil for [#{key}]" if conf[:options].nil?
248
+ if conf[:options].kind_of? Integer
249
+ conf[:size] = conf[:options]
250
+ elsif conf[:options].kind_of? Array
251
+ conf[:size] = conf[:options].size
252
+ elsif conf[:options].kind_of? Symbol || conf[:options].kind_of?(String)
253
+ raise ArgumentError, ":options Character set cannot have duplicate characters" if conf[:options].kind_of?(String) && (conf[:options].size != conf[:options].split(//).uniq.size)
254
+ raise ArgumentError, ":options"
255
+ raise ArgumentError, ":size needs to be an integer larger than 0 [#{conf[:name]}]" unless conf[:size].kind_of? Integer and conf[:size] > 0
256
+ else
257
+ raise ArgumentError, ":options needs to be an Array or Integer for [#{conf[:name]}]"
258
+ end
259
+ if !conf[:default].nil?
260
+ raise ArgumentError, "default value of (#{conf[:default]}) is not valid for #{conf[:name]}" unless check_value(conf,conf[:default])
261
+ default = conf[:default]
262
+ elsif !conf[:default_index].nil?
263
+ raise ArgumentError, ":default_index must be an integer #{conf[:name]}" unless conf[:default_index].kind_of? Integer
264
+ unless default = conf[:options][conf[:default_index]]
265
+ raise ArgumentError, ":default_index must be a valid option array index #{conf[:name]}"
266
+ end
267
+ end
268
+ conf[:size] = (conf[:size]-1).to_s(2).size
269
+ default ||= (conf[:options].kind_of? Integer) ? 0 : conf[:options][0]
270
+ end
271
+ end
272
+
@@ -0,0 +1,104 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe BitHash do
4
+
5
+ before(:each) do
6
+ @config_map = [
7
+ { :name=> 'min_price_cents', :options => [1000000,1500000,2000000,3000000,3500000,4000000,4500000,5000000,5500000,6000000,6500000,7000000] },
8
+ { :name=> 'max_price_cents', :options => [1500000,2000000,3000000,3500000,4000000,4500000,5000000,5500000,6000000,6500000,7000000,8000000] },
9
+ { :name=> 'segment_1', :options => 2},
10
+ { :name=> 'segment_2', :options => 2},
11
+ { :name=> 'segment_3', :options => 2},
12
+ { :name=> 'segment_4', :options => 2},
13
+ { :name=> 'segment_5', :options => 2},
14
+ { :name=> 'segment_6', :options => 2},
15
+ { :name=> 'segment_7', :options => 2},
16
+ { :name=> 'segment_8', :options => 2},
17
+ { :name=> 'segment_9', :options => 2},
18
+ { :name=> 'brand_pref_acura', :options => 3},
19
+ { :name=> 'brand_pref_aston_martin', :options => 3},
20
+ { :name=> 'brand_pref_audi', :options => 3},
21
+ { :name=> 'brand_pref_bentley', :options => 3},
22
+ { :name=> 'brand_pref_bmw', :options => 3},
23
+ { :name=> 'brand_pref_buick', :options => 3},
24
+ { :name=> 'brand_pref_cadillac', :options => 3},
25
+ { :name=> 'brand_pref_chevrolet', :options => 3},
26
+ { :name=> 'brand_pref_chrysler', :options => 3},
27
+ { :name=> 'brand_pref_dodge', :options => 3},
28
+ { :name=> 'brand_pref_ferrari', :options => 3},
29
+ {
30
+ :name => :air, # name of option
31
+ :options => 2, # number of options must be 2 or greater
32
+ },
33
+ {
34
+ :name => :color,
35
+ :options => ['blue','green','red'] # bit_hash can map arrays of data, the default setting will be the first value in the array
36
+ },
37
+ {
38
+ :name => :body_style,
39
+ :options => [:sedan,:mini_van,:suv], # Array values can be anything that can be found using the Array#index function
40
+ :default => :mini_van # for arrays the default is any array value
41
+ },
42
+ {
43
+ :name => :transmission, # name of option
44
+ :options => 6,
45
+ :default => 5 # for numbers the default must be between 0 and the options value
46
+ },
47
+ {
48
+ :name => :min_price,
49
+ :options => (50..100).to_a, # ( just a way to store ranges of numbers)
50
+ :default => 60 # basically any default can be used as long as it is a valid option
51
+ },
52
+ {
53
+ :name => :max_price,
54
+ # intervals of 20 starting at 10000 (just a way to store ranges of numbers)
55
+ :options => (1..5).to_a.map {|n| 10000+(n*20)},
56
+ # you can use :default_index option to reference something in the option arrays but it really isn't suggested, :default take precedence
57
+ :default_index => 2
58
+ }
59
+ ]
60
+ @config = BitHash.new(@config_map)
61
+ end
62
+
63
+ it "should raise an error if config lacks name" do
64
+ BitHash.new(@config_map).should_not be_nil
65
+ end
66
+
67
+ it "should raise an error if config lacks name" do
68
+ @config_map[0].delete(:name)
69
+ lambda { BitHash.new(@config_map) }.should raise_error(ArgumentError)
70
+ end
71
+
72
+ it "should be able to get keys" do
73
+ @config.keys.should be_a Array
74
+ end
75
+
76
+ it "should have load same config" do
77
+ @config.parse(@config.to_s).should eql(@config.to_hash)
78
+ end
79
+
80
+ it "should output equal it self after being converted and parsed" do
81
+ str = @config.to_s
82
+ bin = @config.to_bin
83
+ @config.save(str)
84
+ bin.should eql(@config.to_bin)
85
+ end
86
+
87
+ it "settings should change" do
88
+ old = @config.to_s
89
+ @config.set!(:color,'red')
90
+ @config[:color].should eql('red')
91
+ end
92
+
93
+ it "should have different string if settings change" do
94
+ @new = BitHash.new(@config_map)
95
+ @config[:color]= 'red'
96
+ @config[:body_style]= :suv
97
+ @config[:air]= 1
98
+ @new.save(@config.to_s)
99
+ @new[:body_style].should eql(:suv)
100
+ @new[:air].should eql(1)
101
+ @new[:color].should eql('red')
102
+ end
103
+
104
+ end
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'bit_hash'
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
+
10
+ RSpec.configure do |config|
11
+
12
+ end
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bit_hash
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Ryan Ong
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-02-16 00:00:00 -05:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: to_insane
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.2.1
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: shoulda
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: bundler
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.0.0
46
+ type: :development
47
+ prerelease: false
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: jeweler
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: 1.5.2
57
+ type: :development
58
+ prerelease: false
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: rcov
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: *id005
71
+ - !ruby/object:Gem::Dependency
72
+ name: rspec
73
+ requirement: &id006 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: *id006
82
+ description: bit_hash is a useful tool to pass through options through a string. The best usecases would be forms with binary,trinary, etc etc data sets.
83
+ email: ryanong@gmail.com
84
+ executables: []
85
+
86
+ extensions: []
87
+
88
+ extra_rdoc_files:
89
+ - LICENSE.txt
90
+ - README.rdoc
91
+ files:
92
+ - .document
93
+ - .rspec
94
+ - Gemfile
95
+ - Gemfile.lock
96
+ - LICENSE.txt
97
+ - README.rdoc
98
+ - Rakefile
99
+ - VERSION
100
+ - bit_hash.gemspec
101
+ - lib/bit_hash.rb
102
+ - spec/bit_hash_spec.rb
103
+ - spec/spec_helper.rb
104
+ has_rdoc: true
105
+ homepage: http://github.com/ryanong/bit_hash
106
+ licenses:
107
+ - MIT
108
+ post_install_message:
109
+ rdoc_options: []
110
+
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ hash: 59358543
119
+ segments:
120
+ - 0
121
+ version: "0"
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: "0"
128
+ requirements: []
129
+
130
+ rubyforge_project:
131
+ rubygems_version: 1.5.0
132
+ signing_key:
133
+ specification_version: 3
134
+ summary: bit_hash allows you to serialize simple set data into short compact URL safe strings.
135
+ test_files:
136
+ - spec/bit_hash_spec.rb
137
+ - spec/spec_helper.rb