porth 0.0.1 → 0.0.2

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