dm-is-select 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,16 @@
1
+ ## OS STUFF
2
+ .DS_Store
3
+
4
+ ## TM SPECIFIC
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## PROJECT::GENERAL
9
+ *.sw?
10
+ coverage
11
+ rdoc
12
+ pkg
13
+ doc
14
+
15
+ ## PROJECT::SPECIFIC
16
+
@@ -0,0 +1,24 @@
1
+ === 0.0.1 / 2009-07-12
2
+
3
+ * Release!
4
+
5
+ === 0.0.2 / 2009-07-15
6
+
7
+ * Added Top Level Parent support in output.
8
+
9
+ === 0.0.3 / 2009-08-20
10
+
11
+ * Fixed rendering bug in gem server when the description contained the <tt><select></tt> tag
12
+ * Converted History.txt to .rdoc
13
+ * Improved the Rakefile docs output
14
+ * Added support for custom SQL queries.
15
+
16
+
17
+ === 0.0.4 / 2009-10-30
18
+
19
+ * Changed the output order of options array from [key, value] to [value, key] to link with options better.
20
+
21
+ === 0.0.5 / 2009-10-30
22
+
23
+ * Somehow reintroduced the rendering bug in the gemspec description fixed in 0.0.3
24
+ * Updated History.rdoc
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 mats
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.
@@ -0,0 +1,170 @@
1
+ = dm-is-select
2
+
3
+ A DataMapper plugin that makes getting the <tt><select></tt> options from a Model easier.
4
+
5
+
6
+ == Installation
7
+
8
+ # Add Gemcutter to your RubyGems sources
9
+ $ gem sources -a http://gemcutter.com
10
+
11
+ $ (sudo)? gem install dm-is-select
12
+
13
+ === Dependencies
14
+
15
+ The plugin depends upon the following:
16
+
17
+ * dm-core ( >= 0.10.0)
18
+ * dm-more ( >= 0.10.0) [not really, but your code will depend upon it]
19
+
20
+
21
+ <b>NB!</b> The plugin has been developed for and on DM's next branch[http://github.com/datamapper/dm-core/tree/next], so may NOT work on previous incarnations.
22
+
23
+
24
+
25
+ == Getting Started
26
+
27
+ Let's say you got a basic Category Model.
28
+
29
+ class Category
30
+ include DataMapper::Resource
31
+ property :id, Serial
32
+ property :name, String
33
+
34
+ is :select, :name
35
+
36
+ end
37
+
38
+ Through that simple declaration you get the following class method ..
39
+
40
+ Category.items_for_select_menu
41
+
42
+ ...which returns an Array with the Model items in a structured way, ready for use.
43
+
44
+ [
45
+ [nil, "Select Category"],
46
+ ["nil", " ------ "],
47
+ [1, "Category 1"],
48
+ [2, "Category 2"],
49
+ [3, "Category 3"],
50
+ [4, "Category 4"],
51
+ [5, "Category 5"]
52
+ ]
53
+
54
+ Great, but you don't want the prompt to say "Select Category", but
55
+
56
+ Category.items_for_select_menu( :prompt => "Choose Whatever" )
57
+
58
+
59
+ ...which returns the Array with the prompt changed
60
+
61
+ [
62
+ [nil, "Choose Whatever"],
63
+ ["nil", " ------ "],
64
+ [1, "Category 1"],
65
+ ...<snip>...
66
+ ]
67
+
68
+
69
+ OK, but you don't like the divider node (2nd in output above). That’s fine, you remove it like this:
70
+
71
+ Category.items_for_select_menu( :divider => false )
72
+
73
+
74
+ ...which returns the Array with the divider removed
75
+
76
+ [
77
+ [nil, "Select Category"],
78
+ [1, "Category 1"],
79
+ ...<snip>...
80
+ ]
81
+
82
+
83
+
84
+ Hmm, fine, but I don't want either a prompt or a divider, you say. That's fine too.
85
+
86
+ Category.items_for_select_menu( :prompt => false )
87
+
88
+ ...which returns the Array with the prompt and divider removed
89
+
90
+ [
91
+ [1, "Category 1"],
92
+ [1, "Category 2"],
93
+ ...<snip>...
94
+ ]
95
+
96
+
97
+ OK, that's smooth, but my Category model is a tree with parents, children and so on. This won't work with that.
98
+
99
+ Sure, no problem, just do this when you declare the Model:
100
+
101
+ is :select, :name, :is_tree => true
102
+
103
+
104
+ Then you can just use this
105
+
106
+ Category.items_for_select_menu( :prompt => "Choose Parent" )
107
+
108
+ ...and you get this nicely formatted <tt><select></tt> options array
109
+
110
+ [
111
+ [nil, "Choose Parent"],
112
+ ["nil", " ------ "],
113
+ [0, "Top Level Category"],
114
+ ["nil", " ------ "],
115
+ [1, "Parent-1"],
116
+ [2, "-- Parent-1-Child"],
117
+ [3, "-- -- Parent-1-Child-GrandChild"],
118
+ [4, "Parent-2"],
119
+ [5, "-- Parent-2-Child"],
120
+ [6, "-- -- Parent-2-Child-GrandChild"]
121
+ ]
122
+
123
+ <b>NB!</b> It only supports 3 levels at this point in time, as I think that's enough in most use cases,
124
+ but IF not, fix the code and let me know and I'll add it.
125
+
126
+ Cool, but that "Top Level Category" node is a bit ugly, but easily fixed.
127
+
128
+ Category.items_for_select_menu( :root_text => "1st Parent (root)" )
129
+
130
+ ...gives you:
131
+
132
+ [
133
+ ...<snip>...
134
+ ["nil", " ------ "],
135
+ [0, "1st Parent (root)"],
136
+ ["nil", " ------ "],
137
+ ...<snip>...
138
+ ]
139
+
140
+ You can even remove it all together by doing this:
141
+
142
+ Category.items_for_select_menu( :show_root => false )
143
+
144
+
145
+
146
+
147
+ Obviously all the config options from above works with Tree models as well.
148
+
149
+ == Last Few Words
150
+
151
+ OK, I admit it, not the most impressive DM plugin there is, but hey, it sure helps keeping your model/views cleaner.
152
+
153
+
154
+ == RTFM
155
+
156
+ For a better understanding of this gem/plugin, make sure you study the '<tt>dm-is-select/spec/integration/select_spec.rb</tt>' file.
157
+
158
+
159
+ == Errors / Bugs
160
+
161
+ If something is not behaving intuitively, it is a bug, and should be reported.
162
+ Report it here: http://github.com/kematzy/dm-is-select/issues
163
+
164
+ == Credits
165
+
166
+ Copyright (c) 2009-07-12 Kematzy [ kematzy gmail com ]
167
+
168
+ == Licence
169
+
170
+ Released under the MIT license.
@@ -0,0 +1,109 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "dm-is-select"
8
+ # gem.version = IO.read('VERSION')
9
+ gem.summary = %Q{A DataMapper plugin that makes getting the <tt>select</tt> options from a Model easier.}
10
+ gem.description = gem.summary
11
+ gem.email = "kematzy@gmail.com"
12
+ gem.homepage = "http://github.com/kematzy/dm-is-select"
13
+ gem.authors = ["kematzy"]
14
+ gem.extra_rdoc_files = %w[ README.rdoc LICENSE TODO History.rdoc ]
15
+ gem.add_dependency('dm-core', '>= 0.10.0')
16
+ gem.add_dependency('dm-more', '>= 0.10.0')
17
+ # gem.add_dependency('dm-validations', '>= 0.10.0')
18
+
19
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
20
+ end
21
+
22
+ rescue LoadError
23
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
24
+ end
25
+
26
+ require 'spec/rake/spectask'
27
+ Spec::Rake::SpecTask.new(:spec) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.spec_files = FileList['spec/**/*_spec.rb']
30
+ end
31
+
32
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
33
+ spec.libs << 'lib' << 'spec'
34
+ spec.pattern = 'spec/**/*_spec.rb'
35
+ spec.rcov = true
36
+ end
37
+
38
+ namespace :spec do
39
+
40
+ desc "Run all specifications verbosely"
41
+ Spec::Rake::SpecTask.new(:verbose) do |t|
42
+ t.libs << "lib"
43
+ t.spec_opts = ["--color", "--format", "specdoc", "--require", "spec/spec_helper.rb"]
44
+ end
45
+
46
+ desc "Run specific spec verbosely (SPEC=/path/2/file)"
47
+ Spec::Rake::SpecTask.new(:select) do |t|
48
+ t.libs << "lib"
49
+ t.spec_files = [ENV["SPEC"]]
50
+ t.spec_opts = ["--color", "--format", "specdoc", "--require", "spec/spec_helper.rb"]
51
+ end
52
+
53
+ end
54
+
55
+ task :default => :spec
56
+
57
+ require 'rake/rdoctask'
58
+ Rake::RDocTask.new do |rdoc|
59
+ version = File.exist?('VERSION') ? IO.read('VERSION').chomp : "[Unknown]"
60
+
61
+ rdoc.rdoc_dir = 'rdoc'
62
+ rdoc.title = "dm-is-select #{version}"
63
+ rdoc.rdoc_files.include('README*')
64
+ rdoc.rdoc_files.include('lib/**/*.rb')
65
+ end
66
+
67
+
68
+
69
+ desc 'Build the rdoc HTML Files'
70
+ task :docs do
71
+ version = File.exist?('VERSION') ? IO.read('VERSION').chomp : "[Unknown]"
72
+
73
+ sh "sdoc -N --title 'DM::Is::Select v#{version}' lib/dm-is-select README.rdoc"
74
+ end
75
+
76
+ namespace :docs do
77
+
78
+ desc 'Remove rdoc products'
79
+ task :remove => [:clobber_rdoc] do
80
+ sh "rm -rf doc"
81
+ end
82
+
83
+ desc 'Force a rebuild of the RDOC files'
84
+ task :rebuild => [:docs]
85
+
86
+ desc 'Build docs, and open in browser for viewing (specify BROWSER)'
87
+ task :open => [:docs] do
88
+ browser = ENV["BROWSER"] || "safari"
89
+ sh "open -a #{browser} doc/index.html"
90
+ end
91
+
92
+ end
93
+
94
+
95
+ # kept just as a reference for now.
96
+ #
97
+ # def sudo_gem(cmd)
98
+ # sh "#{SUDO} #{RUBY} -S gem #{cmd}", :verbose => false
99
+ # end
100
+ #
101
+ # desc "Install #{GEM_NAME} #{GEM_VERSION}"
102
+ # task :install => [ :package ] do
103
+ # sudo_gem "install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources"
104
+ # end
105
+ #
106
+ # desc "Uninstall #{GEM_NAME} #{GEM_VERSION}"
107
+ # task :uninstall => [ :clobber ] do
108
+ # sudo_gem "uninstall #{GEM_NAME} -v#{GEM_VERSION} -Ix"
109
+ # end
data/TODO ADDED
File without changes
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.5
@@ -0,0 +1,62 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
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{dm-is-select}
8
+ s.version = "0.0.5"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["kematzy"]
12
+ s.date = %q{2009-10-30}
13
+ s.description = %q{A DataMapper plugin that makes getting the <tt>select</tt> options from a Model easier.}
14
+ s.email = %q{kematzy@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "History.rdoc",
17
+ "LICENSE",
18
+ "README.rdoc",
19
+ "TODO"
20
+ ]
21
+ s.files = [
22
+ ".gitignore",
23
+ "History.rdoc",
24
+ "LICENSE",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "TODO",
28
+ "VERSION",
29
+ "dm-is-select.gemspec",
30
+ "lib/dm-is-select.rb",
31
+ "lib/dm-is-select/is/select.rb",
32
+ "lib/dm-is-select/is/version.rb",
33
+ "spec/integration/select_spec.rb",
34
+ "spec/spec.opts",
35
+ "spec/spec_helper.rb"
36
+ ]
37
+ s.homepage = %q{http://github.com/kematzy/dm-is-select}
38
+ s.rdoc_options = ["--charset=UTF-8"]
39
+ s.require_paths = ["lib"]
40
+ s.rubygems_version = %q{1.3.5}
41
+ s.summary = %q{A DataMapper plugin that makes getting the <tt>select</tt> options from a Model easier.}
42
+ s.test_files = [
43
+ "spec/integration/select_spec.rb",
44
+ "spec/spec_helper.rb"
45
+ ]
46
+
47
+ if s.respond_to? :specification_version then
48
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
+ s.add_runtime_dependency(%q<dm-core>, [">= 0.10.0"])
53
+ s.add_runtime_dependency(%q<dm-more>, [">= 0.10.0"])
54
+ else
55
+ s.add_dependency(%q<dm-core>, [">= 0.10.0"])
56
+ s.add_dependency(%q<dm-more>, [">= 0.10.0"])
57
+ end
58
+ else
59
+ s.add_dependency(%q<dm-core>, [">= 0.10.0"])
60
+ s.add_dependency(%q<dm-more>, [">= 0.10.0"])
61
+ end
62
+ end
@@ -0,0 +1,22 @@
1
+ # Needed to import datamapper and other gems
2
+ require 'rubygems'
3
+ require 'pathname'
4
+
5
+ # Add all external dependencies for the plugin here
6
+ gem 'dm-core', '~> 0.10.0'
7
+ require 'dm-core'
8
+ # gem 'extlib', '~> 0.9.13'
9
+ # require 'extlib'
10
+ gem 'dm-is-tree', '~> 0.10.0'
11
+ require 'dm-is-tree'
12
+
13
+
14
+ # Require plugin-files
15
+ require Pathname(__FILE__).dirname.expand_path / 'dm-is-select' / 'is' / 'select.rb'
16
+
17
+ DataMapper::Model.append_extensions(DataMapper::Is::Select)
18
+
19
+ # If you wish to add methods to all DM Models, use this:
20
+ #
21
+ # DataMapper::Model.append_inclusions(DataMapper::Is::Select::ResourceInstanceMethods)
22
+ #
@@ -0,0 +1,160 @@
1
+ module DataMapper
2
+ module Is
3
+
4
+ ##
5
+ # = dm-is-select
6
+ #
7
+ # A DataMapper plugin that makes getting the <tt><select></tt> options from a Model easier.
8
+ #
9
+ #
10
+ #
11
+ module Select
12
+
13
+ ##
14
+ # Defines the field to use for the select menu
15
+ #
16
+ # ==== Params
17
+ #
18
+ # * :field_name => the name of the field values shown in select
19
+ # * :options
20
+ # * :is_tree => whether if the current Model is an is :tree model. (Defaults to false)
21
+ #
22
+ # ==== Examples
23
+ #
24
+ #
25
+ # is :select, :name
26
+ # => creates a <select> options array on the :name attribute of the model
27
+ #
28
+ # is :select, :name, :is_tree => true
29
+ # => creates a <select> options array with the results ordered in hierarchical order
30
+ # parent > child > grandchild for each parent
31
+ #
32
+ #
33
+ # @api public
34
+ def is_select(select_field = :name, options = {})
35
+ raise ArgumentError, "The :select_field, must be an existing attribute in the Model. Got [ #{select_field.inspect} ]" unless properties.any?{ |p| p.name == select_field.to_sym }
36
+
37
+ @select_options = {
38
+ # add specical features if we are working with Tree Model
39
+ :is_tree => false
40
+ }.merge(options)
41
+
42
+ @select_field = select_field
43
+
44
+
45
+ # Add class & Instance methods
46
+ extend DataMapper::Is::Select::ClassMethods
47
+ # include DataMapper::Is::Select::InstanceMethods
48
+
49
+ end
50
+
51
+ module ClassMethods
52
+ attr_reader :select_field, :select_options
53
+
54
+ ##
55
+ # Provides the Model content in a ready to use <tt><select></tt> options array
56
+ #
57
+ # ==== Params
58
+ #
59
+ # * :options
60
+ # * :prompt [String/Boolean] => The text shown on the <tt><select></tt> field in the browser. (Defaults to "Select NameOfYourModel")
61
+ # * :divider [Boolean] => Whether to add a divider/separator between the prompt and the main options. (Defaults to +true+)
62
+ # * :order [Array] => A normal DM order declaration. (Defaults to [:name] or the name of the select_field declared)
63
+ # * :show_root [Boolean] => Whether to add the Top Level Parent in the choices. (Defaults to +true+)
64
+ # * :root_text [String] => The text to show as the Parent item in select list. (Defaults to "Top Level NameOfYourModel")
65
+ #
66
+ # ==== Examples
67
+ #
68
+ # Category.items_for_select_menu
69
+ # => [ [nil, 'Select Category'], [nil, '---'], [1, 'Category 1'] ,....]
70
+ #
71
+ # Category.items_for_select_menu(:prompt => "Custom Prompt")
72
+ # => [ [nil, 'Custom Prompt'],...]
73
+ #
74
+ # Category.items_for_select_menu(:prompt => false)
75
+ # => [ [1, 'Category 1'] ,...]
76
+ #
77
+ # Category.items_for_select_menu(:divider => false )
78
+ # => array without the [nil, '---'] node
79
+ #
80
+ # Category.items_for_select_menu(:order => [ :id.desc ] )
81
+ # => array with the order reversed. (Prompts & divider always comes first)
82
+ #
83
+ # Category.items_for_select_menu(:publish_status => "on", :order => [ :id.desc ] )
84
+ # => returns only those items that matches the query params or just an empty Select Menu
85
+ #
86
+ # If your model is a Tree:
87
+ #
88
+ # Category.items_for_select_menu(:root_text => "Custom Root Text") # sets the text for the Top Level (root) Parent
89
+ # => [ ..., [0, 'Custom Root Text'],...]
90
+ #
91
+ # Category.items_for_select_menu(:show_root => false) # removes the Top Level (root) Parent from the
92
+ #
93
+ #
94
+ # @api public
95
+ def items_for_select_menu(options = {})
96
+ # clean out the various parts
97
+ html_options = options.only(:prompt, :divider, :show_root, :root_text)
98
+ sql_options = options.except(:prompt, :divider, :show_root, :root_text)
99
+ # puts "sql_options=[#{sql_options.inspect}] [#{__FILE__}:#{__LINE__}]"
100
+ # puts "html_options=[#{html_options.inspect}] [#{__FILE__}:#{__LINE__}]"
101
+
102
+ options = {
103
+ :prompt => "Select #{self.name}",
104
+ :divider => true,
105
+ :show_root => true,
106
+ :root_text => "Top Level #{self.name}",
107
+ }.merge(html_options)
108
+
109
+ sql_options = {
110
+ :order => [self.select_field.to_sym],
111
+ }.merge(sql_options)
112
+
113
+ mi = self.select_options[:is_tree] ?
114
+ all({ :parent_id => 0 }.merge(sql_options) ) :
115
+ all(sql_options)
116
+
117
+ res = []
118
+ if options[:prompt]
119
+ res << [nil, options[:prompt]]
120
+ res << ['nil', " ------ "] if options[:divider]
121
+ if self.select_options[:is_tree]
122
+ if options[:show_root]
123
+ res << [0, options[:root_text]]
124
+ res << ['nil'," ------ "] if options[:divider]
125
+ end
126
+ end
127
+ end
128
+
129
+ if self.select_options[:is_tree]
130
+ mi.each do |x|
131
+ res << [x.id, x.send(self.select_field)]
132
+ unless x.children.blank?
133
+ x.children.each do |child|
134
+ res << [child.id, "-- #{child.send(self.select_field)}"]
135
+ child.children.each do |grand_child|
136
+ res << [ grand_child.id, "-- -- #{grand_child.send(self.select_field)}"]
137
+ end unless child.children.blank?
138
+ end
139
+ end
140
+ end
141
+ else
142
+ mi.each do |x|
143
+ res << [x.id, x.send(self.select_field)]
144
+ end
145
+ end
146
+ res
147
+ end
148
+
149
+ end # ClassMethods
150
+
151
+ # module InstanceMethods
152
+ #
153
+ # end # InstanceMethods
154
+
155
+ end # Select
156
+ end # Is
157
+
158
+ Model.append_extensions(Is::Select)
159
+
160
+ end # DataMapper
@@ -0,0 +1,7 @@
1
+ module DataMapper
2
+ module Is
3
+ module Select
4
+ VERSION = '0.0.5'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,285 @@
1
+ require 'pathname'
2
+ require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
3
+
4
+ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
5
+ describe 'DataMapper::Is::Select' do
6
+
7
+ class Category
8
+ include DataMapper::Resource
9
+ property :id, Serial
10
+ property :name, String
11
+ property :publish_status, String, :default => "on"
12
+
13
+ is :select, :name
14
+
15
+ auto_migrate!
16
+ end
17
+
18
+ class TreeCategory
19
+ include DataMapper::Resource
20
+ property :id, Serial
21
+ property :name, String
22
+ property :publish_status, String, :default => "on"
23
+
24
+ is :tree, :order => :name
25
+ is :select, :name, :is_tree => true
26
+
27
+ auto_migrate!
28
+ end
29
+
30
+ 5.times do |n|
31
+ Category.create(:name => "Category #{n+1}")
32
+ end
33
+
34
+ 2.times do |parent_id|
35
+ parent_id += 1
36
+ parent = TreeCategory.create(:name => "TreeCategory-#{parent_id}" , :parent_id => 0 )
37
+ child = TreeCategory.create(:name => "TreeCategory-#{parent_id}-Child" , :parent_id => parent.id )
38
+ grandchild = TreeCategory.create(:name => "TreeCategory-#{parent_id}-Child-GrandChild" , :parent_id => child.id )
39
+ end
40
+
41
+
42
+ describe "Class Methods" do
43
+
44
+ describe "is :select" do
45
+
46
+ it "should work with both strings & symbols as the fieldname provided" do
47
+ lambda {
48
+ class Dummy
49
+ include DataMapper::Resource
50
+ property :id, Serial
51
+ property :name, String
52
+
53
+ is :select, 'name'
54
+ auto_migrate!
55
+ end
56
+
57
+ }.should_not raise_error(ArgumentError)
58
+ end
59
+
60
+ it "should raise an ArgumentError if non-existant field is provided" do
61
+ lambda {
62
+ class Dummy
63
+ include DataMapper::Resource
64
+ property :id, Serial
65
+ property :name, String
66
+
67
+ is :select, :does_not_exist
68
+ auto_migrate!
69
+ end
70
+
71
+ }.should raise_error(ArgumentError)
72
+ end
73
+
74
+ end #/ is :select
75
+
76
+ describe "#items_for_select_menu" do
77
+
78
+ describe "A Normal Model" do
79
+
80
+ it "should return the default select options when given no params" do
81
+ Category.items_for_select_menu.should == [
82
+ [nil, "Select Category"],
83
+ ["nil", " ------ "],
84
+ [1, "Category 1"],
85
+ [2, "Category 2"],
86
+ [3, "Category 3"],
87
+ [4, "Category 4"],
88
+ [5, "Category 5"]
89
+ ]
90
+ end
91
+
92
+ it "should return the select options with custom prompt when given the :prompt => ? " do
93
+ Category.items_for_select_menu(:prompt => "Custom Prompt " ).should == [
94
+ [nil, "Custom Prompt "],
95
+ ["nil", " ------ "],
96
+ [1, "Category 1"],
97
+ [2, "Category 2"],
98
+ [3, "Category 3"],
99
+ [4, "Category 4"],
100
+ [5, "Category 5"]
101
+ ]
102
+ end
103
+
104
+ it "should return the select options without a prompt & divider when given :prompt => false" do
105
+ Category.items_for_select_menu(:prompt => false ).should == [
106
+ [1, "Category 1"],
107
+ [2, "Category 2"],
108
+ [3, "Category 3"],
109
+ [4, "Category 4"],
110
+ [5, "Category 5"]
111
+ ]
112
+ end
113
+
114
+ it "should return the select options without a prompt & divider when given :prompt => true" do
115
+ # TODO:: this should be reworked, but right now it's good enough
116
+ Category.items_for_select_menu(:prompt => true ).should == [
117
+ [nil, true],
118
+ ["nil", " ------ "],
119
+ [1, "Category 1"],
120
+ [2, "Category 2"],
121
+ [3, "Category 3"],
122
+ [4, "Category 4"],
123
+ [5, "Category 5"]
124
+ ]
125
+ end
126
+
127
+ it "should return the select options without the divider when given :divider => false" do
128
+ Category.items_for_select_menu(:divider => false ).should == [
129
+ [nil, "Select Category"],
130
+ [1, "Category 1"],
131
+ [2, "Category 2"],
132
+ [3, "Category 3"],
133
+ [4, "Category 4"],
134
+ [5, "Category 5"]
135
+ ]
136
+ end
137
+
138
+ it "should return the select options with reversed order when given :order => DESC" do
139
+ Category.items_for_select_menu(:order => [ :id.desc ] ).should == [
140
+ [nil, "Select Category"],
141
+ ["nil", " ------ "],
142
+ [5, "Category 5"],
143
+ [4, "Category 4"],
144
+ [3, "Category 3"],
145
+ [2, "Category 2"],
146
+ [1, "Category 1"]
147
+ ]
148
+ end
149
+
150
+ it "should respect the SQL select options" do
151
+ c = Category.get(1)
152
+ c.publish_status = 'off'
153
+ c.save
154
+
155
+ Category.items_for_select_menu(:publish_status => "on", :order => [ :id.desc ] ).should == [
156
+ [nil, "Select Category"],
157
+ ["nil", " ------ "],
158
+ [5, "Category 5"],
159
+ [4, "Category 4"],
160
+ [3, "Category 3"],
161
+ [2, "Category 2"],
162
+ # [1, "Category 1"]
163
+ ]
164
+ end
165
+ it "should handle invalid SQL select options" do
166
+ Category.items_for_select_menu(:publish_status => "invalid", :order => [ :id.desc ] ).should == [
167
+ [nil, "Select Category"],
168
+ ["nil", " ------ "],
169
+ # [5, "Category 5"],
170
+ # [4, "Category 4"],
171
+ # [3, "Category 3"],
172
+ # [2, "Category 2"],
173
+ # [1, "Category 1"]
174
+ ]
175
+ end
176
+
177
+ end #/ Normal Model
178
+
179
+ describe "Tree Model" do
180
+
181
+ it "should return the default select options when given no params" do
182
+ TreeCategory.items_for_select_menu.should == [
183
+ [nil, "Select TreeCategory"],
184
+ ["nil", " ------ "],
185
+ [0, "Top Level TreeCategory"],
186
+ ["nil", " ------ "],
187
+ [1, "TreeCategory-1"],
188
+ [2, "-- TreeCategory-1-Child"],
189
+ [3, "-- -- TreeCategory-1-Child-GrandChild"],
190
+ [4, "TreeCategory-2"],
191
+ [5, "-- TreeCategory-2-Child"],
192
+ [6, "-- -- TreeCategory-2-Child-GrandChild"]
193
+ ]
194
+ end
195
+
196
+ it "should return the select options with reversed order when given :order => DESC" do
197
+ TreeCategory.items_for_select_menu(:order => [ :id.desc ] ).should == [
198
+ [nil, "Select TreeCategory"],
199
+ ["nil", " ------ "],
200
+ [0, "Top Level TreeCategory"],
201
+ ["nil", " ------ "],
202
+ [4, "TreeCategory-2"],
203
+ [5, "-- TreeCategory-2-Child"],
204
+ [6, "-- -- TreeCategory-2-Child-GrandChild"],
205
+ [1, "TreeCategory-1"],
206
+ [2, "-- TreeCategory-1-Child"],
207
+ [3, "-- -- TreeCategory-1-Child-GrandChild"]
208
+ ]
209
+ end
210
+
211
+ it "should return the select options without the Top Level Parent when given :show_root => false" do
212
+ TreeCategory.items_for_select_menu(:show_root => false).should == [
213
+ [nil, "Select TreeCategory"],
214
+ ["nil", " ------ "],
215
+ [1, "TreeCategory-1"],
216
+ [2, "-- TreeCategory-1-Child"],
217
+ [3, "-- -- TreeCategory-1-Child-GrandChild"],
218
+ [4, "TreeCategory-2"],
219
+ [5, "-- TreeCategory-2-Child"],
220
+ [6, "-- -- TreeCategory-2-Child-GrandChild"]
221
+ ]
222
+ end
223
+
224
+ it "should return the select options with custom text for the Top Level Parent when given :root_text => ?" do
225
+ TreeCategory.items_for_select_menu(:root_text => "Custom Top Level Text").should == [
226
+ [nil, "Select TreeCategory"],
227
+ ["nil", " ------ "],
228
+ [0, "Custom Top Level Text"],
229
+ ["nil", " ------ "],
230
+ [1, "TreeCategory-1"],
231
+ [2, "-- TreeCategory-1-Child"],
232
+ [3, "-- -- TreeCategory-1-Child-GrandChild"],
233
+ [4, "TreeCategory-2"],
234
+ [5, "-- TreeCategory-2-Child"],
235
+ [6, "-- -- TreeCategory-2-Child-GrandChild"]
236
+ ]
237
+ end
238
+
239
+ it "should respect the SQL select options" do
240
+ c = TreeCategory.get(1)
241
+ c.publish_status = 'off'
242
+ c.save
243
+
244
+ TreeCategory.items_for_select_menu( :publish_status => "on", :order => [ :id.desc ] ).should == [
245
+ [nil, "Select TreeCategory"],
246
+ ["nil", " ------ "],
247
+ [0, "Top Level TreeCategory"],
248
+ ["nil", " ------ "],
249
+ [4, "TreeCategory-2"],
250
+ [5, "-- TreeCategory-2-Child"],
251
+ [6, "-- -- TreeCategory-2-Child-GrandChild"],
252
+ # [1, "TreeCategory-1"],
253
+ # [2, "-- TreeCategory-1-Child"],
254
+ # [3, "-- -- TreeCategory-1-Child-GrandChild"]
255
+ ]
256
+ end
257
+
258
+ it "should handle invalid SQL select options" do
259
+ TreeCategory.items_for_select_menu( :publish_status => "invalid", :order => [ :id.desc ] ).should == [
260
+ [nil, "Select TreeCategory"],
261
+ ["nil", " ------ "],
262
+ [0, "Top Level TreeCategory"],
263
+ ["nil", " ------ "],
264
+ # [4, "TreeCategory-2"],
265
+ # [5, "-- TreeCategory-2-Child"],
266
+ # [6, "-- -- TreeCategory-2-Child-GrandChild"],
267
+ # [1, "TreeCategory-1"],
268
+ # [2, "-- TreeCategory-1-Child"],
269
+ # [3, "-- -- TreeCategory-1-Child-GrandChild"]
270
+ ]
271
+ end
272
+
273
+ end #/ Tree Model
274
+
275
+ end #/ #item_for_select_menu
276
+
277
+ end #/ Class Methods
278
+
279
+ # describe "Instance Methods" do
280
+ #
281
+ # end #/ Instance Methods
282
+
283
+ end #/ DataMapper::Is::Select
284
+
285
+ end #/ if
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,28 @@
1
+ require 'pathname'
2
+ require 'rubygems'
3
+
4
+ gem 'rspec', '~>1.2.6'
5
+ require 'spec'
6
+ # gem 'dm-is-tree', '~>0.10.0'
7
+ # require 'dm-is-tree'
8
+
9
+ require Pathname(__FILE__).dirname.expand_path.parent + 'lib/dm-is-select'
10
+
11
+ def load_driver(name, default_uri)
12
+ return false if ENV['ADAPTER'] != name.to_s
13
+
14
+ begin
15
+ DataMapper.setup(name, ENV["#{name.to_s.upcase}_SPEC_URI"] || default_uri)
16
+ DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[name]
17
+ true
18
+ rescue LoadError => e
19
+ warn "Could not load do_#{name}: #{e}"
20
+ false
21
+ end
22
+ end
23
+
24
+ ENV['ADAPTER'] ||= 'sqlite3'
25
+
26
+ HAS_SQLITE3 = load_driver(:sqlite3, 'sqlite3::memory:')
27
+ HAS_MYSQL = load_driver(:mysql, 'mysql://localhost/dm_core_test')
28
+ HAS_POSTGRES = load_driver(:postgres, 'postgres://postgres@localhost/dm_core_test')
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dm-is-select
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ platform: ruby
6
+ authors:
7
+ - kematzy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-30 00:00:00 +08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: dm-core
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.10.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: dm-more
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.10.0
34
+ version:
35
+ description: A DataMapper plugin that makes getting the <tt>select</tt> options from a Model easier.
36
+ email: kematzy@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - History.rdoc
43
+ - LICENSE
44
+ - README.rdoc
45
+ - TODO
46
+ files:
47
+ - .gitignore
48
+ - History.rdoc
49
+ - LICENSE
50
+ - README.rdoc
51
+ - Rakefile
52
+ - TODO
53
+ - VERSION
54
+ - dm-is-select.gemspec
55
+ - lib/dm-is-select.rb
56
+ - lib/dm-is-select/is/select.rb
57
+ - lib/dm-is-select/is/version.rb
58
+ - spec/integration/select_spec.rb
59
+ - spec/spec.opts
60
+ - spec/spec_helper.rb
61
+ has_rdoc: true
62
+ homepage: http://github.com/kematzy/dm-is-select
63
+ licenses: []
64
+
65
+ post_install_message:
66
+ rdoc_options:
67
+ - --charset=UTF-8
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "0"
75
+ version:
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: "0"
81
+ version:
82
+ requirements: []
83
+
84
+ rubyforge_project:
85
+ rubygems_version: 1.3.5
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: A DataMapper plugin that makes getting the <tt>select</tt> options from a Model easier.
89
+ test_files:
90
+ - spec/integration/select_spec.rb
91
+ - spec/spec_helper.rb