rango 0.1.1.3 → 0.2.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/CHANGELOG +17 -1
  2. data/Rakefile +8 -3
  3. data/bin/rango +0 -13
  4. data/lib/rango.rb +23 -12
  5. data/lib/rango/controller.rb +70 -57
  6. data/lib/rango/core_ext.rb +100 -17
  7. data/lib/rango/environments.rb +33 -19
  8. data/lib/rango/exceptions.rb +1 -1
  9. data/lib/rango/forms/form.rb +2 -1
  10. data/lib/rango/helpers/assets.rb +6 -1
  11. data/lib/rango/helpers/general.rb +1 -1
  12. data/lib/rango/mixins/action_args.rb +48 -0
  13. data/lib/rango/mixins/chainable.rb +66 -0
  14. data/lib/rango/mixins/filters.rb +12 -20
  15. data/lib/rango/mixins/logger.rb +1 -0
  16. data/lib/rango/mixins/message.rb +5 -6
  17. data/lib/rango/mixins/render.rb +1 -1
  18. data/lib/rango/orm/tasks/datamapper.rake +4 -4
  19. data/lib/rango/path.rb +6 -1
  20. data/lib/rango/rack/request.rb +18 -29
  21. data/lib/rango/router.rb +1 -1
  22. data/lib/rango/stacks/controller.rb +0 -1
  23. data/lib/rango/templates/exts/tilt.rb +3 -3
  24. data/lib/rango/templates/helpers.rb +55 -27
  25. data/lib/rango/templates/template.rb +11 -9
  26. data/spec/rango/controller_spec.rb +0 -1
  27. data/spec/rango/{loggers/fireruby_spec.rb → core_ext_spec.rb} +0 -0
  28. data/spec/rango/environments_spec.rb +6 -6
  29. data/spec/rango/{mixins/application_spec.rb → gv/router_spec.rb} +0 -0
  30. data/spec/rango/{orm/adapter_spec.rb → gv/scaffolding_spec.rb} +0 -0
  31. data/spec/rango/{orm/adapters/datamapper_spec.rb → mini_render_spec.rb} +0 -0
  32. data/spec/rango/mixins/action_args_spec.rb +78 -0
  33. data/spec/rango/{orm/adapters/sequel_spec.rb → mixins/chainable_spec.rb} +0 -0
  34. data/spec/rango/{orm/support/datamapper/support_spec.rb → mixins/logger_spec.rb} +0 -0
  35. data/spec/rango/mixins/message_spec.rb +4 -1
  36. data/spec/rango/mixins/render_spec.rb +1 -1
  37. data/spec/rango/{settings/erubis_spec.rb → path_spec.rb} +0 -0
  38. data/spec/rango/{settings/framework_spec.rb → stacks/controller_spec.rb} +0 -0
  39. data/spec/rango/{settings/haml_spec.rb → stacks/mini_spec.rb} +0 -0
  40. data/spec/rango/templates/helpers_spec.rb +125 -0
  41. data/spec/rango/templates/template_spec.rb +1 -2
  42. data/spec/rango/{settings/template_spec.rb → version_spec.rb} +0 -0
  43. data/spec/rango_spec.rb +6 -1
  44. data/spec/spec_helper.rb +8 -2
  45. data/spec/stubs/templates/_basic.html.erb +6 -0
  46. data/spec/stubs/templates/block/block.html.haml +2 -0
  47. data/spec/stubs/templates/block/blocks.html.haml +5 -0
  48. data/spec/stubs/templates/block/error.html.haml +2 -0
  49. data/spec/stubs/templates/block/getter.html.haml +3 -0
  50. data/spec/stubs/templates/block/value.html.haml +1 -0
  51. data/spec/stubs/templates/enhance_block/basic.html.haml +5 -0
  52. data/spec/stubs/templates/enhance_block/error.html.haml +3 -0
  53. data/spec/stubs/templates/enhance_block/name_error.html.haml +1 -0
  54. data/spec/stubs/templates/enhance_block/nil.html.haml +3 -0
  55. data/spec/stubs/templates/enhance_block/standalone.html.haml +2 -0
  56. data/spec/stubs/templates/extend_block/basic.html.haml +5 -0
  57. data/spec/stubs/templates/extend_block/error.html.haml +5 -0
  58. data/spec/stubs/templates/extend_block/error2.html.haml +1 -0
  59. data/spec/stubs/templates/extend_block/name_error.html.haml +1 -0
  60. data/spec/stubs/templates/extend_block/nil.html.haml +4 -0
  61. data/spec/stubs/templates/includes/base.html.haml +1 -0
  62. data/spec/stubs/templates/includes/basic.html.haml +1 -0
  63. data/spec/stubs/templates/includes/includes.html.haml +7 -0
  64. data/spec/stubs/templates/includes/integration.html.haml +4 -0
  65. data/spec/stubs/templates/includes/integration2.html.haml +4 -0
  66. data/spec/stubs/templates/library.html.haml +3 -0
  67. data/stubs/features/content/shared/.gitignore +0 -0
  68. data/stubs/stack/content/.gitignore +18 -0
  69. data/stubs/stack/content/.rvmrc.rbt +2 -0
  70. data/stubs/stack/content/Gemfile.rbt +8 -1
  71. data/stubs/stack/content/{settings_local.rb.rbt → environments.rb.rbt} +11 -0
  72. data/stubs/stack/content/init.rb.rbt +8 -4
  73. data/stubs/stack/content/media/.gitignore +0 -0
  74. data/stubs/stack/content/spec/spec_helper.rb +1 -1
  75. data/stubs/stack/content/views.rb.rbt +13 -5
  76. data/stubs/stack/postprocess.rb +2 -9
  77. metadata +62 -29
  78. data/lib/rango/logger.rb +0 -19
  79. data/lib/rango/loggers/fireruby.rb +0 -1
  80. data/lib/rango/mixins/application.rb +0 -27
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require "rango"
4
+ require "rango/templates/template"
4
5
 
5
6
  module Rango
6
7
  module TemplateHelpers
@@ -54,52 +55,79 @@ module Rango
54
55
  # post/base.html
55
56
  # base.html: here it will be rendered, so we need block to returns the correct block code
56
57
  # @since 0.0.2
58
+ # @version 0.2
57
59
  def block(name, value = nil, &block)
58
- value = self._template.scope.capture(&block) if value.nil? && block
59
- self._template.blocks[name] ||= value
60
+ raise ArgumentError, "Block has to have a name!" if name.nil?
61
+ raise ArgumentError, "You have to provide value or block, not both of them!" if value && block
62
+ self._template.blocks[name] ||= block ? self._template.scope.capture(&block) : value
60
63
  return self._template.blocks[name]
61
64
  end
62
65
 
63
66
  # - extend_block(:head) do
64
- # != pupu :lighter, syntax: "html", theme: "standard"
65
- # != block(:head)
66
- #
67
- # TODO: something more intuitive like:
68
- # - block(:head) do
69
- # != pupu :lighter, syntax: "html", theme: "standard"
70
- # != block(:head)
71
- #
72
- # OR even:
73
- # - block(:head) do
74
- # != pupu :lighter, syntax: "html", theme: "standard"
75
- # = superblock
67
+ # = pupu :lighter, syntax: "html", theme: "standard"
68
+ # = block(:head)
76
69
  def extend_block(name, value = nil, &block)
70
+ unless self._template.blocks[name]
71
+ raise NameError, "Block #{name.inspect} wasn't defined yet, you can't extend it!"
72
+ end
73
+ self.enhance_block(name, value, &block)
74
+ end
75
+
76
+ def enhance_block(name, value = nil, &block)
77
+ raise ArgumentError, "Block has to have a name!" if name.nil?
78
+ raise ArgumentError, "You have to provide value or block, not both of them!" if value && block
77
79
  value = self._template.scope.capture(&block) if value.nil? && block
78
- self._template.blocks[name] += value
80
+ self._template.blocks[name] = "#{self._template.blocks[name]}\n#{value}" if value
79
81
  return self._template.blocks[name]
80
82
  end
81
83
 
84
+ # Low-level rendering method for templates.
85
+ #
86
+ # @since 0.2
87
+ # @example
88
+ # render "base.html"
89
+ # render "./base.html"
90
+ # render "../base.html"
91
+ def render(template, context = Hash.new)
92
+ normalize_template_path(template)
93
+ original_template = self._template
94
+ template = Rango::Template.new(template, self) # self is scope
95
+ self._template = original_template
96
+ return template.render(context)
97
+ end
98
+
82
99
  # partial "products/list"
83
100
  # @since 0.0.2
101
+ # @version 0.2
84
102
  def partial(template, context = Hash.new)
85
- if template.match(%r[/])
86
- path, last = File.split(template)[0..-1]
87
- template = File.join(path, "_#{last}")
88
- else
89
- template = "_#{template}"
90
- end
91
- template = Rango::Template.new(template, self._template.scope, context)
92
- template.partial = true
93
- # TODO: #block in partial templates
94
- output = template.render
95
- return output
103
+ # NOTE: we can't use File.split because it normalize the path,
104
+ # so "./base.html" will be the same as "base.html", but it shouldn't be
105
+ *path, basename = template.split("/")
106
+ render File.join(*path, "_#{basename}")
107
+ end
108
+
109
+ # @since 0.2
110
+ def includes(template, context = Hash.new)
111
+ render template, context
112
+ return true
96
113
  end
97
114
 
98
115
  # extends "base.html"
99
116
  # @since 0.0.2
100
117
  def extends(path)
101
118
  # we can't just create a new template, because it has to do it after it reads the whole file
102
- self._template.supertemplate = path
119
+ self._template.supertemplate = normalize_template_path(path)
120
+ end
121
+
122
+ # @since 0.2
123
+ def normalize_template_path(template)
124
+ if template.start_with?("./")
125
+ File.expand_path(File.join(File.dirname(self._template.fullpath), template))
126
+ elsif template.start_with?("../")
127
+ File.expand_path(File.join(File.dirname(self._template.fullpath), "..", template))
128
+ else
129
+ template
130
+ end
103
131
  end
104
132
  end
105
133
  end
@@ -1,9 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require "rango/templates/exts/tilt"
4
- require "rubyexts/attribute"
5
- require "rubyexts/string" # String#snake_case
6
- require "rubyexts/class" # cattr_accessor
4
+ require "rango/core_ext" # String#snake_case
7
5
  require "rango/templates/helpers"
8
6
  require "rango/exceptions"
9
7
 
@@ -13,19 +11,23 @@ module Rango
13
11
  end
14
12
 
15
13
  class Template
16
- cattr_accessor :template_paths
17
- self.template_paths = [File.join(Rango.root, "templates")]
14
+ def self.template_paths
15
+ @@template_paths ||= [File.join(Rango.root, "templates")]
16
+ end
18
17
 
19
18
  # template -> supertemplate is the same relationship as class -> superclass
20
19
  # @since 0.0.2
21
20
  attr_accessor :path, :scope, :supertemplate
22
21
 
23
22
  # @since 0.0.2
24
- attribute :blocks, Hash.new
23
+ attr_writer :blocks
24
+ def blocks
25
+ @blocks ||= Hash.new
26
+ end
25
27
 
26
28
  # @since 0.0.2
27
29
  def initialize(path, scope = Object.new)
28
- self.path = path#[scope.class.template_prefix.chomp("/"), template].join("/")
30
+ self.path = path#[scope.class.template_prefix.chomp("/"), template].join("/")
29
31
  self.scope = scope.extend(TemplateHelpers)
30
32
  self.scope._template = self
31
33
  end
@@ -55,10 +57,10 @@ module Rango
55
57
 
56
58
  # @since 0.0.2
57
59
  def render(context = Hash.new)
58
- raise Errors::TemplateNotFound.new("Template #{self.path} wasn't found in these template_paths: #{self.template_paths.inspect}") if self.fullpath.nil?
60
+ raise Errors::TemplateNotFound.new("Template #{self.path} wasn't found in these template_paths: #{self.class.template_paths.inspect}") if self.fullpath.nil?
59
61
  value = self.template.render(self.scope, context)
60
62
  Rango.logger.info("Rendering template #{self.path}")
61
- # Rango.logger.inspect(self.blocks)
63
+ # #Rango.logger.inspect(self.blocks)
62
64
  if self.supertemplate
63
65
  Rango.logger.debug("Extends call: #{self.supertemplate}")
64
66
  supertemplate = self.class.new(self.supertemplate, self.scope)
@@ -2,7 +2,6 @@
2
2
 
3
3
  require_relative "../spec_helper"
4
4
 
5
- require "rango/logger"
6
5
  require "rango/controller"
7
6
  require "rack/mock"
8
7
 
@@ -14,10 +14,10 @@ describe "Rango environments" do
14
14
  Rango.should be_development
15
15
  end
16
16
 
17
- it "should be true if Rango.environment is included in Rango.development_environments" do
17
+ it "should be true if Rango.environment is included in Rango.environments[:development]" do
18
18
  Rango.environment = "foobar"
19
19
  Rango.should_not be_development
20
- Rango.development_environments.push("foobar")
20
+ Rango.environments[:development].push("foobar")
21
21
  Rango.should be_development
22
22
  end
23
23
  end
@@ -30,10 +30,10 @@ describe "Rango environments" do
30
30
  end
31
31
  end
32
32
 
33
- it "should be true if Rango.environment is included in Rango.production_environments" do
33
+ it "should be true if Rango.environment is included in Rango.environments[:production]" do
34
34
  Rango.environment = "foobar"
35
35
  Rango.should_not be_production
36
- Rango.production_environments.push("foobar")
36
+ Rango.environments[:production].push("foobar")
37
37
  Rango.should be_production
38
38
  end
39
39
  end
@@ -46,10 +46,10 @@ describe "Rango environments" do
46
46
  end
47
47
  end
48
48
 
49
- it "should be true if Rango.environment is included in Rango.testing_environments" do
49
+ it "should be true if Rango.environment is included in Rango.environments[:testing]" do
50
50
  Rango.environment = "foobar"
51
51
  Rango.should_not be_testing
52
- Rango.testing_environments.push("foobar")
52
+ Rango.environments[:testing].push("foobar")
53
53
  Rango.should be_testing
54
54
  end
55
55
  end
@@ -0,0 +1,78 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative "../../spec_helper"
4
+
5
+ require "rango"
6
+ require "logger"
7
+ Rango.logger = Logger.new("/dev/null")
8
+
9
+ require "rango/controller"
10
+ require "rango/mixins/action_args"
11
+
12
+ Rango::Router.use(:urlmap)
13
+
14
+ describe Rango::ActionArgsMixin do
15
+ controller = Class.new(Rango::Controller) do
16
+ include Rango::ActionArgsMixin
17
+
18
+ def show(id)
19
+ id
20
+ end
21
+
22
+ def create(post, msg = "Created successfuly")
23
+ "#{post} - #{msg}"
24
+ end
25
+
26
+ def view_with_a_splat(*args)
27
+ end
28
+
29
+ def view_with_a_block(&block)
30
+ end
31
+ end
32
+
33
+ def env_for_action(action, url = "/")
34
+ env = Rack::MockRequest.env_for(url)
35
+ env.merge("rango.controller.action" => action)
36
+ end
37
+
38
+ it "should raise argument error if there is a splat argument" do
39
+ env = env_for_action(:view_with_a_splat)
40
+ -> { controller.call(env) }.should raise_error(ArgumentError)
41
+ end
42
+
43
+ it "should raise argument error if there is a block argument" do
44
+ env = env_for_action(:view_with_a_block)
45
+ -> { controller.call(env) }.should raise_error(ArgumentError)
46
+ end
47
+
48
+ it "should raise argument error if there are arguments which doesn't match any key in params" do
49
+ env = env_for_action(:show)
50
+ -> { controller.call(env) }.should raise_error(ArgumentError)
51
+ end
52
+
53
+ it "should call a view with arguments matching params[argument]" do
54
+ env = env_for_action(:show, "/?id=12")
55
+ status, headers, body = controller.call(env)
56
+ body.should eql(["12"])
57
+ end
58
+
59
+ it "should call a view with arguments matching params[argument]" do
60
+ env = env_for_action(:show, "/?id=12&msg=hi") # nevadi ze je tam toho vic
61
+ instance = controller.new(env)
62
+ status, headers, body = controller.call(env)
63
+ body.should eql(["12"])
64
+ end
65
+
66
+ # NOTE: we can't use stubs because the stub redefine the method, so parameters of this method will be everytime just optional args and block
67
+ it "should call a view with arguments matching params[argument]" do
68
+ env = env_for_action(:create, "/?post=neco&msg=message")
69
+ status, headers, body = controller.call(env)
70
+ body.should eql(["neco - message"])
71
+ end
72
+
73
+ it "should not require optinal arguments to be in params" do
74
+ env = env_for_action(:create, "/?post=neco")
75
+ status, headers, body = controller.call(env)
76
+ body.should eql(["neco - Created successfuly"])
77
+ end
78
+ end
@@ -7,6 +7,10 @@ require "rango/controller"
7
7
  require "rango/mixins/message"
8
8
  require "rango/mixins/rendering"
9
9
 
10
+ # HACK because of rSpec, the trouble was:
11
+ # TestController.method_defined?(:context) => true
12
+ Rango::Controller.send(:undef_method, :context)
13
+
10
14
  class TestController < Rango::Controller
11
15
  include Rango::MessageMixin
12
16
  end
@@ -19,7 +23,6 @@ describe Rango::MessageMixin do
19
23
 
20
24
  describe ".included" do
21
25
  it "should not do anything if method context isn't defined" do
22
- pending "How to implement it?"
23
26
  @controller.should_not respond_to(:context)
24
27
  end
25
28
 
@@ -4,7 +4,7 @@ require_relative "../../spec_helper"
4
4
 
5
5
  require "rango/mixins/render"
6
6
 
7
- Rango::Template.template_paths = [File.join(STUBS_ROOT, "templates")]
7
+ Rango::Template.template_paths.clear.push(File.join(STUBS_ROOT, "templates"))
8
8
 
9
9
  describe Rango::RenderMixin do
10
10
  it "should work standalone" do
@@ -0,0 +1,125 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative "../../spec_helper"
4
+ require "rango/templates/helpers"
5
+
6
+ Rango::Template.template_paths.clear.push(File.join(STUBS_ROOT, "templates"))
7
+
8
+ describe Rango::TemplateHelpers do
9
+ include Rango::TemplateHelpers
10
+ describe "#partial" do
11
+ it "should work" do
12
+ partial "basic.html"
13
+ end
14
+
15
+ it "should share context with the parent template"
16
+ it "should be able to specify additional context which isn't propagated to the parent template"
17
+ end
18
+
19
+ describe "#render" do
20
+ it "should consider 'path.html' as a path relative to Template.template_paths"
21
+ it "should consider './path.html' as a path relative to the current template"
22
+ it "should look for '../path.html' in the parent directory of directory with current template"
23
+ end
24
+
25
+ describe "#includes" do
26
+ require "rango/mixins/render"
27
+ it "should return true" do
28
+ Rango::RenderMixin.render("includes/basic.html").strip.should eql("true")
29
+ end
30
+
31
+ it "should work with blocks" do
32
+ Rango::RenderMixin.render("includes/includes.html")
33
+ end
34
+
35
+ it "should work with extends" do
36
+ output = Rango::RenderMixin.render("includes/integration.html")
37
+ output.strip.should eql("Greeting by Jakub Stastny")
38
+ end
39
+
40
+ it "should work with extends" do
41
+ output = Rango::RenderMixin.render("includes/integration2.html")
42
+ output.strip.should eql("Greeting by Jakub Stastny")
43
+ end
44
+ end
45
+
46
+ describe "extends" do
47
+ end
48
+
49
+ describe "block" do
50
+ it "should raise argument error if name isn't specified" do
51
+ -> { block(nil) }.should raise_error(ArgumentError)
52
+ end
53
+
54
+ it "should work as a setter if a value is provided" do
55
+ output = Rango::RenderMixin.render("block/value.html")
56
+ output.strip.should eql("a value")
57
+ end
58
+
59
+ it "should work as a setter if a block is provided" do
60
+ output = Rango::RenderMixin.render("block/block.html")
61
+ output.strip.should eql("a block")
62
+ end
63
+
64
+ it "should work as a getter" do
65
+ output = Rango::RenderMixin.render("block/getter.html")
66
+ output.strip.should eql("Hello World!")
67
+ end
68
+
69
+ it "should raise argument error if both value and block is provided" do
70
+ -> { Rango::RenderMixin.render("block/error.html") }.should raise_error(ArgumentError)
71
+ end
72
+
73
+ it "should store the first non-nil value" do
74
+ output = Rango::RenderMixin.render("block/blocks.html")
75
+ output.strip.should eql("first")
76
+ end
77
+ end
78
+
79
+ describe "extend_block" do
80
+ it "should raise argument error if name isn't specified" do
81
+ -> { Rango::RenderMixin.render("extend_block/name_error.html") }.should raise_error(NameError)
82
+ end
83
+
84
+ it "should raise argument error if both value and block is provided" do
85
+ -> { Rango::RenderMixin.render("extend_block/error.html") }.should raise_error(ArgumentError)
86
+ end
87
+
88
+ it "should raise argument error if block of given name doesn't exist so far" do
89
+ -> { Rango::RenderMixin.render("extend_block/error2.html") }.should raise_error
90
+ end
91
+
92
+ it "should work with super()-like inheritance" do
93
+ Rango::RenderMixin.render("extend_block/basic.html")
94
+ end
95
+
96
+ it "should do nothing if the value or block is nil" do
97
+ output = Rango::RenderMixin.render("extend_block/nil.html")
98
+ output.strip.should eql("Original")
99
+ end
100
+ end
101
+
102
+ describe "enhance_block" do
103
+ it "should work even if the block isn't defined so far" do
104
+ output = Rango::RenderMixin.render("enhance_block/standalone.html")
105
+ output.strip.should eql("Hello World!")
106
+ end
107
+
108
+ it "should not raise argument error if name isn't specified" do
109
+ -> { Rango::RenderMixin.render("enhance_block/name_error.html") }.should_not raise_error(NameError)
110
+ end
111
+
112
+ it "should raise argument error if both value and block is provided" do
113
+ -> { Rango::RenderMixin.render("enhance_block/error.html") }.should raise_error(ArgumentError)
114
+ end
115
+
116
+ it "should work with super()-like inheritance" do
117
+ Rango::RenderMixin.render("enhance_block/basic.html")
118
+ end
119
+
120
+ it "should do nothing if the value or block is nil" do
121
+ output = Rango::RenderMixin.render("enhance_block/nil.html")
122
+ output.strip.should eql("Original")
123
+ end
124
+ end
125
+ end