pkwde-has_set 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -8,8 +8,8 @@ $hoe = Hoe.new('has_set', HasSet::VERSION) do |p|
8
8
  p.developer('pkw.de Dev Team', 'dev@pkw.de')
9
9
  p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
10
10
  p.extra_deps = [
11
- ['activerecord', '= 2.2.2'],
12
- ['activesupport', '= 2.2.2']
11
+ ['activerecord', '>= 2.3.2'],
12
+ ['activesupport', '>= 2.3.2']
13
13
  ]
14
14
  p.extra_dev_deps = [
15
15
  ['newgem', ">= #{::Newgem::VERSION}"],
@@ -2,39 +2,69 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{has_set}
5
- s.version = "0.0.2"
5
+ s.version = "0.0.4"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["pkw.de Dev Team"]
9
- s.date = %q{2009-04-16}
10
- s.description = %q{A simple Gem to enable any `ActiveRecord::Base` object to store a set of attributes in a set like structure represented through a bitfield on the database level. You only have to specify the name of the set to hold the attributes in question an the rest is done for you through some fine selected Ruby magic. Here is a simple example of how you could use the gem: class Person < ActiveRecord::Base has_set :interests end To get this to work you need some additional work done first: 1. You need an unsigned 8-Byte integer column in your database to store the bitfield. It is expected that the column is named after the name of the set with the suffix `_bitfield` appended (e.g. `interests_bitfield`). You can change that default behavior by providing the option `:column_name` (e.g. `has_set :interests, :column_name => :my_custom_column`). 2. You need a class that provides the valid values to be stored within the set and map the single bits back to something meaningful. The class should be named after the name of the set (you can change this through the `:enum_class` option). This class could be seen as an enumeration and must implement the following simple interface: * There must be a class method `values` to return all valid enumerators in the defined enumeration. * Each enumerator must implement a `name` method to return a literal representation for identification. The literal must be of the type `String`. * Each enumerator must implement a `bitfield_index` method to return the exponent of the number 2 for calculation the position of this enumerator in the bitfield. **Attention** Changing this index afterwards will destroy your data integrity. Here is a simple example of how to implement such a enumeration type while using the the `renum` gem for simplicity. You are free to use anything else that matches the described interface. enum :Interests do attr_reader :bitfield_index Art(0) Golf(1) Sleeping(2) Drinking(3) Dating(4) Shopping(5) def init(bitfield_index) @bitfield_index = bitfield_index end end}
9
+ s.date = %q{2009-05-13}
10
+ s.description = %q{A simple Gem to enable any `ActiveRecord::Base` object to store a set of attributes in a set like structure represented through a bitfield on the database level.
11
+
12
+ You only have to specify the name of the set to hold the attributes in question an the rest is done for you through some fine selected Ruby magic. Here is a simple example of how you could use the gem:
13
+
14
+ class Person < ActiveRecord::Base
15
+ has_set :interests
16
+ end
17
+
18
+ To get this to work you need some additional work done first:
19
+
20
+ 1. You need an unsigned 8-Byte integer column in your database to store the bitfield. It is expected that the column is named after the name of the set with the suffix `_bitfield` appended (e.g. `interests_bitfield`). You can change that default behavior by providing the option `:column_name` (e.g. `has_set :interests, :column_name => :my_custom_column`).
21
+ 2. You need a class that provides the valid values to be stored within the set and map the single bits back to something meaningful. The class should be named after the name of the set (you can change this through the `:enum_class` option). This class could be seen as an enumeration and must implement the following simple interface:
22
+ * There must be a class method `values` to return all valid enumerators in the defined enumeration.
23
+ * Each enumerator must implement a `name` method to return a literal representation for identification. The literal must be of the type `String`.
24
+ * Each enumerator must implement a `bitfield_index` method to return the exponent of the number 2 for calculation the position of this enumerator in the bitfield. **Attention** Changing this index afterwards will destroy your data integrity.
25
+
26
+ Here is a simple example of how to implement such a enumeration type while using the the `renum` gem for simplicity. You are free to use anything else that matches the described interface.
27
+
28
+ enum :Interests do
29
+ attr_reader :bitfield_index
30
+
31
+ Art(0)
32
+ Golf(1)
33
+ Sleeping(2)
34
+ Drinking(3)
35
+ Dating(4)
36
+ Shopping(5)
37
+
38
+ def init(bitfield_index)
39
+ @bitfield_index = bitfield_index
40
+ end
41
+ end}
11
42
  s.email = ["dev@pkw.de"]
12
43
  s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
13
44
  s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile", "has_set.gemspec", "lib/has_set.rb", "script/console", "script/destroy", "script/generate", "test/has_set_test.rb", "test/test_helper.rb"]
14
- s.has_rdoc = true
15
45
  s.homepage = %q{http://github.com/pkwde/has_set}
16
46
  s.rdoc_options = ["--main", "README.txt"]
17
47
  s.require_paths = ["lib"]
18
48
  s.rubyforge_project = %q{has_set}
19
- s.rubygems_version = %q{1.3.1}
49
+ s.rubygems_version = %q{1.3.3}
20
50
  s.summary = %q{A Gem that enables ActiveRecord models to have a set of values defined in a certain class and stored in an integer bitfield on the database level.}
21
51
  s.test_files = ["test/test_helper.rb"]
22
52
 
23
53
  if s.respond_to? :specification_version then
24
54
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
- s.specification_version = 2
55
+ s.specification_version = 3
26
56
 
27
57
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
- s.add_runtime_dependency(%q<activerecord>, ["= 2.2.2"])
29
- s.add_runtime_dependency(%q<activesupport>, ["= 2.2.2"])
58
+ s.add_runtime_dependency(%q<activerecord>, [">= 2.3.2"])
59
+ s.add_runtime_dependency(%q<activesupport>, [">= 2.3.2"])
30
60
  s.add_development_dependency(%q<newgem>, [">= 1.3.0"])
31
61
  s.add_development_dependency(%q<mocha>, [">= 0"])
32
62
  s.add_development_dependency(%q<pkwde-renum>, [">= 0"])
33
63
  s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
34
64
  s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
35
65
  else
36
- s.add_dependency(%q<activerecord>, ["= 2.2.2"])
37
- s.add_dependency(%q<activesupport>, ["= 2.2.2"])
66
+ s.add_dependency(%q<activerecord>, [">= 2.3.2"])
67
+ s.add_dependency(%q<activesupport>, [">= 2.3.2"])
38
68
  s.add_dependency(%q<newgem>, [">= 1.3.0"])
39
69
  s.add_dependency(%q<mocha>, [">= 0"])
40
70
  s.add_dependency(%q<pkwde-renum>, [">= 0"])
@@ -42,8 +72,8 @@ Gem::Specification.new do |s|
42
72
  s.add_dependency(%q<hoe>, [">= 1.8.0"])
43
73
  end
44
74
  else
45
- s.add_dependency(%q<activerecord>, ["= 2.2.2"])
46
- s.add_dependency(%q<activesupport>, ["= 2.2.2"])
75
+ s.add_dependency(%q<activerecord>, [">= 2.3.2"])
76
+ s.add_dependency(%q<activesupport>, [">= 2.3.2"])
47
77
  s.add_dependency(%q<newgem>, [">= 1.3.0"])
48
78
  s.add_dependency(%q<mocha>, [">= 0"])
49
79
  s.add_dependency(%q<pkwde-renum>, [">= 0"])
@@ -5,7 +5,7 @@ require 'activesupport'
5
5
  require 'activerecord'
6
6
 
7
7
  module HasSet
8
- VERSION = '0.0.2'
8
+ VERSION = '0.0.4'
9
9
 
10
10
  module ClassMethods
11
11
 
@@ -24,10 +24,16 @@ module HasSet
24
24
  raise NameError, "There ist no class to take the set entries from (#{ne.message})."
25
25
  end
26
26
 
27
+ # Extend enum_class with field_name method
28
+ enum_class.class_eval <<-EOF
29
+ def field_name
30
+ '#{set_name.to_s.singularize}_' + self.name.underscore
31
+ end
32
+ EOF
33
+
27
34
  define_method("#{set_name}=") do |set_elements|
28
- if set_elements.blank?
29
- self[set_column] = 0
30
- else
35
+ self[set_column] = 0
36
+ unless set_elements.blank?
31
37
  if set_elements.kind_of? String
32
38
  set_elements = set_elements.split(",").collect do |element|
33
39
  element.strip!
@@ -48,18 +54,32 @@ module HasSet
48
54
  if self[set_column] == 0
49
55
  return []
50
56
  else
51
- enum_class.values.inject([]) do |set_elements, enum_element|
57
+ set_elements = enum_class.values.inject([]) do |set_elements, enum_element|
52
58
  set_elements << enum_element if send("#{set_name.to_s.singularize}_#{enum_element.name.underscore}?")
53
59
  set_elements
54
60
  end
61
+ # special to_s method for element-array
62
+ class <<set_elements
63
+ def to_s
64
+ self.collect { |element| "#{element.name}" }.join(", ")
65
+ end
66
+ end
67
+ return set_elements
55
68
  end
56
69
  end
57
70
 
71
+ # TODO: This should be a class method
72
+ define_method("available_#{set_name.to_s}") do
73
+ self.methods.grep(/#{set_name.to_s.singularize}_\w+[^\?=]$/).sort
74
+ end
75
+
58
76
  enum_class.values.each do |enum|
59
77
  define_method("#{set_name.to_s.singularize}_#{enum.name.underscore}?") do
60
78
  2**enum.bitfield_index & self[set_column] == 2**enum.bitfield_index ? true : false
61
79
  end
62
80
 
81
+ alias_method :"#{set_name.to_s.singularize}_#{enum.name.underscore}", :"#{set_name.to_s.singularize}_#{enum.name.underscore}?"
82
+
63
83
  define_method("#{set_name.to_s.singularize}_#{enum.name.underscore}=") do |true_or_false|
64
84
  current_value = (2**enum.bitfield_index & self[set_column] == 2**enum.bitfield_index)
65
85
  true_or_false = true if true_or_false.to_s == "true" || (true_or_false.respond_to?(:to_i) && true_or_false.to_i == 1)
@@ -57,6 +57,12 @@ class HasSetTest < Test::Unit::TestCase
57
57
  assert_equal [Interests::Dating, Interests::Shopping], person.interests
58
58
  end
59
59
 
60
+ def test_should_reset_values_if_setter_is_used
61
+ person = Person.new(:fullname => "Jessie Summers", :interests => [Interests::Dating])
62
+ person.interests = Interests::Shopping
63
+ assert_equal [Interests::Shopping], person.interests
64
+ end
65
+
60
66
  def test_should_set_elements_by_string_names
61
67
  person = Person.new(:fullname => "Jessie Summers", :interests => "Dating, Shopping")
62
68
  assert_equal [Interests::Dating, Interests::Shopping], person.interests
@@ -76,9 +82,15 @@ class HasSetTest < Test::Unit::TestCase
76
82
  assert party.save, "Party should save!"
77
83
  party.reload
78
84
  assert party.drink_beer?, "Party should offer beer."
85
+ assert party.drink_beer, "Party should offer beer."
79
86
  assert party.drink_cuba_libre?, "Party should offer cuba libre."
80
87
  end
81
88
 
89
+ def test_should_have_to_s_method
90
+ party = Party.new(:location => "Beach House", :drinks => [Drinks::Beer, Drinks::CubaLibre])
91
+ assert_equal "Beer, CubaLibre", party.drinks.to_s
92
+ end
93
+
82
94
  def test_should_provide_the_name_of_the_enum_class
83
95
  Party.has_set :music, :enum_class => MusicStyles
84
96
 
@@ -93,4 +105,14 @@ class HasSetTest < Test::Unit::TestCase
93
105
  assert_raise(ArgumentError) { person.interests = Drinks::Beer }
94
106
  end
95
107
 
108
+ def test_should_list_all_available_enum_elements
109
+ assert_equal ["drink_beer", "drink_cuba_libre", "drink_wine"], Party.new.available_drinks
110
+ end
111
+
112
+ def test_should_extend_enum_with_fieldname_method
113
+ assert_equal "drink_cuba_libre", Drinks::CubaLibre.field_name
114
+ assert_equal "drink_beer", Drinks::Beer.field_name
115
+ assert_equal "drink_wine", Drinks::Wine.field_name
116
+ end
117
+
96
118
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pkwde-has_set
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - pkw.de Dev Team
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-16 00:00:00 -07:00
12
+ date: 2009-05-13 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -18,9 +18,9 @@ dependencies:
18
18
  version_requirement:
19
19
  version_requirements: !ruby/object:Gem::Requirement
20
20
  requirements:
21
- - - "="
21
+ - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 2.2.2
23
+ version: 2.3.2
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activesupport
@@ -28,9 +28,9 @@ dependencies:
28
28
  version_requirement:
29
29
  version_requirements: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "="
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 2.2.2
33
+ version: 2.3.2
34
34
  version:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: newgem
@@ -105,7 +105,7 @@ files:
105
105
  - script/generate
106
106
  - test/has_set_test.rb
107
107
  - test/test_helper.rb
108
- has_rdoc: true
108
+ has_rdoc: false
109
109
  homepage: http://github.com/pkwde/has_set
110
110
  post_install_message:
111
111
  rdoc_options:
@@ -130,7 +130,7 @@ requirements: []
130
130
  rubyforge_project: has_set
131
131
  rubygems_version: 1.2.0
132
132
  signing_key:
133
- specification_version: 2
133
+ specification_version: 3
134
134
  summary: A Gem that enables ActiveRecord models to have a set of values defined in a certain class and stored in an integer bitfield on the database level.
135
135
  test_files:
136
136
  - test/test_helper.rb