alfa 0.0.2.pre → 0.0.4.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,36 +1,56 @@
1
1
  require 'alfa/logger'
2
2
  require 'alfa/config'
3
+ require 'alfa/exceptions'
4
+
5
+ Encoding.default_external = 'utf-8'
6
+ Encoding.default_internal = 'utf-8'
3
7
 
4
8
  module Alfa
9
+
10
+ # Dirty hack. Using constant-hash to store values. Ruby forbid dynamically change constants, but it allow change items of constant-structs
11
+ # 1st using - in rake tasks (see self.load_tasks)
12
+ VARS = {}
13
+
5
14
  class Application
6
15
  private_class_method :new
7
16
 
8
- include Alfa::ClassInheritance
17
+ include ClassInheritance
9
18
  inheritable_attributes :config
10
19
 
11
20
  @config = Alfa::Config.new
12
21
 
13
- def self.config args=nil
14
- return @config if args.nil?
15
- @config.merge args
22
+ def self.config(kwargs={})
23
+ @config.merge! kwargs
16
24
  end
17
25
 
26
+
18
27
  def self.init!
19
- @log_file = File.open(File.join(@config[:log][:file]), File::WRONLY | File::APPEND | File::CREAT)
20
- @logger = Alfa::Logger.new(@log_file)
21
- str = "Application (pid=#{$$}) started at #{DateTime.now}"
22
- @logger.info "#{'='*str.length}\n#{str}"
23
- @logger.info " PROJECT_ROOT: #{@config[:project_root]}"
24
- @logger.info " DOCUMENT_ROOT: #{@config[:document_root]}\n"
25
- @log_file.flush
26
- ObjectSpace.define_finalizer(@logger, Proc.new {@logger.info "Application (pid=#{$$}) stopped at #{DateTime.now}\n\n"})
27
- @config[:db].each_value { |db| db.loggers = [@logger] }
28
+ self.verify_config
29
+ if @config[:log][:file]
30
+ @log_file = File.open(@config[:log][:file], File::WRONLY | File::APPEND | File::CREAT)
31
+ @logger = Alfa::Logger.new(@log_file)
32
+ str = "Application (pid=#{$$}) started at #{DateTime.now}"
33
+ @logger.info "#{'='*str.length}\n#{str}"
34
+ @logger.info " PROJECT_ROOT: #{@config[:project_root]}"
35
+ @logger.info " DOCUMENT_ROOT: #{@config[:document_root]}\n"
36
+ @log_file.flush
37
+ ObjectSpace.define_finalizer(@logger, Proc.new {@logger.info "Application (pid=#{$$}) stopped at #{DateTime.now}\n\n"})
38
+ @config[:db].each_value { |db| db[:instance].loggers = [@logger] }
39
+ else
40
+ @logger = Alfa::NullLogger.new
41
+ end
28
42
  @inited = true
29
43
  end
30
44
 
31
- def self.load_database path
32
- Kernel.require path
45
+
46
+ def self.load_tasks
47
+ VARS[:rakeapp_instance] = self
48
+ require 'alfa/tasks'
33
49
  end
34
50
 
51
+
52
+ def self.verify_config
53
+ raise Exceptions::E001 unless @config[:project_root]
54
+ end
35
55
  end
36
56
  end
@@ -6,8 +6,5 @@ require 'alfa/tfile'
6
6
 
7
7
  module Alfa
8
8
  class CliApplication < Alfa::Application
9
- def self.load_tasks
10
- Kernel.load 'alfa/tasks/assets.rake'
11
- end
12
9
  end
13
10
  end
data/lib/alfa/config.rb CHANGED
@@ -1,11 +1,24 @@
1
1
  module Alfa
2
2
  class Config < ::Hash
3
- #attr_accessor :project_root, :document_root, :db
4
3
 
5
4
  def initialize
6
5
  self[:db] = {}
7
6
  self[:log] = {}
8
7
  end
9
8
 
9
+ def []=(key, value)
10
+ if [:db, :log].include? key
11
+ raise "key :#{key} should include Enumerable" unless value.class.included_modules.include? Enumerable
12
+ end
13
+ super
14
+ end
15
+
16
+ def store(key, value)
17
+ if [:db, :log].include? key
18
+ raise "key :#{key} should include Enumerable" unless value.class.included_modules.include? Enumerable
19
+ end
20
+ super
21
+ end
22
+
10
23
  end
11
24
  end
@@ -1,4 +1,12 @@
1
1
  module Alfa
2
- class RouteException404 < StandardError
2
+ module Exceptions
3
+ # Route not found
4
+ class Route404 < StandardError; end
5
+
6
+ # Application's config.project_root required
7
+ class E001 < StandardError; end
8
+
9
+ # WebApplication's config.document_root required
10
+ class E002 < StandardError; end
3
11
  end
4
12
  end
data/lib/alfa/logger.rb CHANGED
@@ -1,21 +1,41 @@
1
1
  require 'logger'
2
+ require 'weakref'
3
+ require 'alfa/support'
2
4
 
3
5
  module Alfa
6
+ class NullLogger
7
+ def portion(*args, &block)
8
+ l = WeakRef.new(self.class.new)
9
+ yield(l)
10
+ end
11
+
12
+ def info(*args)
13
+ end
14
+
15
+ def <<(*args)
16
+ end
17
+ end
18
+
19
+
4
20
  class Logger < ::Logger
5
21
 
6
22
  def initialize(logdev, shift_age = 0, shift_size = 1048576)
7
23
  super
24
+ @logdev = logdev
8
25
  @formatter = Formatter.new
9
26
  end
10
27
 
11
- def portion(&block)
28
+ def portion(kwargs={}, &block)
12
29
  io = VirtualIO.new
13
- l = ::Logger.new(io)
30
+ l = Logger.new(io)
14
31
  l.formatter = @formatter
15
32
  yield(l)
16
33
  self << io.join
17
- l = nil
18
- io = nil
34
+ flush if kwargs[:sync]
35
+ end
36
+
37
+ def flush
38
+ @logdev.flush #if @logdev.respond_to?(:flush)
19
39
  end
20
40
 
21
41
  private
@@ -27,6 +47,9 @@ module Alfa
27
47
 
28
48
  def close
29
49
  end
50
+
51
+ def flush
52
+ end
30
53
  end
31
54
 
32
55
  class Formatter < ::Logger::Formatter
data/lib/alfa/router.rb CHANGED
@@ -1,6 +1,10 @@
1
1
  module Alfa
2
2
  class Router
3
3
 
4
+ class << self
5
+ attr_accessor :apps_dir
6
+ end
7
+
4
8
  # initialize class variables
5
9
  @routes = []
6
10
  @cursor = @routes
@@ -11,10 +15,6 @@ module Alfa
11
15
  def self.call &block
12
16
  end
13
17
 
14
- def self.set_apps_dir dir
15
- @apps_dir = dir
16
- end
17
-
18
18
 
19
19
  def self.context options = {}, &block
20
20
  new_routes_container = []
@@ -32,7 +32,8 @@ module Alfa
32
32
 
33
33
 
34
34
  def self.reset
35
- @routes = []
35
+ @routes.clear
36
+ @apps_dir = nil
36
37
  end
37
38
 
38
39
  # Set routes
@@ -61,18 +62,31 @@ module Alfa
61
62
  # mount '/admin/', :admin
62
63
  # all requests to site.com/ and nested (site.com/*) will be sent to application 'frontend' (/apps/frontend)
63
64
  # mount '/', :frontend
64
- def self.mount path, app, options = {}
65
+ def self.mount path, app = nil, options = {}
66
+ if path.is_a?(Hash) && app == nil
67
+ path, a = path.first.to_a
68
+ app = a.to_sym
69
+ end
65
70
  @mounts << {:path => path, :app => app, :options => options}
66
71
  if @apps_dir
67
72
  self.context :app => app do
68
- require File.join(@apps_dir, app.to_s, 'routes')
73
+ Kernel.load File.join(@apps_dir, app.to_s, 'routes.rb')
69
74
  end
70
75
  end
71
76
  end
72
77
 
73
78
  # Sets route rule
74
79
  def self.route rule, options = {}
75
- @cursor << {:rule => rule, :options => options}
80
+ if rule.is_a?(Hash)
81
+ r, o = rule.to_a.first
82
+ options = rule.dup
83
+ options.delete(r)
84
+ raise 'Expected hash rule have controller#action format' unless o.include? '#'
85
+ c, a = o.split('#')
86
+ @cursor << {:rule => r, :options => options.merge({:controller => c.to_sym, :action => a.to_sym})}
87
+ else
88
+ @cursor << {:rule => rule, :options => options}
89
+ end
76
90
  #puts "set rule '#{rule}', routes = #{@routes}"
77
91
  end
78
92
 
@@ -106,7 +120,7 @@ module Alfa
106
120
  rule_segments.zip(url_segments).each do |rule_segment, url_segment|
107
121
  skip_flag = true if rule_segment == '**'
108
122
  if rule_segment =~ /^:[a-z]+\w*$/i && url_segment =~ /^[a-z0-9_]+$/
109
- pares[rule_segment[1..-1].to_sym] = url_segment
123
+ pares[rule_segment[1..-1].to_sym] = url_segment.to_sym
110
124
  elsif (rule_segment == url_segment) || (rule_segment == '*' && url_segment =~ /^[a-z0-9_]+$/) || (rule_segment == nil && skip_flag) || rule_segment == '**'
111
125
  else
112
126
  fail_flag = true
@@ -140,7 +154,7 @@ module Alfa
140
154
  r[:options][:app] = route[:context][:app][:app]
141
155
  return r, params if is_success
142
156
  end
143
- raise Alfa::RouteException404
157
+ raise Alfa::Exceptions::Route404
144
158
  end
145
159
  # else - ???
146
160
  else
@@ -148,7 +162,7 @@ module Alfa
148
162
  return route, params if is_success
149
163
  end
150
164
  end
151
- raise Alfa::RouteException404
165
+ raise Alfa::Exceptions::Route404
152
166
  end
153
167
 
154
168
  end
data/lib/alfa/support.rb CHANGED
@@ -19,7 +19,7 @@ module Alfa
19
19
  @inheritable_attributes
20
20
  end
21
21
 
22
- def inherited(subclass)
22
+ def inherited(subclass) # ruby hook
23
23
  @inheritable_attributes.each do |inheritable_attribute|
24
24
  instance_var = "@#{inheritable_attribute}"
25
25
  subclass.instance_variable_set(instance_var, instance_variable_get(instance_var))
@@ -28,10 +28,17 @@ module Alfa
28
28
  end
29
29
  end
30
30
 
31
- class Support
32
- def self.capitalize_name arg
31
+ module Support
32
+ extend self
33
+
34
+ def capitalize_name(arg)
33
35
  arg.to_s.split('/').last.split('_').map(&:capitalize).join
34
36
  end
37
+
38
+ def parse_arguments(*arguments)
39
+ return arguments[0..-2], arguments.last if arguments.last.is_a?(Hash)
40
+ return arguments, {}
41
+ end
35
42
  end
36
43
 
37
44
  end
data/lib/alfa/tasks.rb ADDED
@@ -0,0 +1,2 @@
1
+ load 'alfa/tasks/assets.rake'
2
+ load 'alfa/tasks/db.rake'
data/lib/alfa/tfile.rb CHANGED
@@ -15,11 +15,10 @@ module Alfa
15
15
  def allowed_options
16
16
  @allowed_options ||= %w(absfile projfile url).map(&:to_sym)
17
17
  end
18
- def inherited(subclass)
18
+ def inherited(subclass) # ruby hook
19
19
  subclass.instance_variable_set(:@project_root, instance_variable_get(:@project_root))
20
20
  subclass.instance_variable_set(:@document_root, instance_variable_get(:@document_root))
21
21
  end
22
-
23
22
  end
24
23
 
25
24
  attr_reader :absfile, :absdir, :basename, :dirname
@@ -10,9 +10,6 @@ require 'ruty/bugfix'
10
10
  require 'ruty/upgrade'
11
11
  require 'ruty/tags/resources'
12
12
 
13
- Encoding.default_external='utf-8'
14
- Encoding.default_internal='utf-8'
15
-
16
13
  module Alfa
17
14
  class WebApplication < Alfa::Application
18
15
 
@@ -26,9 +23,10 @@ module Alfa
26
23
  end
27
24
 
28
25
  def self.init!
29
- Alfa::Router.set_apps_dir File.join(PROJECT_ROOT, 'apps')
30
- require File.join(PROJECT_ROOT, 'config/routes')
31
26
  super
27
+ Alfa::Router.reset
28
+ Alfa::Router.apps_dir = File.join(@config[:project_root], 'apps')
29
+ load File.join(@config[:project_root], 'config/routes.rb')
32
30
  end
33
31
 
34
32
  # main rack routine
@@ -37,8 +35,8 @@ module Alfa
37
35
  response_code = nil # required for store context inside @logger.portion
38
36
  headers = {} # required for store context inside @logger.portion
39
37
  body = nil # required for store context inside @logger.portion
40
- @logger.portion do |l|
41
- @config[:db].each_value { |db| db.loggers = [l] }
38
+ @logger.portion(:sync=>true) do |l|
39
+ @config[:db].each_value { |db| db[:instance].loggers = [l] }
42
40
  @env = env
43
41
  @bputs = []
44
42
  headers = {"Content-Type" => 'text/html; charset=utf-8'}
@@ -50,7 +48,7 @@ module Alfa
50
48
  #@logger.info " HTTP_ACCEPT_LANGUAGE: #{env['HTTP_ACCEPT_LANGUAGE']}"
51
49
  #@logger.info " PATH_INFO: #{env['PATH_INFO']}"
52
50
  response_code = 200
53
- route, params = self.routes.find_route @env['PATH_INFO']
51
+ route, params = self.routes.find_route(@env['PATH_INFO'])
54
52
  t_sym = route[:options].has_key?(:type) ? route[:options][:type] : :default
55
53
  if t_sym == :asset
56
54
  body = File.read(File.expand_path('../../../assets/' + params[:path], __FILE__))
@@ -66,8 +64,7 @@ module Alfa
66
64
  c_sym = route[:options].has_key?(:controller) ? route[:options][:controller] : params[:controller]
67
65
  a_sym = route[:options].has_key?(:action) ? route[:options][:action] : params[:action]
68
66
  l_sym = route[:options].has_key?(:layout) ? route[:options][:layout] : :default
69
- controller = self.invoke_controller(app_sym, c_sym)
70
- raise Alfa::RouteException404 unless controller.public_methods.include?(a_sym)
67
+ controller = self.invoke_controller_check_action(app_sym, c_sym, a_sym)
71
68
  controller.__send__(a_sym)
72
69
  data = controller._instance_variables_hash
73
70
  Ruty::Tags::RequireStyle.clean_cache
@@ -75,14 +72,14 @@ module Alfa
75
72
  body = self.render_layout(app_sym.to_s, l_sym.to_s + '.tpl', {body: content})
76
73
  headers = {"Content-Type" => 'text/html; charset=utf-8'}
77
74
  end
78
- rescue Alfa::RouteException404 => e
75
+ rescue Alfa::Exceptions::Route404 => e
79
76
  response_code = 404
80
77
  body = 'Url not found<br>urls map:<br>'
81
78
  body += self.routes.instance_variable_get(:@routes).inspect
82
79
  l.info "404: Url not found (#{e.message})"
83
80
  rescue Exception => e
84
81
  response_code = 500
85
- body = "Error occured: #{e.message} at #{e.backtrace.first}<br>Full backtrace:<br>#{e.backtrace.join("<br>")}"
82
+ body = "Error occured: #{e.message} at #{e.backtrace.first}<br>Full backtrace:<br>\n#{e.backtrace.join("<br>\n")}"
86
83
  end
87
84
  if t_sym == :default
88
85
  #debug_info = '<hr>Queries:<br>' + @logger.logs.map { |log|
@@ -96,8 +93,6 @@ module Alfa
96
93
  l.info "RESPONSE: #{response_code} (#{sprintf('%.4f', Time.now - start_time)} sec)"
97
94
  l << "\n"
98
95
  end
99
- @log_file.flush
100
- #@logger = nil
101
96
  return [response_code, headers, [body, @bputs.join('<br>')]]
102
97
  end
103
98
 
@@ -114,10 +109,18 @@ module Alfa
114
109
 
115
110
  # private section
116
111
 
117
- def self.invoke_controller application, controller
112
+ def self.verify_config
113
+ super
114
+ raise Exceptions::E002.new unless @config[:document_root]
115
+ end
116
+
117
+ def self.invoke_controller_check_action application, controller, action
118
118
  @controllers ||= {}
119
- require File.join(PROJECT_ROOT, 'apps', application.to_s, 'controllers', controller.to_s)
120
- @controllers[[application, controller]] ||= Kernel.const_get(Alfa::Support.capitalize_name(controller)+'Controller').new
119
+ require File.join(@config[:project_root], 'apps', application.to_s, 'controllers', controller.to_s)
120
+ # @todo put klass to controllers cache
121
+ klass = Kernel.const_get(Alfa::Support.capitalize_name(controller)+'Controller')
122
+ raise Exceptions::Route404 unless klass.instance_methods(false).include?(action)
123
+ @controllers[[application, controller]] ||= klass.new
121
124
  end
122
125
 
123
126
  def self.render_template app, template, data = {}
@@ -131,7 +134,7 @@ module Alfa
131
134
  end
132
135
 
133
136
  def self.loader
134
- @loader ||= Ruty::Loaders::Filesystem.new(:dirname => File.join(PROJECT_ROOT, 'apps'))
137
+ @loader ||= Ruty::Loaders::Filesystem.new(:dirname => File.join(@config[:project_root], 'apps'))
135
138
  end
136
139
 
137
140
  end
@@ -0,0 +1,4 @@
1
+ Alfa::Router.draw do
2
+ route '/', :controller => :main, :action => :index, :layout => :index
3
+ route '/:controller', :action => :index
4
+ end
@@ -0,0 +1,6 @@
1
+ Alfa::Router.draw do
2
+ route '/', :controller => :main, :action => :index, :layout => :index
3
+ route '/:action', :controller => :main, :layout => :internal
4
+ route '/:controller/:action', :layout => :internal
5
+ route '/:controller/:action/:id', :layout => :internal
6
+ end
@@ -0,0 +1,4 @@
1
+ Alfa::Router.draw do
2
+ route '/' => 'main#index', :layout => :index
3
+ route '/:controller', :action => :index
4
+ end
@@ -0,0 +1,6 @@
1
+ Alfa::Router.draw do
2
+ route '/' => 'main#index', :layout => :index
3
+ route '/:action', :controller => :main, :layout => :internal
4
+ route '/:controller/:action', :layout => :internal
5
+ route '/:controller/:action/:id', :layout => :internal
6
+ end
@@ -0,0 +1,4 @@
1
+ Alfa::Router.draw do
2
+ mount '/admin/' => :backend
3
+ mount '/' => :frontend
4
+ end
@@ -0,0 +1,9 @@
1
+ class KfkController < Alfa::Controller
2
+ def index
3
+
4
+ end
5
+
6
+ def bar
7
+
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ Alfa::WebApplication.routes.draw do
2
+ route '/' => 'kfk#index'
3
+ route '/:action', :controller => :kfk
4
+ end
@@ -0,0 +1,3 @@
1
+ Alfa::WebApplication.routes.draw do
2
+ mount '/' => :frontend
3
+ end
@@ -0,0 +1,38 @@
1
+ require 'test/unit'
2
+ require 'alfa/application'
3
+ require 'alfa/config'
4
+
5
+ class AlfaApplicationTest < Test::Unit::TestCase
6
+ def test_01 # base test
7
+ assert Alfa::VARS.is_a?(Hash), "Alfa::VARS expected to be a Hash"
8
+ assert_raise NoMethodError do
9
+ application = Alfa::Application.new
10
+ end
11
+ assert Alfa::Application.respond_to?(:init!)
12
+ assert Alfa::Application.respond_to?(:load_tasks)
13
+ assert Alfa::Application.respond_to?(:config)
14
+ end
15
+
16
+ def test_02 # Alfa::Application.config
17
+ assert Alfa::Application.config.is_a?(Alfa::Config)
18
+ Alfa::Application.config :foo => 1
19
+ assert_equal(1, Alfa::Application.config[:foo])
20
+ Alfa::Application.config[:bar] = 2
21
+ assert_equal(2, Alfa::Application.config[:bar])
22
+ end
23
+
24
+ # test config.project_root
25
+ def test_03
26
+ assert_raise Alfa::Exceptions::E001, "Application requires config.project_root" do
27
+ Alfa::Application.init!
28
+ end
29
+ assert_raise Alfa::Exceptions::E001, "Application's project_root should not be nil" do
30
+ Alfa::Application.config[:project_root] = nil
31
+ Alfa::Application.init!
32
+ end
33
+ assert_nothing_raised Exception, "Application should silent init when project_root is set" do
34
+ Alfa::Application.config[:project_root] = File.expand_path('../data/test_application', __FILE__)
35
+ Alfa::Application.init!
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,26 @@
1
+ require 'test/unit'
2
+ require 'alfa/config'
3
+
4
+ class AlfaConfigTest < Test::Unit::TestCase
5
+ def test_01
6
+ config = Alfa::Config.new
7
+ assert config.is_a?(Hash)
8
+ assert config[:db].is_a?(Hash)
9
+ assert config[:log].is_a?(Hash)
10
+ assert_raise RuntimeError do
11
+ config[:db] = nil
12
+ end
13
+ assert_raise RuntimeError do
14
+ config.store(:db, nil)
15
+ end
16
+ assert_raise RuntimeError do
17
+ config[:log] = nil
18
+ end
19
+ assert_raise RuntimeError do
20
+ config.store(:log, nil)
21
+ end
22
+ assert_equal({:db=>{}, :log=>{}}, config)
23
+ config[:foo] = 1
24
+ assert_equal({:db=>{}, :log=>{}, :foo=>1}, config)
25
+ end
26
+ end
@@ -0,0 +1,22 @@
1
+ require 'test/unit'
2
+ require 'alfa/controller'
3
+
4
+ class TestAlfaController < Test::Unit::TestCase
5
+ def test_01
6
+ eval <<EOL
7
+ class Z < Alfa::Controller
8
+ def some_action
9
+ @foo = :bar
10
+ end
11
+ def other_action
12
+ @fuu = :baz
13
+ end
14
+ end
15
+ EOL
16
+ z = Z.new
17
+ z.some_action
18
+ assert_equal({:foo=>:bar}, z._instance_variables_hash)
19
+ z.other_action
20
+ assert_equal({:foo=>:bar, :fuu=>:baz}, z._instance_variables_hash)
21
+ end
22
+ end
@@ -0,0 +1,97 @@
1
+ require 'test/unit'
2
+ require 'alfa/logger'
3
+ require 'tempfile'
4
+
5
+ class TestAlfaLogger < Test::Unit::TestCase
6
+ # test of nested Formatter class
7
+ def test_01
8
+ formatter = Alfa::Logger::Formatter.new
9
+ time = Time.now
10
+ progname = 'unknown'
11
+ assert_equal("Hello\n", formatter.call(Logger::Severity::DEBUG, time, progname, 'Hello'))
12
+ assert_equal("Hello\n", formatter.call(Logger::Severity::INFO, time, progname, 'Hello'))
13
+ assert_equal("Hello\n", formatter.call(Logger::Severity::WARN, time, progname, 'Hello'))
14
+ assert_equal("Hello\n", formatter.call(Logger::Severity::ERROR, time, progname, 'Hello'))
15
+ assert_equal("Hello\n", formatter.call(Logger::Severity::FATAL, time, progname, 'Hello'))
16
+ assert_equal("Hello\n", formatter.call(Logger::Severity::UNKNOWN, time, progname, 'Hello'))
17
+ end
18
+
19
+ # test of nested VirtualIO class
20
+ def test_02
21
+ io = Alfa::Logger::VirtualIO.new
22
+ assert io.respond_to?(:write)
23
+ assert io.respond_to?(:close)
24
+ io.write("Hello")
25
+ io.write("World")
26
+ assert_equal(["Hello", "World"], io)
27
+ end
28
+
29
+ # base test with virtual receiver
30
+ def test_03
31
+ io = Alfa::Logger::VirtualIO.new
32
+ logger = Alfa::Logger.new(io)
33
+ logger.info("Hello")
34
+ logger.info("World")
35
+ logger << "zz"
36
+ assert_equal(["Hello\n", "World\n", "zz"], io)
37
+ end
38
+
39
+ # base test with real file
40
+ def test_04
41
+ Tempfile.open('loggertest_04_') do |f|
42
+ logger = Alfa::Logger.new(f)
43
+ logger.info "Hello"
44
+ logger.info "World"
45
+ logger << "zz"
46
+ f.rewind
47
+ assert_equal("Hello\nWorld\nzz", f.read)
48
+ end
49
+ end
50
+
51
+ # simulate 2 threads with virtual receiver
52
+ # threads write to receiver in their close order
53
+ def test_05
54
+ io = Alfa::Logger::VirtualIO.new
55
+ logger = Alfa::Logger.new(io)
56
+ logger.portion do |l1|
57
+ l1.info "Hello"
58
+ logger.portion do |l2|
59
+ l2.info "Baramba"
60
+ l2.info "Caramba!"
61
+ l2 << "\n"
62
+ # first closed thread -> first write to receiver
63
+ end
64
+ l1.info "World"
65
+ l1 << "\n"
66
+ # last closed thread -> last write to receiver
67
+ end
68
+ assert_equal(["Baramba\nCaramba!\n\n", "Hello\nWorld\n\n"], io)
69
+ end
70
+
71
+ # simulate 2 threads with real file
72
+ # threads write to receiver in their close order
73
+ def test_06
74
+ Tempfile.open('loggertest_06_') do |f|
75
+ logger = Alfa::Logger.new(f)
76
+ logger.portion do |l1|
77
+ l1.info "Hello"
78
+ logger.portion do |l2|
79
+ l2.info "Baramba"
80
+ l2.info "Caramba!"
81
+ l2 << "\n"
82
+ # first closed thread -> first write to receiver
83
+ end
84
+ l1.info "World"
85
+ l1 << "\n"
86
+ # last closed thread -> last write to receiver
87
+ end
88
+ f.rewind
89
+ assert_equal("Baramba\nCaramba!\n\nHello\nWorld\n\n", f.read)
90
+ end
91
+ end
92
+
93
+ # NullLogger
94
+ def test_07
95
+ assert Alfa::NullLogger.instance_methods.include?(:portion)
96
+ end
97
+ end
data/test/test_router.rb CHANGED
@@ -5,20 +5,20 @@ class AlfaRouterTest < Test::Unit::TestCase
5
5
  def test_01 # route_match
6
6
  # string rules, positive cases
7
7
  assert_equal([true, {}], Alfa::Router.route_match?('/', '/'))
8
- assert_equal([true, {action: 'foo'}], Alfa::Router.route_match?('/:action', '/foo'))
9
- assert_equal([true, {action: 'foo'}], Alfa::Router.route_match?('/:action/', '/foo/'))
10
- assert_equal([true, {controller: 'foo', action: 'bar'}], Alfa::Router.route_match?('/:controller/:action', '/foo/bar'))
8
+ assert_equal([true, {action: :foo}], Alfa::Router.route_match?('/:action', '/foo'))
9
+ assert_equal([true, {action: :foo}], Alfa::Router.route_match?('/:action/', '/foo/'))
10
+ assert_equal([true, {controller: :foo, action: :bar}], Alfa::Router.route_match?('/:controller/:action', '/foo/bar'))
11
11
  assert_equal([true, {}], Alfa::Router.route_match?('/foo/bar', '/foo/bar'))
12
12
  assert_equal([true, {}], Alfa::Router.route_match?('/*/bar', '/foo/bar'))
13
- assert_equal([true, {action: 'bar'}], Alfa::Router.route_match?('/*/:action', '/foo/bar'))
13
+ assert_equal([true, {action: :bar}], Alfa::Router.route_match?('/*/:action', '/foo/bar'))
14
14
  assert_equal([true, {}], Alfa::Router.route_match?('/**', '/foo/bar'))
15
- assert_equal([true, {controller: 'foo'}], Alfa::Router.route_match?('/:controller/**', '/foo/bar/baz'))
15
+ assert_equal([true, {controller: :foo}], Alfa::Router.route_match?('/:controller/**', '/foo/bar/baz'))
16
16
  assert_equal([true, {path: 'js/jquery/jquery-latest.js', type: :asset}], Alfa::Router.route_match?('/~assets/:path**', '/~assets/js/jquery/jquery-latest.js'))
17
17
  assert_equal([true, {}], Alfa::Router.route_match?('/hello.html', '/hello.html'))
18
18
 
19
19
  # string rules, negative cases
20
- assert_equal([false, {action: 'foo'}], Alfa::Router.route_match?('/:action', '/foo/'))
21
- assert_equal([false, {action: 'foo'}], Alfa::Router.route_match?('/:action/', '/foo'))
20
+ assert_equal([false, {action: :foo}], Alfa::Router.route_match?('/:action', '/foo/'))
21
+ assert_equal([false, {action: :foo}], Alfa::Router.route_match?('/:action/', '/foo'))
22
22
  assert_equal([false, {}], Alfa::Router.route_match?('/foo/bar/', '/foo/bar'))
23
23
  assert_equal([false, {}], Alfa::Router.route_match?('/*', '/foo/bar'))
24
24
  assert_equal([false, {}], Alfa::Router.route_match?('/*/', '/foo/bar'))
@@ -79,6 +79,7 @@ class AlfaRouterTest < Test::Unit::TestCase
79
79
 
80
80
  # Checks right order of draw and mounted rules
81
81
  def test_03 # Router's internal routes struct
82
+ Alfa::Router.reset
82
83
  prepare_router
83
84
  assert_equal(
84
85
  [
@@ -103,30 +104,111 @@ class AlfaRouterTest < Test::Unit::TestCase
103
104
 
104
105
 
105
106
  def test_04 # mount
107
+ Alfa::Router.reset
106
108
  prepare_router
107
109
  #puts Alfa::Router.instance_variable_get(:@routes)
108
110
  assert_equal([{rule: '/hello.html', options: {}}, {}], Alfa::Router.find_route('/hello.html'))
109
111
  assert_equal([{rule: '/', options: {app: :frontend, controller: :main, action: :index, layout: :index}}, {}], Alfa::Router.find_route('/'))
110
- assert_equal([{rule: '/:action', options: {app: :frontend, controller: :main, layout: :internal}}, {action: 'foo'}], Alfa::Router.find_route('/foo'))
111
- assert_equal([{rule: '/:controller/:action', options: {app: :frontend, layout: :internal}}, {controller: 'foo', action: 'bar'}], Alfa::Router.find_route('/foo/bar'))
112
- assert_equal([{rule: '/:controller/:action/:id', options: {app: :frontend, layout: :internal}}, {controller: 'foo', action: 'bar', id: '8'}], Alfa::Router.find_route('/foo/bar/8'))
112
+ assert_equal([{rule: '/:action', options: {app: :frontend, controller: :main, layout: :internal}}, {action: :foo}], Alfa::Router.find_route('/foo'))
113
+ assert_equal([{rule: '/:controller/:action', options: {app: :frontend, layout: :internal}}, {controller: :foo, action: :bar}], Alfa::Router.find_route('/foo/bar'))
114
+ assert_equal([{rule: '/:controller/:action/:id', options: {app: :frontend, layout: :internal}}, {controller: :foo, action: :bar, id: :'8'}], Alfa::Router.find_route('/foo/bar/8'))
113
115
  assert_equal([{rule: '/', options: {app: :admin, controller: :main, action: :index, layout: :admin}}, {}], Alfa::Router.find_route('/admin/'))
114
- assert_equal([{rule: '/:controller', options: {app: :admin, action: :index}}, {controller: 'foo'}], Alfa::Router.find_route('/admin/foo'))
115
- assert_raise Alfa::RouteException404 do
116
+ assert_equal([{rule: '/:controller', options: {app: :admin, action: :index}}, {controller: :foo}], Alfa::Router.find_route('/admin/foo'))
117
+ assert_raise Alfa::Exceptions::Route404 do
116
118
  Alfa::Router.find_route('/admin/foo/bar')
117
119
  end
118
120
  assert_equal([{rule: '/~assets/:path**', options: {type: :asset}}, {path: 'js/jquery/jquery-latest.js', type: :asset}], Alfa::Router.find_route('/~assets/js/jquery/jquery-latest.js'))
119
121
  #assert_equal([{rule: '/:controller/:action/:id', options: {app: :backend, layout: :internal}}, {controller: 'foo', action: 'bar', id: '8'}], Alfa::Router.find_route('/foo/bar/8'))
120
122
  end
121
123
 
124
+ # Checks right order of draw and mounted rules
125
+ def test_05
126
+ Alfa::Router.reset
127
+ Alfa::Router.apps_dir = File.expand_path('../data/test_router/1/apps', __FILE__)
128
+ load File.expand_path('../data/test_router/1/config/routes.rb', __FILE__)
129
+ assert_equal(
130
+ [
131
+ {:rule=>"/~assets/:path**", :options=>{:type=>:asset}},
132
+ {:context=>{:app=>{:path=>"/admin/", :app=>:backend, :options=>{}}},
133
+ :routes=>[
134
+ {:rule=>"/", :options=>{:controller=>:main, :action=>:index, :layout=>:index}},
135
+ {:rule=>"/:controller", :options=>{:action=>:index}}
136
+ ]},
137
+ {:context=>{:app=>{:path=>"/", :app=>:frontend, :options=>{}}},
138
+ :routes=>[
139
+ {:rule=>"/", :options=>{:controller=>:main, :action=>:index, :layout=>:index}},
140
+ {:rule=>"/:action", :options=>{:controller=>:main, :layout=>:internal}},
141
+ {:rule=>"/:controller/:action", :options=>{:layout=>:internal}},
142
+ {:rule=>"/:controller/:action/:id", :options=>{:layout=>:internal}},
143
+ ]},
144
+ ],
145
+ Alfa::Router.instance_variable_get(:@routes)
146
+ )
147
+ end
148
+
122
149
  # this test loads routes.rb files from data/test_router directory to simulate real project skeletron
123
- def test_05 # load_from_files
150
+ def test_06 # load_from_files
151
+ Alfa::Router.reset
152
+ Alfa::Router.apps_dir = File.expand_path('../data/test_router/1/apps', __FILE__)
153
+ load File.expand_path('../data/test_router/1/config/routes.rb', __FILE__)
154
+ #puts Alfa::Router.instance_variable_get(:@routes).inspect
124
155
  assert_equal([{rule: '/', options: {app: :frontend, controller: :main, action: :index, layout: :index}}, {}], Alfa::Router.find_route('/'))
125
- assert_equal([{rule: '/:action', options: {app: :frontend, controller: :main, layout: :internal}}, {action: 'foo'}], Alfa::Router.find_route('/foo'))
126
- assert_equal([{rule: '/:controller/:action', options: {app: :frontend, layout: :internal}}, {controller: 'foo', action: 'bar'}], Alfa::Router.find_route('/foo/bar'))
127
- assert_equal([{rule: '/:controller/:action/:id', options: {app: :frontend, layout: :internal}}, {controller: 'foo', action: 'bar', id: '8'}], Alfa::Router.find_route('/foo/bar/8'))
128
- assert_equal([{rule: '/', options: {app: :admin, controller: :main, action: :index, layout: :admin}}, {}], Alfa::Router.find_route('/admin/'))
129
- assert_equal([{rule: '/:controller', options: {app: :admin, action: :index}}, {controller: 'foo'}], Alfa::Router.find_route('/admin/foo'))
156
+ assert_equal([{rule: '/:action', options: {app: :frontend, controller: :main, layout: :internal}}, {action: :foo}], Alfa::Router.find_route('/foo'))
157
+ assert_equal([{rule: '/:controller/:action', options: {app: :frontend, layout: :internal}}, {controller: :foo, action: :bar}], Alfa::Router.find_route('/foo/bar'))
158
+ assert_equal([{rule: '/:controller/:action/:id', options: {app: :frontend, layout: :internal}}, {controller: :foo, action: :bar, id: :'8'}], Alfa::Router.find_route('/foo/bar/8'))
159
+ assert_equal([{rule: '/', options: {app: :backend, controller: :main, action: :index, layout: :index}}, {}], Alfa::Router.find_route('/admin/'))
160
+ assert_equal([{rule: '/:controller', options: {app: :backend, action: :index}}, {controller: :foo}], Alfa::Router.find_route('/admin/foo'))
161
+ end
162
+
163
+ # alternative route format 'url' => 'controller#action'
164
+ def test_07
165
+ Alfa::Router.reset
166
+ Alfa::Router.draw do
167
+ route '/' => 'default#index'
168
+ route '/zoo' => 'default#zoo', :layout => :default
169
+ mount '/admin' => :backend
170
+ Alfa::Router.context :app => :backend do
171
+ route '/' => 'kfk#index', :layout => :fantastic
172
+ end
173
+ end
174
+ #puts Alfa::Router.instance_variable_get(:@routes).inspect
175
+ assert_equal(
176
+ [
177
+ {:rule=>"/~assets/:path**", :options=>{:type=>:asset}},
178
+ {:rule=>'/', :options=>{:controller=>:default, :action=>:index}},
179
+ {:rule=>'/zoo', :options=>{:controller=>:default, :action=>:zoo, :layout => :default}},
180
+ {:context=>{:app=>{:path=>'/admin/', :app=>:backend, :options=>{}}},
181
+ :routes=>[
182
+ {:rule=>'/', :options=>{:controller=>:kfk, :action=>:index, :layout=>:fantastic}}
183
+ ]},
184
+ ],
185
+ Alfa::Router.instance_variable_get(:@routes)
186
+ )
130
187
  end
131
188
 
189
+ # alternative route format with real files
190
+ def test_08
191
+ Alfa::Router.reset
192
+ Alfa::Router.apps_dir = File.expand_path('../data/test_router/2/apps', __FILE__)
193
+ load File.expand_path('../data/test_router/2/config/routes.rb', __FILE__)
194
+ assert_equal(
195
+ [
196
+ {:rule=>"/~assets/:path**", :options=>{:type=>:asset}},
197
+ {:context=>{:app=>{:path=>"/admin/", :app=>:backend, :options=>{}}},
198
+ :routes=>[
199
+ {:rule=>"/", :options=>{:controller=>:main, :action=>:index, :layout=>:index}},
200
+ {:rule=>"/:controller", :options=>{:action=>:index}}
201
+ ]},
202
+ {:context=>{:app=>{:path=>"/", :app=>:frontend, :options=>{}}},
203
+ :routes=>[
204
+ {:rule=>"/", :options=>{:controller=>:main, :action=>:index, :layout=>:index}},
205
+ {:rule=>"/:action", :options=>{:controller=>:main, :layout=>:internal}},
206
+ {:rule=>"/:controller/:action", :options=>{:layout=>:internal}},
207
+ {:rule=>"/:controller/:action/:id", :options=>{:layout=>:internal}},
208
+ ]},
209
+ ],
210
+ Alfa::Router.instance_variable_get(:@routes)
211
+ )
212
+ #puts Alfa::Router.instance_variable_get(:@routes).inspect
213
+ end
132
214
  end
data/test/test_support.rb CHANGED
@@ -23,4 +23,16 @@ class AlfaSupportTest < Test::Unit::TestCase
23
23
  assert_equal('localhost', DB1.host)
24
24
  assert_equal('otherhost', DB2.host)
25
25
  end
26
+
27
+ def test_parse_arguments
28
+ assert_equal([[], {}], Alfa::Support.parse_arguments())
29
+ assert_equal([[1, 2], {}], Alfa::Support.parse_arguments(1, 2))
30
+ assert_equal([[1, 2], {3=>4}], Alfa::Support.parse_arguments(1, 2, 3=>4))
31
+ assert_equal([[1, 2], {3=>4}], Alfa::Support.parse_arguments(1, 2, {3=>4}))
32
+ assert_equal([[], {3=>4}], Alfa::Support.parse_arguments(3=>4))
33
+ assert_equal([[1, 2], {3=>4, 5=>6}], Alfa::Support.parse_arguments(1, 2, 3=>4, 5=>6))
34
+ assert_equal([[], {3=>4, 5=>6}], Alfa::Support.parse_arguments(3=>4, 5=>6))
35
+ assert_equal([[[]], {}], Alfa::Support.parse_arguments([]))
36
+ assert_equal([[], {}], Alfa::Support.parse_arguments({}))
37
+ end
26
38
  end
@@ -0,0 +1,40 @@
1
+ require 'test/unit'
2
+ require 'alfa/web_application'
3
+
4
+ class TestAlfaWebApplication < Test::Unit::TestCase
5
+ # basics
6
+ def test_01
7
+ assert Alfa::WebApplication.respond_to?(:call), "WebApplication should be callable for Rack"
8
+ assert Alfa::WebApplication.ancestors.include?(Alfa::Application), "WebApplication should be subclass of Application"
9
+ end
10
+
11
+
12
+ def test_02
13
+ Alfa::WebApplication.config[:project_root] = File.expand_path('../data/test_web_application', __FILE__)
14
+ assert_raise Alfa::Exceptions::E002, "WebApplication requires config.document_root" do
15
+ Alfa::WebApplication.config.delete(:document_root)
16
+ Alfa::WebApplication.init!
17
+ end
18
+ assert_raise Alfa::Exceptions::E002, "WebApplication's document_root should not be nil" do
19
+ Alfa::WebApplication.config[:document_root] = nil
20
+ Alfa::WebApplication.init!
21
+ end
22
+ assert_nothing_raised Exception do
23
+ Alfa::WebApplication.config[:document_root] = File.expand_path('../data/test_web_application/public', __FILE__)
24
+ Alfa::WebApplication.init!
25
+ end
26
+ end
27
+
28
+
29
+ def test_03
30
+ Alfa::WebApplication.config[:project_root] = File.expand_path('../data/test_web_application', __FILE__)
31
+ Alfa::WebApplication.config[:document_root] = File.expand_path('../data/test_web_application/public', __FILE__)
32
+ Alfa::WebApplication.init!
33
+ #puts Alfa::Router.instance_variable_get(:@routes).inspect
34
+ assert_equal(200, Alfa::WebApplication.call({'PATH_INFO' => '/'})[0])
35
+ assert_equal(404, Alfa::WebApplication.call({'PATH_INFO' => '/404'})[0])
36
+ assert_equal(200, Alfa::WebApplication.call({'PATH_INFO' => '/bar'})[0])
37
+ assert_equal(404, Alfa::WebApplication.call({'PATH_INFO' => '/methods'})[0])
38
+ assert_equal(404, Alfa::WebApplication.call({'PATH_INFO' => '/inspect'})[0])
39
+ end
40
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alfa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2.pre
4
+ version: 0.0.4.pre
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-15 00:00:00.000000000 Z
12
+ date: 2012-12-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rvm
@@ -115,32 +115,46 @@ extra_rdoc_files: []
115
115
  files:
116
116
  - lib/alfa/commands/new.rb
117
117
  - lib/alfa/database/mysql.rb
118
- - lib/alfa/exceptions.rb
119
118
  - lib/alfa/models/base.rb
120
119
  - lib/alfa/models/base_sql.rb
121
120
  - lib/alfa/models/dummy.rb
122
121
  - lib/alfa/models/mysql.rb
123
- - lib/alfa/application.rb
124
- - lib/alfa/cli_application.rb
125
- - lib/alfa/config.rb
126
122
  - lib/alfa/controller.rb
127
123
  - lib/alfa/database.rb
128
- - lib/alfa/logger.rb
129
124
  - lib/alfa/models.rb
130
125
  - lib/alfa/query_logger.rb
126
+ - lib/alfa/application.rb
127
+ - lib/alfa/cli_application.rb
128
+ - lib/alfa/config.rb
129
+ - lib/alfa/exceptions.rb
130
+ - lib/alfa/logger.rb
131
+ - lib/alfa/router.rb
131
132
  - lib/alfa/support.rb
133
+ - lib/alfa/tasks.rb
132
134
  - lib/alfa/tfile.rb
133
- - lib/alfa/router.rb
134
135
  - lib/alfa/web_application.rb
135
136
  - lib/ruty/tags/resources.rb
136
137
  - lib/ruty/bugfix.rb
137
138
  - lib/ruty/upgrade.rb
138
139
  - lib/alfa.rb
139
140
  - test/test_alfa.rb
140
- - test/test_support.rb
141
141
  - test/test_tfile.rb
142
- - test/data/test_router/config/routes.rb
142
+ - test/test_controller.rb
143
+ - test/test_logger.rb
143
144
  - test/test_router.rb
145
+ - test/test_support.rb
146
+ - test/test_web_application.rb
147
+ - test/data/test_router/1/apps/backend/routes.rb
148
+ - test/data/test_router/1/apps/frontend/routes.rb
149
+ - test/data/test_router/1/config/routes.rb
150
+ - test/data/test_router/2/apps/backend/routes.rb
151
+ - test/data/test_router/2/apps/frontend/routes.rb
152
+ - test/data/test_router/2/config/routes.rb
153
+ - test/data/test_web_application/apps/frontend/controllers/kfk.rb
154
+ - test/data/test_web_application/apps/frontend/routes.rb
155
+ - test/data/test_web_application/config/routes.rb
156
+ - test/test_application.rb
157
+ - test/test_config.rb
144
158
  - assets/css/960gs/960.css
145
159
  - assets/css/960gs/960_12_col.css
146
160
  - assets/css/960gs/960_12_col_rtl.css