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
@@ -29,7 +29,7 @@ module Rango
29
29
  end
30
30
 
31
31
  def to_response
32
- headers = self.headers.reverse_merge("Content-Type" => self.content_type)
32
+ headers = {"Content-Type" => self.content_type}.merge(self.headers)
33
33
  [self.status, headers, [self.message]]
34
34
  end
35
35
 
@@ -9,7 +9,8 @@
9
9
  # @future 0.0.3 It's just a prototype now
10
10
  module Rango
11
11
  class Form
12
- attribute :media
12
+ def media
13
+ end
13
14
 
14
15
  def valid?
15
16
  end
@@ -4,7 +4,12 @@
4
4
  # ... but what if I need full path? It should be tested if file exist, of course
5
5
  # javascript Path.new("design/whatever.js")
6
6
  require "rango/helpers"
7
- require "media-path"
7
+
8
+ begin
9
+ require "media-path"
10
+ rescue LoadError
11
+ raise LoadError, "You have to install media-path gem!"
12
+ end
8
13
 
9
14
  module Rango
10
15
  module Helpers
@@ -46,7 +46,7 @@ module Rango
46
46
  options[:size] = args[0] || 75
47
47
  options[:omission] = args[1] || "..."
48
48
  end
49
- options.reverse_merge!(:size => 75, :omission => "...")
49
+ options = {size: 75, omission: "..."}.merge(options)
50
50
  text.scan(/(\S+)(\s+)/)[0..options[:size]].flatten.join << options[:omission] if text
51
51
  end
52
52
  end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+
3
+ # class Application < Rango::Controller
4
+ # include Rango::ActionArgsMixin
5
+ # end
6
+
7
+ # def test(name, params = Hash.new, *args)
8
+ # end
9
+ # method(:test).parameters
10
+ # => [[:req, :name], [:opt, :params], [:rest, :args]]
11
+
12
+ if RUBY_VERSION < "1.9.2"
13
+ begin
14
+ require "methopara"
15
+ rescue LoadError
16
+ raise LoadError, "Method#parameters is part of Ruby 1.9.2 and higher. If you want to use this feature with Ruby 1.9.1, you have to install methopara gem (http://github.com/genki/methopara)"
17
+ end
18
+ end
19
+
20
+ module Rango
21
+ module ActionArgsMixin
22
+ def invoke_action(action)
23
+ view = self.method(action)
24
+ names = view.parameters.map { |type, name| name }
25
+ types = view.parameters.map { |type, name| type }
26
+ required = view.parameters.map { |type, name| name if type.eql?(:req) }.compact
27
+
28
+ # validate types
29
+ if types.include?(:rest)
30
+ raise ArgumentError, "View can't have splat argument. Use just this: def #{action}(#{names[0..-2].join(", ")})"
31
+ elsif types.include?(:block)
32
+ raise ArgumentError, "View can't have block argument. Use just this: def #{action}(#{names[0..-2].join(", ")})"
33
+ end
34
+
35
+ # validate names
36
+ unless (extra_keys = required - self.params.keys).empty?
37
+ raise ArgumentError, "Following keys aren't available in params: #{extra_keys.inspect}\nAvailable keys: #{self.params.keys.inspect}"
38
+ end
39
+
40
+ args = Array.new
41
+ view.parameters.each do |type, name|
42
+ args.push(self.params[name]) if type.eql?(:req) || (type.eql?(:opt) && !self.params[name].nil?) # this is a bit complex, but we have to do because of rewriting optional args by nil value if we use just map with params[name]
43
+ end
44
+ puts "Rendering #{self}##{action} with #{args.map(&:inspect).join(", ")}"
45
+ self.send(action, *args)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+
3
+ # from merb-core
4
+ module Chainable
5
+ # Allows the definition of methods on a class that will be available via
6
+ # super.
7
+ #
8
+ # ==== Examples
9
+ # class Foo
10
+ # extend Chainable
11
+ # chainable do
12
+ # def hello
13
+ # "hello"
14
+ # end
15
+ # end
16
+ # end
17
+ #
18
+ # class Foo
19
+ # def hello
20
+ # super + " Merb!"
21
+ # end
22
+ # end
23
+ #
24
+ # # Example with mixin:
25
+ # module TestMixin
26
+ # extend Chainable
27
+ # chainable do
28
+ # def test
29
+ # "from mixin!"
30
+ # end
31
+ # end
32
+ # end
33
+ #
34
+ # class Test
35
+ # include TestMixin
36
+ # def test
37
+ # "hello " + super
38
+ # end
39
+ # end
40
+ #
41
+ # puts Test.new.test
42
+ #
43
+ #
44
+ # Foo.new.hello #=> "hello Merb!"
45
+ #
46
+ # ==== Parameters
47
+ # &block::
48
+ # a block containing method definitions that should be
49
+ # marked as chainable
50
+ #
51
+ # ==== Returns
52
+ # Module:: The anonymous module that was created
53
+ def chainable(method = nil, &block)
54
+ if method.nil? && block_given?
55
+ mixin = Module.new(&block)
56
+ include mixin
57
+ return mixin
58
+ elsif method && ! block_given?
59
+ # TODO
60
+ # def test
61
+ # # ...
62
+ # end
63
+ # chainable :test
64
+ end
65
+ end
66
+ end
@@ -16,7 +16,7 @@ module Rango
16
16
  # @since 0.0.2
17
17
  def run_filters(name, method)
18
18
  # Rango.logger.debug(self.class.instance_variables)
19
- # Rango.logger.inspect(name: name, method: method)
19
+ # #Rango.logger.inspect(name: name, method: method)
20
20
  self.class.get_filters(name).each do |filter_method, options|
21
21
  unless options[:except] && options[:except].include?(method)
22
22
  if filter_method.is_a?(Symbol) && self.respond_to?(filter_method)
@@ -33,17 +33,19 @@ module Rango
33
33
  end
34
34
 
35
35
  module ClassMethods
36
- def inherited(subclass)
37
- inherit_filters(subclass, :before)
38
- inherit_filters(subclass, :after)
39
- inherit_filters(subclass, :before_render)
40
- inherit_filters(subclass, :after_render)
41
- inherit_filters(subclass, :before_display)
42
- inherit_filters(subclass, :after_display)
36
+ #def inherited(subclass)
37
+ # subclass.before_filters = self.before_filters.dup
38
+ # subclass.after_filters = self.after_filters.dup
39
+ #end
40
+
41
+ # @since 0.2
42
+ def before_filters
43
+ @@before_filters ||= Hash.new
43
44
  end
44
45
 
45
- def inherit_filters(subclass, name)
46
- subclass.send("#{name}_filters=", self.send("#{name}_filters").dup)
46
+ # @since 0.2
47
+ def after_filters
48
+ @@after_filters ||= Hash.new
47
49
  end
48
50
 
49
51
  # before :login
@@ -62,16 +64,6 @@ module Rango
62
64
  def get_filters(type)
63
65
  self.send("#{type}_filters")
64
66
  end
65
-
66
- # @since 0.0.2
67
- attribute :before_filters, Hash.new
68
- attribute :after_filters, Hash.new
69
-
70
- attribute :before_render_filters, Array.new
71
- attribute :after_render_filters, Array.new
72
-
73
- attribute :before_display_filters, Array.new
74
- attribute :after_display_filters, Array.new
75
67
  end
76
68
  end
77
69
  end
@@ -17,3 +17,4 @@ module Rango
17
17
  end
18
18
  end
19
19
  end
20
+
@@ -6,12 +6,11 @@ module Rango
6
6
  # @since 0.0.2
7
7
  # NOTE: it's important to include this mixin after ImplicitRendering mixin
8
8
  def self.included(controller)
9
- # How to determine
10
- # respond to not, it's a class
11
- # if controller.instance_methods.include?(:context)
12
- controller.class_eval do
13
- def context
14
- @context ||= super.merge!(message: self.message)
9
+ if controller.method_defined?(:context)
10
+ controller.class_eval do
11
+ def context
12
+ @context ||= super.merge!(message: self.message)
13
+ end
15
14
  end
16
15
  end
17
16
  end
@@ -10,7 +10,7 @@ module Rango
10
10
  # @since 0.0.2
11
11
  def render(path, scope = Object.new, context = Hash.new)
12
12
  scope, context = Object.new, scope if context.empty? && scope.is_a?(Hash)
13
- Rango.logger.inspect(context: context)
13
+ #Rango.logger.inspect(context: context)
14
14
  template = Rango::Template.new(path, scope)
15
15
  return template.render(context)
16
16
  end
@@ -4,7 +4,7 @@ namespace :db do
4
4
  # @since 0.0.2
5
5
  desc "Automigrate the database. It will destroy all the data!"
6
6
  task :automigrate, :environment, :needs => :environment do |task, args|
7
- RANGO_ENV = args.environment || ENV["RANGO_ENV"] || "development"
7
+ RACK_ENV = args.environment || ENV["RACK_ENV"] || "development"
8
8
  Rango.logger.info("[#{Rango.environment}] Migrating databases ...")
9
9
  result = DataMapper.auto_migrate!
10
10
  Rango.logger.debug("Result: #{result.inspect}")
@@ -13,7 +13,7 @@ namespace :db do
13
13
  # @since 0.0.2
14
14
  desc "Autoupgrade the database structure. Data should stay untouched."
15
15
  task :autupgrade, :environment, :needs => :environment do |task, args|
16
- RANGO_ENV = args.environment || ENV["RANGO_ENV"] || "development"
16
+ RACK_ENV = args.environment || ENV["RACK_ENV"] || "development"
17
17
  Rango.logger.info("[#{Rango.environment}] Upgrading databases ...")
18
18
  result = DataMapper.auto_upgrade!
19
19
  Rango.logger.debug("Result: #{result.inspect}")
@@ -21,7 +21,7 @@ namespace :db do
21
21
 
22
22
  desc "Report count of objects in database"
23
23
  task :report, :environment, :needs => :environment do |task, args|
24
- RANGO_ENV = args.environment || ENV["RANGO_ENV"] || "development"
24
+ RACK_ENV = args.environment || ENV["RACK_ENV"] || "development"
25
25
  ObjectSpace.classes.each do |klass|
26
26
  if klass.included(DataMapper::Resource)
27
27
  puts "#{model_class}: #{model_class.count}"
@@ -32,7 +32,7 @@ namespace :db do
32
32
  # @since 0.0.2
33
33
  desc "Run migrations"
34
34
  task :migrate, :environment, :needs => :environment do |task, args|
35
- RANGO_ENV = args.environment || ENV["RANGO_ENV"] || "development"
35
+ RACK_ENV = args.environment || ENV["RACK_ENV"] || "development"
36
36
  abort "Use rake db:migrate:up[version] or db:migrate:down[version]"
37
37
  end
38
38
 
data/lib/rango/path.rb CHANGED
@@ -1,7 +1,12 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require "rango"
4
- require_gem "media-path"
4
+
5
+ begin
6
+ require "media-path"
7
+ rescue LoadError
8
+ raise LoadError, "You have to install media-path gem!"
9
+ end
5
10
 
6
11
  # @since 0.0.2
7
12
  # @example
@@ -37,8 +37,7 @@
37
37
  # http://rack.rubyforge.org/doc/classes/Rack/Request.html
38
38
 
39
39
  require "rack"
40
- require "rubyexts/try"
41
- require "rubyexts/hash" # Hash#except
40
+ require "rango/core_ext"
42
41
 
43
42
  module Rango
44
43
  module Session
@@ -49,9 +48,6 @@ module Rango
49
48
  # @return [Hash] Original Rack environment.
50
49
  attr_reader :env
51
50
 
52
- # @since 0.0.2
53
- #attribute :message, Hash.new
54
-
55
51
  # @since 0.0.1
56
52
  # @example: blog/post/rango-released
57
53
  # @return [Hash] Original Rack environment.
@@ -64,16 +60,17 @@ module Rango
64
60
  # /path will be transformed to path/
65
61
  @path = env["PATH_INFO"]
66
62
  @path.chomp!("/") if @path && @path.length > 1 # so let the / just if the path is only /
67
- @method = env["REQUEST_METHOD"].try(:downcase)
68
- self.extend_session
63
+ @method = (env["REQUEST_METHOD"] || String.new).downcase
64
+ session.extend(Session)
65
+ Rango.logger.debug("Session: #{@env['rack.session'].inspect}")
69
66
  end
70
67
 
71
68
  def GET
72
- super.deep_symbolize_keys.except(:_method)
69
+ normalize_params(super)
73
70
  end
74
71
 
75
72
  def POST
76
- super.deep_symbolize_keys.except(:_method) if self.post?
73
+ normalize_params(super)
77
74
  end
78
75
 
79
76
  def PUT
@@ -88,36 +85,29 @@ module Rango
88
85
  @env["rack.request.form_hash"] = Utils.parse_query(@env["rack.request.form_vars"])
89
86
  @env["rack.input"].rewind if @env["rack.input"].respond_to?(:rewind)
90
87
  end
91
- @env["rack.request.form_hash"].deep_symbolize_keys.except(:_method)
88
+ normalize_params(@env["rack.request.form_hash"])
92
89
  else
93
90
  {}
94
91
  end
95
92
  end
96
93
  end
97
94
 
98
- def DELETE
99
- {}.deep_symbolize_keys.except(:_method)
100
- end
101
-
102
95
  def params
103
- @params = Hash.new
104
- [self.GET, self.POST, self.PUT, self.DELETE].each do |data|
105
- @params.merge!(data) if data.respond_to?(:merge) # Hash, Mash and friends
96
+ input = [self.GET, self.POST, self.PUT]
97
+ input.inject(Hash.new) do |result, hash|
98
+ hash ? result.merge!(hash) : result
106
99
  end
107
- @params.deep_symbolize_keys.except(:msg, :_method)
108
100
  end
109
101
 
110
102
  def cookies
111
- super.except("rack.session").symbolize_keys
103
+ super.tap { |cookies| cookies.delete("rack.session") }.symbolize_keys
112
104
  end
113
105
 
114
106
  def form
115
- data = env["rack.request.form_hash"] || Hash.new
116
- data.deep_symbolize_keys.except(:_method)
107
+ normalize_params(env["rack.request.form_hash"] || Hash.new)
117
108
  end
118
109
 
119
110
  def session
120
- # Rango.logger.inspect(session: @env['rack.session'])
121
111
  @env['rack.session'] ||= {}
122
112
  end
123
113
 
@@ -125,13 +115,6 @@ module Rango
125
115
  env["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest"
126
116
  end
127
117
 
128
- # TODO: use extend method
129
- def extend_session
130
- class << session
131
- include Rango::Session
132
- end
133
- end
134
-
135
118
  # @since 0.0.1
136
119
  # @example: "cz"
137
120
  # @return [String] Top level domain.
@@ -142,6 +125,7 @@ module Rango
142
125
  # @since 0.0.1
143
126
  # @example: "101ideas.cz"
144
127
  # @return [String] Domain name.
128
+ # FIXME: what about .co.uk? Rewrite in the same way as subdomains
145
129
  def domain
146
130
  if host.match(/^localhost/)
147
131
  return host.split(".").last
@@ -172,5 +156,10 @@ module Rango
172
156
  end
173
157
  url
174
158
  end
159
+
160
+ protected
161
+ def normalize_params(hash)
162
+ hash.deep_symbolize_keys.tap { |hash| hash.delete(:_method) }
163
+ end
175
164
  end
176
165
  end
data/lib/rango/router.rb CHANGED
@@ -6,7 +6,7 @@ module Rango
6
6
  module UrlHelper
7
7
  # url(:login)
8
8
  def url(*args)
9
- raise "Your router or your router adapter doesn't support this method"
9
+ raise NotImplementedError, "Your router or your router adapter doesn't support this method"
10
10
  end
11
11
  end
12
12
 
@@ -1,7 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require "rango"
4
- require "rango/logger"
5
4
  require "rango/controller"
6
5
  require "rango/environments"
7
6
  require "rango/rack/middlewares/basic"
@@ -1,11 +1,11 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require "tilt"
4
- require "rubyexts/mixins/chainable"
4
+ require "rango/mixins/chainable"
5
5
 
6
6
  module Tilt
7
7
  ErubisTemplate.class_eval do
8
- extend RubyExts::Chainable
8
+ extend Chainable
9
9
  chainable do
10
10
  def initialize_engine
11
11
  super
@@ -15,7 +15,7 @@ module Tilt
15
15
  end
16
16
 
17
17
  HamlTemplate.class_eval do
18
- extend RubyExts::Chainable
18
+ extend Chainable
19
19
  chainable do
20
20
  def initialize_engine
21
21
  super