attribute_predicates 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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