carmen-rails 1.0.0.beta1

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.
@@ -0,0 +1,20 @@
1
+ Copyright 2012 Jim Benton and contributors
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,31 @@
1
+ # carmen-rails
2
+
3
+ carmen-rails is a Rails 3 plugin that supplies two new form helper methods:
4
+ `country_select` and `subregion_select`. It uses
5
+ [carmen](http://github.com/jim/carmen) as its source of geographic data.
6
+
7
+ ## Installation
8
+
9
+ Just add carmen-rails to your Gemfile:
10
+
11
+ ```ruby
12
+ gem 'carmen-rails', '1.0.0.pre'
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```erb
18
+ <%= form_for(@order) do |f| %>
19
+ <div class="field">
20
+ <%= f.label :country_code %><br />
21
+ <%= f.country_select :country_code, priority: %w(US CA), prompt: 'Please select a country' %>
22
+ </div>
23
+ <% end %>
24
+ ```
25
+
26
+ More docs coming soon.
27
+
28
+ ### Demo app
29
+
30
+ There is a [live demo app](http://carmen-rails-demo.herokuapp.com) that shows
31
+ carmen-rails in action.
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+
8
+ Bundler::GemHelper.install_tasks
9
+
10
+ require 'rake/testtask'
11
+
12
+ Rake::TestTask.new(:spec) do |t|
13
+ t.libs << 'lib'
14
+ t.libs << 'spec'
15
+ t.pattern = 'spec/**/*_spec.rb'
16
+ t.verbose = false
17
+ end
18
+
19
+ task :default => :spec
@@ -0,0 +1,18 @@
1
+ require 'carmen/rails/action_view/form_helper'
2
+ require 'carmen/rails/version'
3
+
4
+ module Carmen
5
+ module Rails
6
+ class Railtie < ::Rails::Railtie
7
+ # Add Carmen's locale paths to the Rails backend
8
+ paths = Carmen.i18n_backend.locale_paths.map { |path|
9
+ Dir[path + '**/*.yml']
10
+ }.flatten.compact
11
+ Carmen.i18n_backend = ::I18n
12
+ config.i18n.load_path += paths
13
+
14
+ # Enable fallbacks so that missing translations use the default locale
15
+ config.i18n.fallbacks = true
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,102 @@
1
+ module ActionView
2
+ module Helpers
3
+ module FormOptionsHelper
4
+
5
+ # Return select and subregion option tags for the given object and method.
6
+ #
7
+ # Uses region_options_or_select to generate the list of option tags.
8
+ def subregion_select(object, method, parent_region_or_code, options={}, html_options={})
9
+ parent_region = determine_parent(parent_region_or_code)
10
+ tag = InstanceTag.new(object, method, self, options.delete(:object))
11
+ tag.to_region_select_tag(parent_region, options, html_options)
12
+ end
13
+
14
+ # Return select and country option tags for the given object and method.
15
+ #
16
+ # Uses region_options_or_select to generate the list of option tags.
17
+ def country_select(object, method, options={}, html_options = {})
18
+ InstanceTag.new(object, method, self, options.delete(:object)).to_region_select_tag(Carmen::World.instance, options, html_options)
19
+ end
20
+
21
+ def region_options_for_select(parent_region, selected = nil, priority_region_codes)
22
+ region_options = ""
23
+
24
+ unless priority_region_codes.empty?
25
+ priority_regions = priority_region_codes.map do |code|
26
+ region = parent_region.subregions.coded(code)
27
+ [region.name, region.code] if region
28
+ end.compact
29
+ unless priority_regions.empty?
30
+ region_options += options_for_select(priority_regions, selected)
31
+ region_options += "<option disabled>-------------</option>"
32
+ end
33
+ end
34
+
35
+ main_options = parent_region.subregions.map { |r| [r.name, r.code] }
36
+ region_options += options_for_select(main_options, selected)
37
+ region_options.html_safe
38
+ end
39
+
40
+ # Return select tag with the name provided containing country option
41
+ # tags.
42
+ #
43
+ # Uses region_options_or_select to generate the list of option tags.
44
+ def country_select_tag(name, value, options={})
45
+ subregion_select_tag(name, value, Carmen::World.instance, options)
46
+ end
47
+ #
48
+ # Return select tag with the name provided containing subregion option
49
+ # tags.
50
+ #
51
+ # Uses region_options_or_select to generate the list of option tags.
52
+ def subregion_select_tag(name, value, parent_region_or_code, options = {})
53
+ options.stringify_keys!
54
+ parent_region = determine_parent(parent_region_or_code)
55
+ priority_regions = options.delete(:priority) || []
56
+ opts = region_options_for_select(parent_region, value, priority_regions)
57
+ html_options = {"name" => name,
58
+ "id" => sanitize_to_id(name)}.update(options.stringify_keys)
59
+ content_tag(:select, opts, html_options)
60
+ end
61
+
62
+ private
63
+
64
+ def determine_parent(parent_region_or_code)
65
+ case parent_region_or_code
66
+ when String
67
+ Carmen::Country.coded(parent_region_or_code)
68
+ when Array
69
+ parent_region_or_code.inject(Carmen::World.instance) { |parent, next_code|
70
+ parent.subregions.coded(next_code)
71
+ }
72
+ else
73
+ parent_region_or_code
74
+ end
75
+ end
76
+ end
77
+
78
+ class InstanceTag
79
+ def to_region_select_tag(parent_region, options, html_options)
80
+ html_options = html_options.stringify_keys
81
+ add_default_name_and_id(html_options)
82
+ priority_regions = options[:priority] || []
83
+ value = value(object)
84
+ opts = add_options(region_options_for_select(parent_region, value, priority_regions), options, value)
85
+ content_tag("select", opts, html_options)
86
+ end
87
+ end
88
+
89
+ class FormBuilder
90
+ def country_select(method, options = {}, html_options = {})
91
+ @template.country_select(@object_name, method,
92
+ options.merge(:object => @object), html_options)
93
+ end
94
+
95
+ def subregion_select(method, parent_region_or_code, options={}, html_options={})
96
+ @template.subregion_select(@object_name, method, parent_region_or_code,
97
+ options.merge(:object => @object), html_options)
98
+ end
99
+ end
100
+
101
+ end
102
+ end
@@ -0,0 +1,5 @@
1
+ module Carmen
2
+ module Rails
3
+ VERSION = "1.0.0.beta1"
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :carmen-rails do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,123 @@
1
+ require 'spec_helper'
2
+
3
+ class CarmenViewHelperTest < MiniTest::Unit::TestCase
4
+ include ActionView::Helpers::FormOptionsHelper
5
+ include ActionView::Helpers::FormTagHelper
6
+ include ActionDispatch::Assertions::SelectorAssertions
7
+
8
+ def setup
9
+ @object = OpenStruct.new
10
+ def @object.to_s; 'object'; end
11
+ end
12
+
13
+ def response_from_page
14
+ HTML::Document.new(@html).root
15
+ end
16
+
17
+ def test_basic_country_select
18
+ html = country_select(@object, :country_code)
19
+ expected = <<-HTML
20
+ <select id="object_country_code" name="object[country_code]">
21
+ <option value="OC">Oceania</option>
22
+ <option value="EU">Eurasia</option>
23
+ <option value="ES">Eastasia</option>
24
+ </select>
25
+ HTML
26
+
27
+ assert_equal_markup(expected, html)
28
+ end
29
+
30
+ def test_country_selected_value
31
+ @object.country_code = 'OC'
32
+ @html = country_select(@object, :country_code)
33
+ assert_select('option[selected="selected"][value="OC"]')
34
+ end
35
+
36
+ def test_basic_country_select_tag
37
+ html = country_select_tag('attribute_name', nil)
38
+ expected = <<-HTML
39
+ <select id="attribute_name" name="attribute_name">
40
+ <option value="OC">Oceania</option>
41
+ <option value="EU">Eurasia</option>
42
+ <option value="ES">Eastasia</option>
43
+ </select>
44
+ HTML
45
+
46
+ assert_equal_markup(expected, html)
47
+ end
48
+
49
+ def test_country_tag_selected_value
50
+ @html = country_select_tag(:country_code, 'OC')
51
+ assert_select('option[selected="selected"][value="OC"]')
52
+ end
53
+
54
+ def test_priority_country_select
55
+ html = country_select(@object, :country_code, {priority: ['ES']})
56
+ expected = <<-HTML
57
+ <select id="object_country_code" name="object[country_code]">
58
+ <option value="ES">Eastasia</option>
59
+ <option disabled>-------------</option>
60
+ <option value="OC">Oceania</option>
61
+ <option value="EU">Eurasia</option>
62
+ <option value="ES">Eastasia</option>
63
+ </select>
64
+ HTML
65
+
66
+ assert_equal_markup(expected, html)
67
+ end
68
+
69
+ def test_basic_subregion_select
70
+ oceania = Carmen::Country.coded('OC')
71
+ expected = <<-HTML
72
+ <select id="object_subregion_code" name="object[subregion_code]"><option value="AO">Airstrip One</option></select>
73
+ HTML
74
+
75
+ html = subregion_select(@object, :subregion_code, oceania)
76
+
77
+ assert_equal_markup(expected, html)
78
+ end
79
+
80
+ def test_subregion_select_using_parent_code
81
+ expected = <<-HTML
82
+ <select id="object_subregion_code" name="object[subregion_code]"><option value="AO">Airstrip One</option></select>
83
+ HTML
84
+
85
+ html = subregion_select(@object, :subregion_code, 'OC')
86
+
87
+ assert_equal_markup(expected, html)
88
+ end
89
+
90
+ def test_subregion_select_using_parent_code_array
91
+ expected = <<-HTML
92
+ <select id="object_subregion_code" name="object[subregion_code]"><option value="LO">London</option></select>
93
+ HTML
94
+
95
+ html = subregion_select(@object, :subregion_code, ['OC', 'AO'])
96
+
97
+ assert_equal_markup(expected, html)
98
+ end
99
+
100
+ def test_subregion_selected_value
101
+ @object.subregion_code = 'AO'
102
+ oceania = Carmen::Country.coded('OC')
103
+
104
+ @html = subregion_select(@object, :subregion_code, oceania)
105
+
106
+ assert_select('option[selected="selected"][value="AO"]')
107
+ end
108
+
109
+ def test_basic_subregion_select
110
+ oceania = Carmen::Country.coded('OC')
111
+ expected = <<-HTML
112
+ <select id="subregion_code" name="subregion_code"><option value="AO">Airstrip One</option></select>
113
+ HTML
114
+
115
+ html = subregion_select_tag(:subregion_code, nil, oceania)
116
+
117
+ assert_equal_markup(expected, html)
118
+ end
119
+
120
+ def method_missing(method, *args)
121
+ fail "method_missing #{method}"
122
+ end
123
+ end
@@ -0,0 +1,40 @@
1
+ lib_path = File.expand_path('../../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib_path)
3
+
4
+ require 'minitest/spec'
5
+ require 'minitest/autorun'
6
+
7
+ require 'action_view/test_case'
8
+
9
+ require 'rails'
10
+ require 'carmen'
11
+ require 'carmen-rails'
12
+ require 'ostruct'
13
+
14
+ require 'yaml'
15
+ YAML::ENGINE.yamler = 'syck'
16
+
17
+ MiniTest::Spec.register_spec_type(/.*/, ActionView::TestCase)
18
+
19
+ Carmen.clear_data_paths
20
+ Carmen.append_data_path(Carmen.root_path + 'spec_data/data')
21
+
22
+ locale_path = Carmen.root_path + 'spec_data/locale'
23
+ Carmen.i18n_backend = Carmen::I18n::Simple.new(locale_path)
24
+
25
+ class MiniTest::Unit::TestCase
26
+ def assert_equal_markup(expected, actual, message=nil)
27
+ assert_equal(clean_markup(expected), clean_markup(actual), message)
28
+ end
29
+
30
+ private
31
+
32
+ def clean_markup(markup)
33
+ markup.
34
+ gsub(/\s+/, ' '). # cleanup whitespace
35
+ gsub(/>\s/, '>'). # kill space after tags
36
+ gsub(/\s</, '<'). # space before tags
37
+ gsub(/\s\/>/, '/>'). # space inside self-closing tags
38
+ strip
39
+ end
40
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: carmen-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0.beta1
5
+ prerelease: 6
6
+ platform: ruby
7
+ authors:
8
+ - Jim Benton
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-09 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: &70334482920600 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70334482920600
25
+ - !ruby/object:Gem::Dependency
26
+ name: carmen
27
+ requirement: &70334482920100 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.0.0.beta2
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70334482920100
36
+ - !ruby/object:Gem::Dependency
37
+ name: minitest
38
+ requirement: &70334482919680 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70334482919680
47
+ description: Provides country_select and subregion_select form helpers.
48
+ email:
49
+ - jim@autonomousmachine.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - lib/carmen/rails/action_view/form_helper.rb
55
+ - lib/carmen/rails/version.rb
56
+ - lib/carmen-rails.rb
57
+ - lib/tasks/carmen-rails_tasks.rake
58
+ - MIT-LICENSE
59
+ - Rakefile
60
+ - README.md
61
+ - spec/carmen/action_view/helpers/form_helper_spec.rb
62
+ - spec/spec_helper.rb
63
+ homepage: http://github.com/jim/carmen-rails
64
+ licenses: []
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>'
79
+ - !ruby/object:Gem::Version
80
+ version: 1.3.1
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 1.8.10
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: Rails adapter for Carmen
87
+ test_files:
88
+ - spec/carmen/action_view/helpers/form_helper_spec.rb
89
+ - spec/spec_helper.rb