alfa 0.0.2.pre → 0.0.4.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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