lipa-web 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -25,14 +25,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
25
 
26
26
  module Lipa
27
27
  module Web
28
- module HtmlHelper
29
- # Make link for node
30
- #
31
- # @param node [Lipa::Node] linking node
32
- # @return [String] html <a href='path/to/node'>name_of_node</a>
33
- def link_to(node)
34
- %(<a href="#{node.full_name}">#{node.name}</a>)
28
+ module Helpers
29
+ module Response
30
+ def read_template(path)
31
+ File.open(path).read
32
+ end
35
33
  end
36
34
  end
37
35
  end
38
36
  end
37
+
@@ -0,0 +1,49 @@
1
+ =begin
2
+ Web access to Lipa
3
+
4
+ Copyright (c) 2011 Aleksey Timin
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ 'Software'), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ =end
25
+
26
+ require "lipa/web/response/html"
27
+ require "lipa/web/response/json"
28
+ require "lipa/web/response/xml"
29
+
30
+ module Lipa
31
+ module Web
32
+ module Response
33
+ # Rendering node data in format
34
+ #
35
+ # @param node [Lipa::Node] node for rendering
36
+ # @param format of rendering
37
+ def respond(node, format)
38
+ case format.to_s
39
+ when "json"
40
+ JSON::response(node)
41
+ when "xml"
42
+ XML::response(node)
43
+ else
44
+ HTML::response(node)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,90 @@
1
+ =begin
2
+ Web access to Lipa
3
+
4
+ Copyright (c) 2011 Aleksey Timin
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ 'Software'), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ =end
25
+
26
+ module Lipa
27
+ module Web
28
+ module Response
29
+ module HTML
30
+ extend Helpers::Response
31
+
32
+ def self.response(node)
33
+ header = {}
34
+
35
+ html = node.html
36
+ if html
37
+ if html[:block]
38
+ body = html[:block].call
39
+ else
40
+ case html[:render]
41
+ when :erb
42
+ body = render_erb(node)
43
+ header["Content-Type"] = "text/html"
44
+ when :text
45
+ body = html[:msg]
46
+ header["Content-Type"] = "text/plain"
47
+ end
48
+ end
49
+ else
50
+ body = render_default_template(node)
51
+ end
52
+ [ 200, header, [body]]
53
+ end
54
+
55
+ private
56
+ def self.context(node)
57
+ node.instance_eval("def binding_for(#{node.attrs.keys.join(",")}) binding; end")
58
+ node.extend(Helpers::HTML)
59
+ block = block_given? ? Proc.new : nil
60
+ node.binding_for(*node.eval_attrs.values, &block)
61
+ end
62
+
63
+ def self.render_default_template(node)
64
+ path = File.join(File.dirname(__FILE__), '..', 'views', 'node.html.erb') # default path
65
+ default_template = read_template(path)
66
+
67
+ path = File.join(File.dirname(__FILE__), '..', 'views', 'layout.html.erb') # default path
68
+ default_layout = read_template(path)
69
+
70
+ ERB.new(default_layout).result(
71
+ context(node) do
72
+ ERB.new(default_template).result(context(node))
73
+ end
74
+ )
75
+ end
76
+
77
+ def self.render_erb(node)
78
+ template = read_template(node.html[:template])
79
+ root = node.root
80
+ if root.layout
81
+ layout = read_template(File.join(root.views, root.layout))
82
+ ERB.new(layout).result(context(node) { ERB.new(template).result(context(node)) })
83
+ else
84
+ ERB.new(template).result(context(node))
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -23,58 +23,40 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
23
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
24
  =end
25
25
 
26
+ require "json"
26
27
  module Lipa
27
28
  module Web
28
- module NodeHelper
29
+ module Response
30
+ module JSON
31
+ def self.response(node)
32
+ body = if node.json
33
+ j = {}
34
+ node.json[:block].call(j)
35
+ j.to_json
36
+ else
37
+ render_default_json(node)
38
+ end
29
39
 
30
- # Assignment erb template fot html response
31
- #
32
- # @param path [String] path about views directory
33
- #
34
- # @examnple
35
- # node :page_1 do
36
- # html erb("page.html.erb")
37
- # end
38
- def erb(path)
39
- { :render => :erb, :template => File.join(root.attrs[:views], path) }
40
- end
40
+ [ 200, { "Content-Type" => "application/json" }, [body]]
41
+ end
41
42
 
42
- # Assignment text for html response
43
- #
44
- # @param msg [String] text message
45
- #
46
- # @examnple
47
- # node :page_1 do
48
- # html text("Hello World!")
49
- # end
50
- def text(msg)
51
- { :render => :text, :msg => msg }
52
- end
43
+ private
44
+ def self.render_default_json(node)
45
+ j = {}
46
+ j[:name] = node.name
47
+ j[:full_name] = node.full_name
48
+ j[:parent] = json_link_to(node.parent)
49
+ j[:children] = node.children.values.each.map {|ch| json_link_to(ch) }
53
50
 
54
- # Definition html response
55
- #
56
- # @see NodeHelpers#erb
57
- # @see NodeHelpers#text
58
- def html(opts=nil)
59
- if opts.nil?
60
- @html
61
- else
62
- @html = opts
51
+ node.eval_attrs.each_pair do |k,v|
52
+ j[k] = v.kind_of?(Lipa::Node) ? json_link_to(v) : v
53
+ end
54
+
55
+ j.to_json
63
56
  end
64
- end
65
57
 
66
- # Definition json response
67
- #
68
- # @example
69
- # node :josn_1 do
70
- # json { |j| j[:name] = name }
71
- # end
72
- # # => { "name":"json_1" }
73
- def json(&block)
74
- if block_given?
75
- @json = {:block => block}
76
- else
77
- @json
58
+ def self.json_link_to(node)
59
+ { :name => node.name, :full_name => node.full_name }
78
60
  end
79
61
  end
80
62
  end
@@ -0,0 +1,68 @@
1
+ =begin
2
+ Web access to Lipa
3
+
4
+ Copyright (c) 2011 Aleksey Timin
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ 'Software'), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ =end
25
+
26
+ require "builder"
27
+
28
+ module Lipa
29
+ module Web
30
+ module Response
31
+ module XML
32
+ extend Helpers::Response
33
+
34
+ def self.response(node)
35
+ xml = Builder::XmlMarkup.new
36
+ if node.xml
37
+ if node.xml[:block]
38
+ node.xml[:block].call(xml)
39
+ else
40
+ case node.xml[:render]
41
+ when :builder
42
+ template = read_template(node.xml[:template])
43
+ end
44
+ eval(template, context(node,xml))
45
+ end
46
+ else
47
+ eval(default_template, context(node,xml))
48
+ end
49
+
50
+ [200, {"Content-Type" => "application/xml"}, [ xml.target!]]
51
+ end
52
+
53
+ private
54
+ def self.context(node,xml)
55
+ node.instance_eval("def binding_for(#{(node.attrs.keys << "xml").join(",")}) binding; end")
56
+ block = block_given? ? Proc.new : nil
57
+ node.binding_for(*(node.eval_attrs.values << xml), &block)
58
+ end
59
+
60
+ def self.default_template
61
+ path = File.join(File.dirname(__FILE__), '..', 'views', 'node.builder') # default path
62
+ template = read_template(path)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+
@@ -25,6 +25,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
25
 
26
26
  module Lipa
27
27
  module Web
28
- VERSION = "0.1.1"
28
+ VERSION = "0.2.0"
29
29
  end
30
30
  end
@@ -1,36 +1,17 @@
1
- require "lipa/web"
2
- require "rack/test"
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
3
2
 
4
3
  describe Lipa::Web::Application do
5
4
  include Rack::Test::Methods
6
5
 
7
6
  before :each do
8
7
  @srv = root :srv do
9
- views File.join(File.dirname(__FILE__), "views")
10
- layout "layout.html.erb"
8
+ static_folder File.join(File.dirname(__FILE__), "public")
11
9
 
12
10
  node :group do
13
11
  node :test_node do
14
- param_int 20
15
- param_bool false
16
- param_float 32.2
17
- param_string "Hello"
18
- param_time Time.new(2000,"jan",1,20,15,1,0)
19
- param_proc run{5+3}
20
- param_ref ref("../node_with_template")
21
-
22
12
  node :child_1
23
13
  node :child_2
24
14
  end
25
-
26
- node :node_with_template do
27
- html erb("./my_template.html.erb")
28
- json { |j| j[:name] = name }
29
- end
30
-
31
- node :node_greater do
32
- html text("Hello world!")
33
- end
34
15
  end
35
16
  end
36
17
  end
@@ -56,44 +37,10 @@ describe Lipa::Web::Application do
56
37
  last_response.body.should eql("Node is not existence")
57
38
  end
58
39
 
59
- it 'should render default html template' do
60
- get "/group/test_node"
61
-
62
- last_response.header['Content-Type'].should eql( "text/html")
63
- last_response.body.gsub(/^\s*\n/, '').should == fixture("node.html")
64
- end
65
-
66
- it 'should render user html template' do
67
- get "/group/node_with_template"
68
-
69
- last_response.header['Content-Type'].should eql("text/html")
70
- last_response.body.gsub(/^\s*\n/, '').should == fixture("node_with_template.html")
71
- end
72
-
73
- it 'should render text' do
74
- get "/group/node_greater"
75
-
76
- last_response.header['Content-Type'].should eql("text/plain")
77
- last_response.body.should == "Hello world!"
78
- end
79
-
80
- it 'should response in default json format' do
81
- get "group/test_node.json"
82
-
83
- last_response.header['Content-Type'].should eql("application/json")
84
- last_response.body.gsub(/\s*/,'').should == fixture("node.json").gsub(/\s*/,'')
85
- end
86
-
87
- it 'should response in default json format' do
88
- get "group/node_with_template.json"
89
-
90
- last_response.header['Content-Type'].should eql("application/json")
91
- last_response.body.should == '{"name":"node_with_template"}'
92
- end
93
-
94
- def fixture(name)
95
- path = File.join(File.dirname(__FILE__), "fixtures", name)
96
- File.open(path).read.gsub(/^\s*\n/,'')
40
+ it 'should serve statics files in public folder' do
41
+ get "/css/style.css"
42
+ last_response.header["Content-Type"].should eql("text/css")
43
+ last_response.body.should eql(".h1 { color: #fff; }\n")
97
44
  end
98
45
  end
99
46
 
@@ -0,0 +1,62 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ describe Lipa::Web::Application do
4
+ include Rack::Test::Methods
5
+
6
+ before :each do
7
+ @srv = root :srv do
8
+ views File.join(File.dirname(__FILE__), "views")
9
+ layout "layout.html.erb"
10
+
11
+ example_node
12
+
13
+ node :node_with_template do
14
+ html erb("./my_template.html.erb")
15
+ end
16
+
17
+ node :node_greater do
18
+ html text("Hello world!")
19
+ end
20
+
21
+ node :node_man_html do
22
+ say "Hello"
23
+ html { "<h1>#{say}</h1>" }
24
+ end
25
+ end
26
+ end
27
+
28
+ def app
29
+ Lipa::Web::Application.new(@srv)
30
+ end
31
+
32
+ it 'should render default html template' do
33
+ get "/group/test_node"
34
+
35
+ last_response.header['Content-Type'].should eql( "text/html")
36
+ last_response.body.gsub(/^\s*\n/, '').should == fixture("node.html")
37
+ end
38
+
39
+ it 'should render custom html template' do
40
+ get "/node_with_template"
41
+
42
+ last_response.header['Content-Type'].should eql("text/html")
43
+ last_response.body.gsub(/^\s*\n/, '').should == fixture("node_with_template.html")
44
+ end
45
+
46
+ it 'should render text' do
47
+ get "/node_greater"
48
+
49
+ last_response.header['Content-Type'].should eql("text/plain")
50
+ last_response.body.should == "Hello world!"
51
+ end
52
+
53
+
54
+ it 'should have custom html response' do
55
+ get "/node_man_html"
56
+
57
+ last_response.header['Content-Type'].should eql("text/html")
58
+ last_response.body.should == '<h1>Hello</h1>'
59
+ end
60
+ end
61
+
62
+