attribute_predicates 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/CHANGELOG.rdoc ADDED
@@ -0,0 +1,27 @@
1
+ == master
2
+
3
+ == 0.1.0 / 2008-07-03
4
+
5
+ * Rename to attribute_predicates
6
+
7
+ == 0.0.5 / 2008-06-19
8
+
9
+ * Avoid string evaluation for dynamic methods
10
+
11
+ == 0.0.4 / 2008-05-05
12
+
13
+ * Support for Rails 2.1
14
+ * Update documentation
15
+
16
+ == 0.0.3 / 2007-09-18
17
+
18
+ * Remove gem dependency on activerecord
19
+ * Convert dos newlines to unix newlines
20
+
21
+ == 0.0.2 / 2007-02-02
22
+
23
+ * Released as a gem
24
+
25
+ == 0.0.1 / 2007-01-04
26
+
27
+ * Initial release
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006-2008 Aaron Pfeifer
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,135 @@
1
+ = attribute_predicates
2
+
3
+ +attribute_predicates+ adds automatic generation of predicate methods (truth
4
+ accessors) when defining attributes using +attr+, +attr_reader+, +attr_writer+, and
5
+ +attr_accessor+.
6
+
7
+ == Resources
8
+
9
+ API
10
+
11
+ * http://api.pluginaweek.org/attribute_predicates
12
+
13
+ Bugs
14
+
15
+ * http://pluginaweek.lighthouseapp.com/projects/13777-attribute_predicates
16
+
17
+ Development
18
+
19
+ * http://github.com/pluginaweek/attribute_predicates
20
+
21
+ Source
22
+
23
+ * git://github.com/pluginaweek/attribute_predicates.git
24
+
25
+ == Description
26
+
27
+ When you define attributes within your classes and want to use the
28
+ predicate-style methods (i.e. "def foo?; end"), then you have to define these
29
+ yourself. This is a repetitive task especially if you want to query attributes
30
+ that may not necessarily contain just true/false. For example, an attribute
31
+ may contain 0, or the string "false". In this case, you would need to do
32
+ special checks to see whether or not the value is really false.
33
+
34
+ +attribute_predicates+ makes it easy by automatically generating predicate-style
35
+ methods for all attributes that are created using +attr+, +attr_reader+, +attr_writer+,
36
+ and +attr_accessor+. In addition, there is support for ActiveRecord's
37
+ non-standard truth accessor implementation (see below).
38
+
39
+ All of these shortcuts have the same interface and meaning as you would normally
40
+ find.
41
+
42
+ == Usage
43
+
44
+ === Ruby Attributes
45
+
46
+ ==== attr
47
+
48
+ This method takes a symbol (the name of the attribute) and an optional argument
49
+ for whether or not the attribute is writeable. For example,
50
+
51
+ module Mod
52
+ attr :is_okay, true
53
+ end
54
+
55
+ is equivalent to:
56
+
57
+ module Mod
58
+ def is_okay
59
+ @is_okay
60
+ end
61
+
62
+ def is_okay=(val)
63
+ @is_okay = value
64
+ end
65
+
66
+ def is_okay?
67
+ !is_okay.blank?
68
+ end
69
+ end
70
+
71
+ ==== attr_reader
72
+
73
+ This method is equivalent to calling <tt>battr(symbol, false)</tt> on each symbol in
74
+ turn. For example,
75
+
76
+ module Mod
77
+ attr_reader :is_good, :is_bad
78
+ end
79
+
80
+ Mod.instance_methods.sort #=> ["is_bad", "is_bad?", "is_good", "is_good?"]
81
+
82
+ ==== attr_writer
83
+
84
+ This method creates an accessor and predicate method for each symbol in turn.
85
+ For example,
86
+
87
+ module Mod
88
+ attr_writer :is_good, :is_bad
89
+ end
90
+
91
+ Mod.instance_methods.sort #=> ["is_bad=", "is_bad?", "is_good=", "is_good?"]
92
+
93
+ ==== attr_accessor
94
+
95
+ This method is equivalent to calling <tt>attr(symbol, true)</tt> on each symbol in
96
+ turn. For example,
97
+
98
+ module Mod
99
+ attr_accessor :is_good, :is_bad
100
+ end
101
+
102
+ Mod.instance_methods.sort #=> ["is_bad", "is_bad=", "is_bad?", "is_good", "is_good=", "is_good?"]
103
+
104
+ === ActiveRecord Attributes
105
+
106
+ The predicate method has a slightly more complex implementation for subclasses
107
+ of ActiveRecord::Base. It is built from how ActiveRecord implemented querying
108
+ attributes. The following lists show which values will return false/true:
109
+
110
+ For String, the following values return true:
111
+ * "true"
112
+ * "t"
113
+
114
+ For Integer, the following values return true:
115
+ * 1
116
+
117
+ For all other types, the predicate will return false.
118
+
119
+ == Testing
120
+
121
+ Before you can run any tests, the following gem must be installed:
122
+ * plugin_test_helper[http://github.com/pluginaweek/plugin_test_helper]
123
+
124
+ To run against a specific version of Rails:
125
+
126
+ rake test RAILS_FRAMEWORK_ROOT=/path/to/rails
127
+
128
+ == Dependencies
129
+
130
+ * Rails 2.0 or later
131
+
132
+ == References
133
+
134
+ * Yurii Rashkovskii - {Boolean Attributes in Ruby}[http://rashkovskii.com/articles/2007/01/04/boolean-attributes-in-ruby]
135
+ * Evan Weaver - {truth accessors in rails}[http://blog.evanweaver.com/articles/2007/01/05/truth-accessors-in-rails]
data/Rakefile ADDED
@@ -0,0 +1,88 @@
1
+ require 'rake/testtask'
2
+ require 'rake/rdoctask'
3
+ require 'rake/gempackagetask'
4
+ require 'rake/contrib/sshpublisher'
5
+
6
+ spec = Gem::Specification.new do |s|
7
+ s.name = 'attribute_predicates'
8
+ s.version = '0.1.0'
9
+ s.platform = Gem::Platform::RUBY
10
+ s.summary = 'Adds automatic generation of predicate methods for attributes.'
11
+
12
+ s.files = FileList['{lib,test}/**/*'].to_a + %w(CHANGELOG.rdoc init.rb LICENSE Rakefile README.rdoc)
13
+ s.require_path = 'lib'
14
+ s.has_rdoc = true
15
+ s.test_files = Dir['test/**/*_test.rb']
16
+
17
+ s.author = 'Aaron Pfeifer'
18
+ s.email = 'aaron@pluginaweek.org'
19
+ s.homepage = 'http://www.pluginaweek.org'
20
+ s.rubyforge_project = 'pluginaweek'
21
+ end
22
+
23
+ desc 'Default: run all tests.'
24
+ task :default => :test
25
+
26
+ desc "Test the #{spec.name} plugin."
27
+ Rake::TestTask.new(:test) do |t|
28
+ t.libs << 'lib'
29
+ t.test_files = spec.test_files
30
+ t.verbose = true
31
+ end
32
+
33
+ begin
34
+ require 'rcov/rcovtask'
35
+ namespace :test do
36
+ desc "Test the #{spec.name} plugin with Rcov."
37
+ Rcov::RcovTask.new(:rcov) do |t|
38
+ t.libs << 'lib'
39
+ t.test_files = spec.test_files
40
+ t.rcov_opts << '--exclude="^(?!lib/)"'
41
+ t.verbose = true
42
+ end
43
+ end
44
+ rescue LoadError
45
+ end
46
+
47
+ desc "Generate documentation for the #{spec.name} plugin."
48
+ Rake::RDocTask.new(:rdoc) do |rdoc|
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = spec.name
51
+ rdoc.template = '../rdoc_template.rb'
52
+ rdoc.options << '--line-numbers'
53
+ rdoc.rdoc_files.include('README.rdoc', 'CHANGELOG.rdoc', 'LICENSE', 'lib/**/*.rb')
54
+ end
55
+
56
+ Rake::GemPackageTask.new(spec) do |p|
57
+ p.gem_spec = spec
58
+ p.need_tar = true
59
+ p.need_zip = true
60
+ end
61
+
62
+ desc 'Publish the beta gem.'
63
+ task :pgem => [:package] do
64
+ Rake::SshFilePublisher.new('aaron@pluginaweek.org', '/home/aaron/gems.pluginaweek.org/public/gems', 'pkg', "#{spec.name}-#{spec.version}.gem").upload
65
+ end
66
+
67
+ desc 'Publish the API documentation.'
68
+ task :pdoc => [:rdoc] do
69
+ Rake::SshDirPublisher.new('aaron@pluginaweek.org', "/home/aaron/api.pluginaweek.org/public/#{spec.name}", 'rdoc').upload
70
+ end
71
+
72
+ desc 'Publish the API docs and gem'
73
+ task :publish => [:pgem, :pdoc, :release]
74
+
75
+ desc 'Publish the release files to RubyForge.'
76
+ task :release => [:gem, :package] do
77
+ require 'rubyforge'
78
+
79
+ ruby_forge = RubyForge.new.configure
80
+ ruby_forge.login
81
+
82
+ %w(gem tgz zip).each do |ext|
83
+ file = "pkg/#{spec.name}-#{spec.version}.#{ext}"
84
+ puts "Releasing #{File.basename(file)}..."
85
+
86
+ ruby_forge.add_release(spec.rubyforge_project, spec.name, spec.version, file)
87
+ end
88
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'attribute_predicates'
@@ -0,0 +1,2 @@
1
+ require 'attribute_predicates/extensions/module'
2
+ require 'attribute_predicates/extensions/active_record'
@@ -0,0 +1,22 @@
1
+ module PluginAWeek #:nodoc:
2
+ module AttributePredicates
3
+ module ActiveRecord
4
+ private
5
+ # For Strings, returns true when value is:
6
+ # * "true"
7
+ # * "t"
8
+ #
9
+ # For Integers, returns true when value is:
10
+ # * 1
11
+ def attr_predicate(symbol)
12
+ define_method("#{symbol}?") do
13
+ ::ActiveRecord::ConnectionAdapters::Column.value_to_boolean(instance_variable_get("@#{symbol}"))
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ ActiveRecord::Base.class_eval do
21
+ extend PluginAWeek::AttributePredicates::ActiveRecord
22
+ end if defined?(ActiveRecord)
@@ -0,0 +1,37 @@
1
+ module PluginAWeek #:nodoc:
2
+ module AttributePredicates
3
+ module Module
4
+ def self.included(base) #:nodoc:
5
+ base.class_eval do
6
+ [:attr, :attr_reader, :attr_writer, :attr_accessor].each do |method|
7
+ alias_method_chain method, :predicates
8
+ end
9
+ end
10
+ end
11
+
12
+ def attr_with_predicates(*args) #:nodoc:
13
+ attr_without_predicates(*args)
14
+ attr_predicate(args.first)
15
+ end
16
+
17
+ [:attr_reader, :attr_writer, :attr_accessor].each do |method|
18
+ define_method("#{method}_with_predicates") do |*symbols|
19
+ send("#{method}_without_predicates", *symbols)
20
+ symbols.each {|symbol| attr_predicate(symbol)}
21
+ end
22
+ end
23
+
24
+ private
25
+ # Returns true if the specified variable is not blank, otherwise false
26
+ def attr_predicate(symbol)
27
+ define_method("#{symbol}?") do
28
+ !instance_variable_get("@#{symbol}").blank?
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ ::Module.class_eval do
36
+ include PluginAWeek::AttributePredicates::Module
37
+ end
@@ -0,0 +1,42 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class ActiveRecordTest < Test::Unit::TestCase
4
+ def setup
5
+ @klass = Class.new(ActiveRecord::Base) do
6
+ def initialize(value)
7
+ self.foo = value
8
+ end
9
+ end
10
+ end
11
+
12
+ def test_should_evaluate_string_values
13
+ @klass.attr_accessor(:foo)
14
+
15
+ [nil, '', 'Name'].each do |value|
16
+ assert_equal false, @klass.new(value).foo?, "#{value.inspect} is true"
17
+ end
18
+ end
19
+
20
+ def test_should_evaluate_numeric_values
21
+ @klass.attr_accessor(:foo)
22
+
23
+ [nil, 0, '0'].each do |value|
24
+ assert_equal false, @klass.new(value).foo?, "#{value.inspect} is true"
25
+ end
26
+
27
+ assert_equal true, @klass.new(1).foo?, '1 is false'
28
+ assert_equal true, @klass.new('1').foo?, '"1" is false'
29
+ end
30
+
31
+ def test_should_evaluate_boolean_values
32
+ @klass.attr_accessor(:foo)
33
+
34
+ [nil, '', false, 'false', 'f', 0].each do |value|
35
+ assert_equal false, @klass.new(value).foo?, "#{value.inspect} is true"
36
+ end
37
+
38
+ [true, 'true', '1', 1].each do |value|
39
+ assert_equal true, @klass.new(value).foo?, "#{value.inspect} is false"
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,146 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Module
4
+ public :attr,
5
+ :attr_reader,
6
+ :attr_writer,
7
+ :attr_accessor,
8
+ :attr_predicate
9
+ end
10
+
11
+ class ModuleAttrTest < Test::Unit::TestCase
12
+ def setup
13
+ @module = Module.new
14
+ end
15
+
16
+ def test_should_create_predicate_for_readonly_attr
17
+ @module.attr(:foo)
18
+ ['foo', 'foo?'].each do |method|
19
+ assert @module.instance_methods.include?(method), "#{method} does not exist"
20
+ end
21
+
22
+ ['foo='].each do |method|
23
+ assert !@module.instance_methods.include?(method), "#{method} exists"
24
+ end
25
+ end
26
+
27
+ def test_should_create_predicate_for_readwrite_attr
28
+ @module.attr(:foo, true)
29
+ ['foo', 'foo=', 'foo?'].each do |method|
30
+ assert @module.instance_methods.include?(method), "#{method} does not exist"
31
+ end
32
+ end
33
+ end
34
+
35
+ class ModuleAttrReaderTest < Test::Unit::TestCase
36
+ def setup
37
+ @module = Module.new
38
+ end
39
+
40
+ def test_should_create_predicate
41
+ @module.attr_reader(:foo)
42
+ ['foo', 'foo?'].each do |method|
43
+ assert @module.instance_methods.include?(method), "#{method} does not exist"
44
+ end
45
+
46
+ ['foo='].each do |method|
47
+ assert !@module.instance_methods.include?(method), "#{method} exists"
48
+ end
49
+ end
50
+
51
+ def test_should_create_predicate_for_multiple_attributes
52
+ @module.attr_reader(:foo, :bar)
53
+ ['foo', 'foo?', 'bar', 'bar?'].each do |method|
54
+ assert @module.instance_methods.include?(method), "#{method} does not exist"
55
+ end
56
+
57
+ ['foo=', 'bar='].each do |method|
58
+ assert !@module.instance_methods.include?(method), "#{method} exists"
59
+ end
60
+ end
61
+ end
62
+
63
+ class ModuleAttrAccessorTest < Test::Unit::TestCase
64
+ def setup
65
+ @module = Module.new
66
+ end
67
+
68
+ def test_should_create_predicate
69
+ @module.attr_accessor(:foo)
70
+ ['foo', 'foo=', 'foo?'].each do |method|
71
+ assert @module.instance_methods.include?(method), "#{method} does not exist"
72
+ end
73
+ end
74
+
75
+ def test_should_create_predicate_for_multiple_attributes
76
+ @module.attr_accessor(:foo, :bar)
77
+ ['foo', 'foo=', 'foo?', 'bar', 'bar=', 'bar?'].each do |method|
78
+ assert @module.instance_methods.include?(method), "#{method} does not exist"
79
+ end
80
+ end
81
+ end
82
+
83
+ class ModuleAttrWriterTest < Test::Unit::TestCase
84
+ def setup
85
+ @module = Module.new
86
+ end
87
+
88
+ def test_should_create_predicate
89
+ @module.attr_writer(:foo)
90
+ ['foo=', 'foo?'].each do |method|
91
+ assert @module.instance_methods.include?(method), "#{method} does not exist"
92
+ end
93
+
94
+ ['foo'].each do |method|
95
+ assert !@module.instance_methods.include?(method), "#{method} exists"
96
+ end
97
+ end
98
+
99
+ def test_should_create_predicate_for_multiple_attributes
100
+ @module.attr_writer(:foo, :bar)
101
+ ['foo=', 'foo?', 'bar=', 'bar?'].each do |method|
102
+ assert @module.instance_methods.include?(method), "#{method} does not exist"
103
+ end
104
+
105
+ ['foo', 'bar'].each do |method|
106
+ assert !@module.instance_methods.include?(method), "#{method} exists"
107
+ end
108
+ end
109
+ end
110
+
111
+ class ModuleAttrPredicateTest < Test::Unit::TestCase
112
+ def setup
113
+ @module = Module.new
114
+ end
115
+
116
+ def test_should_create_predicate
117
+ @module.attr_predicate(:foo)
118
+ assert @module.instance_methods.include?('foo?'), 'foo? does not exist'
119
+ end
120
+ end
121
+
122
+ class ModuleTest < Test::Unit::TestCase
123
+ def setup
124
+ @klass = Class.new do
125
+ def initialize(value)
126
+ self.foo = value
127
+ end
128
+ end
129
+ end
130
+
131
+ def test_should_evaluate_false_values_for_predicate
132
+ @klass.attr_accessor(:foo)
133
+
134
+ [nil, '', ' ', {}, []].each do |value|
135
+ assert_equal false, @klass.new(value).foo?, "#{value.inspect} is true"
136
+ end
137
+ end
138
+
139
+ def test_should_evaluate_true_values_for_predicate
140
+ @klass.attr_accessor(:foo)
141
+
142
+ [1, 'hello world', {1 => 1}, [1]].each do |value|
143
+ assert_equal true, @klass.new(value).foo?, "#{value.inspect} is false"
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,4 @@
1
+ # Load the plugin testing framework
2
+ $:.unshift("#{File.dirname(__FILE__)}/../../plugin_test_helper/lib")
3
+ require 'rubygems'
4
+ require 'plugin_test_helper'
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: attribute_predicates
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Aaron Pfeifer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-07-03 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: aaron@pluginaweek.org
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/attribute_predicates.rb
26
+ - lib/attribute_predicates
27
+ - lib/attribute_predicates/extensions
28
+ - lib/attribute_predicates/extensions/active_record.rb
29
+ - lib/attribute_predicates/extensions/module.rb
30
+ - test/active_record_test.rb
31
+ - test/test_helper.rb
32
+ - test/module_test.rb
33
+ - CHANGELOG.rdoc
34
+ - init.rb
35
+ - LICENSE
36
+ - Rakefile
37
+ - README.rdoc
38
+ has_rdoc: true
39
+ homepage: http://www.pluginaweek.org
40
+ post_install_message:
41
+ rdoc_options: []
42
+
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ requirements: []
58
+
59
+ rubyforge_project: pluginaweek
60
+ rubygems_version: 1.1.1
61
+ signing_key:
62
+ specification_version: 2
63
+ summary: Adds automatic generation of predicate methods for attributes.
64
+ test_files:
65
+ - test/active_record_test.rb
66
+ - test/module_test.rb