porth 0.0.1 → 0.0.2

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,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - jruby
@@ -0,0 +1,10 @@
1
+ # CHANGELOG
2
+
3
+ # 0.0.2 / 2012-01-21
4
+
5
+ * XML singularizes resource name when view returns a single object
6
+ * Relaxed dependancy versions. Works with Rails 3.0.0+ and any version of JSON
7
+
8
+ # 0.0.1 / 2011-10-23
9
+
10
+ * Initial release
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Porth (Plain Old Ruby Template Handler)
2
2
 
3
+ [![Build Status](https://secure.travis-ci.org/tatey/porth.png)](http://travis-ci.org/tatey/porth)
4
+
3
5
  Write your views using plain old Ruby. Views are for representation, not defining
4
6
  `#as_json` in a model. There's no need to learn a DSL for building arrays and hashes.
5
7
  Just use Ruby. Views are written once and rendered in JSON(P) or XML based on
@@ -109,18 +111,108 @@ class TransmittersController < ApplicationController
109
111
  end
110
112
  ```
111
113
 
114
+ Resource names are pluralized or singularized by introspecting the return type from
115
+ the view. Following convention, collection actions (index) should return
116
+ an array of objects and member actions (new, create, edit, update, delete) should
117
+ return an object. Override `#xml_pluralized_root` to explicitly set the collection
118
+ resource name and override `#xml_singularize_root` to explicitly set the member
119
+ resource name.
120
+
121
+ ``` ruby
122
+ class SeaFoodsController < ApplicationController
123
+ # ...
124
+
125
+ protected
126
+
127
+ def xml_pluralized_root
128
+ 'fish'
129
+ end
130
+
131
+ def xml_singularized_root
132
+ 'fish'
133
+ end
134
+ end
135
+ ```
136
+
137
+ ## Examples
138
+
139
+ Remember, anything you can do in Ruby you can do in Porth. Here are a few ideas
140
+ for writing and testing your views.
141
+
142
+ ### Subset
143
+
144
+ Conveniently select a subset of attributes.
145
+
146
+ ``` ruby
147
+ # app/views/users/show.rb
148
+ @author.attributes.slice 'id', 'first_name', 'last_name', 'email'
149
+ ```
150
+
151
+ ### Variable and Condition
152
+
153
+ Hashes may get dirty if you attempt to build them all in one go. Consider storing
154
+ the hash in a variable and adding to it based on a condition. Like a method you
155
+ need to return the hash on the last line.
156
+
157
+ ``` ruby
158
+ # app/views/users/show.rb
159
+ attributes = @author.attributes.slice 'id', 'first_name', 'last_name', 'email'
160
+ if current_user.admin?
161
+ attributes['ip_address'] = @author.ip_address
162
+ attributes['likability'] = @author.determine_likability_as_of Time.current
163
+ end
164
+ attributes
165
+ ```
166
+
167
+ ### Functional Test
168
+
169
+ Use functional tests to verify the response's body is correct.
170
+
171
+ ``` ruby
172
+ # app/views/posts/show.rb
173
+ @author.attributes.slice 'id', 'title', 'body'
174
+ ```
175
+
176
+ JSON maps well to Ruby's hashes. Set the response to JSON, parse the body into
177
+ a hash and verify the key-value pairs.
178
+
179
+ ``` ruby
180
+ # test/functional/posts_controller_test.rb
181
+ require 'test_helper'
182
+
183
+ class PostsControllerTest < ActionController::TestCase
184
+ # ...
185
+
186
+ test "GET show" do
187
+ get :show, id: posts(:hello_word).id, format: 'json'
188
+ post = JSON.parse response.body
189
+ assert_equal 123040040, post['id']
190
+ assert_equal 'Hello, World!', post['title']
191
+ assert_equal 'Lorem ipsum dolar sit amet...', post['body']
192
+ end
193
+ end
194
+ ```
195
+
112
196
  ## Compatibility
113
197
 
198
+ * MRI 1.8.7
199
+ * MRI 1.9.2+
200
+ * JRuby 1.6.4+
201
+
202
+ ## Dependancies
203
+
114
204
  * ActionPack 3.1.0
115
- * JRuby 1.6.4
116
- * Ruby 1.9.2
205
+
206
+ ## Extensions
207
+
208
+ * [porth-plist](https://github.com/soundevolution/porth-plist) - Adds Property list (.plist) support
117
209
 
118
210
  ## Contributing
119
211
 
120
212
  1. Fork
121
213
  2. Install dependancies by running `$ bundle install`
122
214
  3. Write tests and code
123
- 4. Make sure the tests pass by running `$ rake`
215
+ 4. Make sure the tests pass by running `$ bundle exec rake`
124
216
  5. Push and send a pull request on GitHub
125
217
 
126
218
  ## Credits
@@ -1,5 +1,4 @@
1
1
  require 'action_controller'
2
- require 'json'
3
2
 
4
3
  require 'porth/format/json'
5
4
  require 'porth/format/xml'
@@ -2,14 +2,27 @@ module Porth
2
2
  module Format
3
3
  module XML
4
4
  def self.call controller, object
5
- object.to_xml :root => controller.send(:xml_root)
5
+ method = if object.respond_to?(:count) && !object.respond_to?(:keys)
6
+ :xml_pluralized_root
7
+ else
8
+ :xml_singularized_root
9
+ end
10
+ object.to_xml :root => controller.send(method)
6
11
  end
7
12
 
8
13
  module ControllerExtensions
9
14
  protected
10
-
15
+
11
16
  def xml_root
12
- self.class.name.sub('Controller', '').underscore.split('/').last.pluralize
17
+ self.class.name.sub('Controller', '').underscore.split('/').last
18
+ end
19
+
20
+ def xml_pluralized_root
21
+ xml_root.pluralize
22
+ end
23
+
24
+ def xml_singularized_root
25
+ xml_root.singularize
13
26
  end
14
27
  end
15
28
  end
@@ -1,3 +1,3 @@
1
1
  module Porth
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
@@ -20,8 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
21
  s.require_paths = ["lib"]
22
22
 
23
- s.add_runtime_dependency 'actionpack', '>= 3.1.0', '< 4.0.0'
24
- s.add_runtime_dependency 'json', '~> 1.6.1'
23
+ s.add_runtime_dependency 'actionpack', '>= 3.0.0', '< 4.0.0'
25
24
 
26
25
  s.add_development_dependency 'minitest', '~> 2.6.2'
27
26
  s.add_development_dependency 'rake', '~> 0.9.2'
@@ -0,0 +1 @@
1
+ [{:foo => 'bar'}]
@@ -1,3 +1,3 @@
1
1
  (1..2).map do |n|
2
- {n => n * 2}
2
+ {:value => n}
3
3
  end
@@ -0,0 +1 @@
1
+ {:foo => 'bar'}
@@ -0,0 +1,34 @@
1
+ require 'test_helper'
2
+
3
+ class Format::XMLTest < MiniTest::Unit::TestCase
4
+ def mock_controller name
5
+ instance_eval <<-RUBY_STRING
6
+ Class.new do
7
+ include Format::XML::ControllerExtensions
8
+
9
+ public :xml_root, :xml_pluralized_root, :xml_singularized_root
10
+
11
+ def self.name
12
+ '#{name}'
13
+ end
14
+ end
15
+ RUBY_STRING
16
+ end
17
+
18
+ def test_xml_root
19
+ assert_equal 'foo', mock_controller('Foo').new.xml_root
20
+ assert_equal 'foo', mock_controller('FooController').new.xml_root
21
+ assert_equal 'foos', mock_controller('FoosController').new.xml_root
22
+ assert_equal 'bar', mock_controller('Foo::BarController').new.xml_root
23
+ end
24
+
25
+ def test_xml_pluralized_root
26
+ assert_equal 'foos', mock_controller('Foo').new.xml_pluralized_root
27
+ assert_equal 'foos', mock_controller('Foos').new.xml_pluralized_root
28
+ end
29
+
30
+ def test_xml_singularized_root
31
+ assert_equal 'foo', mock_controller('Foo').new.xml_singularized_root
32
+ assert_equal 'foo', mock_controller('Foos').new.xml_singularized_root
33
+ end
34
+ end
File without changes
@@ -0,0 +1,19 @@
1
+ require 'test_helper'
2
+
3
+ class Rendering::JSONTest < MiniTest::Unit::TestCase
4
+ include Rendering
5
+
6
+ def test_render_json
7
+ assert_equal '[{"value":1},{"value":2}]', render('block', :json, MockController.new)
8
+ end
9
+
10
+ def test_render_json_with_callback
11
+ controller = MockController.new
12
+ controller.params[:callback] = 'myFunction'
13
+ assert_equal 'myFunction([{"value":1},{"value":2}])', render('block', :json, controller)
14
+ end
15
+
16
+ def test_render_json_with_instance_variable
17
+ assert_equal '["bar"]', render('instance_variable', :json, MockController.new, {'foo' => 'bar'})
18
+ end
19
+ end
@@ -0,0 +1,25 @@
1
+ require 'active_support/core_ext/hash'
2
+ require 'rexml/document'
3
+ require 'test_helper'
4
+
5
+ class Rendering::XMLTest < MiniTest::Unit::TestCase
6
+ include Rendering
7
+
8
+ def test_render_xml
9
+ assert_equal "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<mocks type=\"array\">\n <mock>\n <value type=\"integer\">1</value>\n </mock>\n <mock>\n <value type=\"integer\">2</value>\n </mock>\n</mocks>\n", render(:block, :xml, MockController.new)
10
+ end
11
+
12
+ def test_render_xml_with_array_of_objects
13
+ xml = REXML::Document.new render('array', :xml, MockController.new)
14
+ assert_equal 'mocks', xml.root.name
15
+ end
16
+
17
+ def test_render_xml_with_object
18
+ xml = REXML::Document.new render('hash', :xml, MockController.new)
19
+ assert_equal 'mock', xml.root.name
20
+ end
21
+
22
+ def test_render_xml_with_instance_variable
23
+ assert_equal "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<mocks type=\"array\">\n <mock>bar</mock>\n</mocks>\n", render('instance_variable', :xml, MockController.new, {'foo' => 'bar'})
24
+ end
25
+ end
@@ -1,4 +1,22 @@
1
1
  require 'minitest/autorun'
2
2
  require 'porth'
3
3
 
4
+ module Rendering
5
+ class MockController < ActionController::Base
6
+ def params
7
+ @params ||= {}
8
+ end
9
+ end
10
+
11
+ def render file, format, controller, assigns = {}
12
+ ActionView::Base.new(template_dir, assigns, controller).tap do |view|
13
+ view.lookup_context.freeze_formats [format]
14
+ end.render :file => file
15
+ end
16
+
17
+ def template_dir
18
+ File.expand_path File.dirname(__FILE__) + '/fixtures'
19
+ end
20
+ end
21
+
4
22
  include Porth
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: porth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,36 +9,25 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-23 00:00:00.000000000Z
12
+ date: 2012-01-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
16
- requirement: &70355213483100 !ruby/object:Gem::Requirement
16
+ requirement: &70304282535720 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 3.1.0
21
+ version: 3.0.0
22
22
  - - <
23
23
  - !ruby/object:Gem::Version
24
24
  version: 4.0.0
25
25
  type: :runtime
26
26
  prerelease: false
27
- version_requirements: *70355213483100
28
- - !ruby/object:Gem::Dependency
29
- name: json
30
- requirement: &70355213481080 !ruby/object:Gem::Requirement
31
- none: false
32
- requirements:
33
- - - ~>
34
- - !ruby/object:Gem::Version
35
- version: 1.6.1
36
- type: :runtime
37
- prerelease: false
38
- version_requirements: *70355213481080
27
+ version_requirements: *70304282535720
39
28
  - !ruby/object:Gem::Dependency
40
29
  name: minitest
41
- requirement: &70355213479740 !ruby/object:Gem::Requirement
30
+ requirement: &70304282563600 !ruby/object:Gem::Requirement
42
31
  none: false
43
32
  requirements:
44
33
  - - ~>
@@ -46,10 +35,10 @@ dependencies:
46
35
  version: 2.6.2
47
36
  type: :development
48
37
  prerelease: false
49
- version_requirements: *70355213479740
38
+ version_requirements: *70304282563600
50
39
  - !ruby/object:Gem::Dependency
51
40
  name: rake
52
- requirement: &70355213477700 !ruby/object:Gem::Requirement
41
+ requirement: &70304282560040 !ruby/object:Gem::Requirement
53
42
  none: false
54
43
  requirements:
55
44
  - - ~>
@@ -57,7 +46,7 @@ dependencies:
57
46
  version: 0.9.2
58
47
  type: :development
59
48
  prerelease: false
60
- version_requirements: *70355213477700
49
+ version_requirements: *70304282560040
61
50
  description: Write your views using plain old Ruby
62
51
  email:
63
52
  - tate@tatey.com
@@ -66,6 +55,8 @@ extensions: []
66
55
  extra_rdoc_files: []
67
56
  files:
68
57
  - .gitignore
58
+ - .travis.yml
59
+ - CHANGELOG.md
69
60
  - Gemfile
70
61
  - LICENSE
71
62
  - README.md
@@ -77,11 +68,14 @@ files:
77
68
  - lib/porth/unknown_format_error.rb
78
69
  - lib/porth/version.rb
79
70
  - porth.gemspec
71
+ - test/fixtures/array.rb
80
72
  - test/fixtures/block.rb
73
+ - test/fixtures/hash.rb
81
74
  - test/fixtures/instance_variable.rb
82
- - test/port/handler_test.rb
83
- - test/port/rendering_test.rb
84
- - test/port/xml_test.rb
75
+ - test/porth/format/xml_test.rb
76
+ - test/porth/handler_test.rb
77
+ - test/porth/rendering/json_test.rb
78
+ - test/porth/rendering/xml_test.rb
85
79
  - test/test_helper.rb
86
80
  homepage: https://github.com/tatey/porth
87
81
  licenses: []
@@ -97,7 +91,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
97
91
  version: '0'
98
92
  segments:
99
93
  - 0
100
- hash: -1831659487050102680
94
+ hash: -621584802889882658
101
95
  required_rubygems_version: !ruby/object:Gem::Requirement
102
96
  none: false
103
97
  requirements:
@@ -106,17 +100,20 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
100
  version: '0'
107
101
  segments:
108
102
  - 0
109
- hash: -1831659487050102680
103
+ hash: -621584802889882658
110
104
  requirements: []
111
105
  rubyforge_project: porbt
112
- rubygems_version: 1.8.10
106
+ rubygems_version: 1.8.11
113
107
  signing_key:
114
108
  specification_version: 3
115
109
  summary: Plain Old Ruby Template Handler
116
110
  test_files:
111
+ - test/fixtures/array.rb
117
112
  - test/fixtures/block.rb
113
+ - test/fixtures/hash.rb
118
114
  - test/fixtures/instance_variable.rb
119
- - test/port/handler_test.rb
120
- - test/port/rendering_test.rb
121
- - test/port/xml_test.rb
115
+ - test/porth/format/xml_test.rb
116
+ - test/porth/handler_test.rb
117
+ - test/porth/rendering/json_test.rb
118
+ - test/porth/rendering/xml_test.rb
122
119
  - test/test_helper.rb
@@ -1,40 +0,0 @@
1
- require 'test_helper'
2
-
3
- class RenderingTest < MiniTest::Unit::TestCase
4
- class TestsController < ActionController::Base
5
- def params
6
- @params ||= {}
7
- end
8
- end
9
-
10
- def render file, format, assigns = {}
11
- ActionView::Base.new(template_dir, assigns, @controller).tap do |view|
12
- view.lookup_context.freeze_formats [format]
13
- end.render :file => file
14
- end
15
-
16
- def template_dir
17
- File.expand_path File.dirname(__FILE__) + '/../fixtures'
18
- end
19
-
20
- def setup
21
- @controller = TestsController.new
22
- end
23
-
24
- def test_json
25
- assert_equal '[{"1":2},{"2":4}]', render('block', :json)
26
- end
27
-
28
- def test_json_callback
29
- @controller.params[:callback] = 'myFunction'
30
- assert_equal 'myFunction([{"1":2},{"2":4}])', render('block', :json)
31
- end
32
-
33
- def test_xml
34
- assert_equal %{<?xml version="1.0" encoding="UTF-8"?>\n<tests type="array">\n <test 1="2" type="hash"/>\n <test 2="4" type="hash"/>\n</tests>\n}, render('block', :xml)
35
- end
36
-
37
- def test_instance_variable
38
- assert_equal '["bar"]', render('instance_variable', :json, 'foo' => 'bar')
39
- end
40
- end
@@ -1,22 +0,0 @@
1
- require 'test_helper'
2
-
3
- class XMLTest < MiniTest::Unit::TestCase
4
- def klass name
5
- instance_eval <<-RUBY_STRING
6
- Class.new do
7
- include Format::XML::ControllerExtensions
8
-
9
- def self.name
10
- '#{name}'
11
- end
12
- end
13
- RUBY_STRING
14
- end
15
-
16
- def test_send_xml_root
17
- assert_equal 'foos', klass('Foo').new.send(:xml_root)
18
- assert_equal 'foos', klass('FooController').new.send(:xml_root)
19
- assert_equal 'foos', klass('FoosController').new.send(:xml_root)
20
- assert_equal 'bars', klass('Foo::BarController').new.send(:xml_root)
21
- end
22
- end