porth 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +6 -0
- data/CHANGELOG.md +10 -0
- data/README.md +95 -3
- data/lib/porth.rb +0 -1
- data/lib/porth/format/xml.rb +16 -3
- data/lib/porth/version.rb +1 -1
- data/porth.gemspec +1 -2
- data/test/fixtures/array.rb +1 -0
- data/test/fixtures/block.rb +1 -1
- data/test/fixtures/hash.rb +1 -0
- data/test/porth/format/xml_test.rb +34 -0
- data/test/{port → porth}/handler_test.rb +0 -0
- data/test/porth/rendering/json_test.rb +19 -0
- data/test/porth/rendering/xml_test.rb +25 -0
- data/test/test_helper.rb +18 -0
- metadata +26 -29
- data/test/port/rendering_test.rb +0 -40
- data/test/port/xml_test.rb +0 -22
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
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
|
-
|
116
|
-
|
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
|
data/lib/porth.rb
CHANGED
data/lib/porth/format/xml.rb
CHANGED
@@ -2,14 +2,27 @@ module Porth
|
|
2
2
|
module Format
|
3
3
|
module XML
|
4
4
|
def self.call controller, object
|
5
|
-
object.
|
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
|
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
|
data/lib/porth/version.rb
CHANGED
data/porth.gemspec
CHANGED
@@ -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.
|
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'}]
|
data/test/fixtures/block.rb
CHANGED
@@ -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
|
data/test/test_helper.rb
CHANGED
@@ -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.
|
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:
|
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: &
|
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.
|
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: *
|
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: &
|
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: *
|
38
|
+
version_requirements: *70304282563600
|
50
39
|
- !ruby/object:Gem::Dependency
|
51
40
|
name: rake
|
52
|
-
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: *
|
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/
|
83
|
-
- test/
|
84
|
-
- test/
|
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: -
|
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: -
|
103
|
+
hash: -621584802889882658
|
110
104
|
requirements: []
|
111
105
|
rubyforge_project: porbt
|
112
|
-
rubygems_version: 1.8.
|
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/
|
120
|
-
- test/
|
121
|
-
- test/
|
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
|
data/test/port/rendering_test.rb
DELETED
@@ -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
|
data/test/port/xml_test.rb
DELETED
@@ -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
|