ruil 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,43 @@
1
+ # module Ruil
2
+
3
+ # class SessionWidget < Ruil::Widget
4
+
5
+ # # Initialize a new RuilSessionWidget
6
+ # def initialize(options = {})
7
+ # if Hash === options
8
+ # # Set @path_prefix
9
+ # @path_prefix = options[:path_prefix] || "/session_widget/"
10
+ # # Set @logout_redirects_to
11
+ # @logout_redirects_to = options[:logout_redirects_to] || "/front.html"
12
+ # # Set @users_collection
13
+ # @users_collection = options[:users_collection]
14
+ # if @users_collection.nil?
15
+ # if defined?(DB).nil?
16
+ # raise "DB undefined"
17
+ # else
18
+ # @users_collection = DB['users']
19
+ # end
20
+ # end
21
+ # end
22
+ # super
23
+ # end
24
+
25
+ # def setup_actions
26
+ # render "stylesheet", "stylesheet"
27
+ # render "script", "script"
28
+ # redirect "logout", @logout_redirects_to do
29
+ # # Clean session
30
+ # end
31
+ # render "login", "login" do
32
+ # # Authenticate
33
+ # end
34
+ # render "request", "request" do
35
+ # end
36
+ # render "check", "check" do
37
+ # # Check code
38
+ # end
39
+ # render "update", "update" do
40
+ # end
41
+ # end
42
+
43
+ # end
@@ -0,0 +1,63 @@
1
+ require 'rubygems'
2
+ require 'rack'
3
+ require 'ruil/register'
4
+
5
+
6
+ module Ruil
7
+
8
+ # {Ruil::StaticResource} objects answer requests with static files.
9
+ class StaticResource
10
+
11
+ # Initialize a new {Ruil::StaticResource}.
12
+ #
13
+ # @param authorizer [lambda(Ruil::Request)]
14
+ # A procedure that checks if the user is allowed to access the resource.
15
+ def initialize(authorizer = nil, &block)
16
+ # Setup
17
+ @authorizer = authorizer
18
+ @files = {}
19
+ yield self if block_given?
20
+ # Register
21
+ Ruil::Register << self
22
+ end
23
+
24
+ # Methods that a resource responds.
25
+ #
26
+ # @return [Array<String>]
27
+ def request_methods
28
+ ['GET']
29
+ end
30
+
31
+ # Add a static file
32
+ #
33
+ # @param file_name [String] the path in the file system.
34
+ # @param file_uri [String] the path from client request.
35
+ # @param content_type [String] the mime type.
36
+ def add(file_name, file_uri, content_type)
37
+ file = File.new(file_name)
38
+ body = file.read
39
+ file.close
40
+ @files[file_uri] = {
41
+ :body => [body],
42
+ :content_type => content_type
43
+ }
44
+ end
45
+
46
+ # Respond a request
47
+ #
48
+ # @param request [Rack::Request] a request to the resource.
49
+ # @return [Rack::Response] a response for the request.
50
+ def call(rack_request)
51
+ path_info = rack_request.path_info
52
+ file = @files[path_info]
53
+ return false if file.nil?
54
+ unless @authorizer.nil?
55
+ request = Ruil::Request.new(rack_request)
56
+ return @autorizer.unauthorized unless @authorizer.authorize(request)
57
+ end
58
+ Rack::Response.new(file[:body], 200, {'Content-Type' => file[:content_type]})
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -0,0 +1,39 @@
1
+ # module Ruil
2
+
3
+ # class Widget
4
+ # def initialize(options = {})
5
+ # if Hash === options
6
+ # @templates_dir = options[:templates_dir]
7
+ # if @templates_dir.nil?
8
+ # if defined?(APPLICATION_PATH).nil?
9
+ # raise "APPLICATION_PATH is undefinded"
10
+ # else
11
+ # @templates_dir = File.join(APPLICATION_PATH, "dynamic", "templates", "session_widget")
12
+ # end
13
+ # end
14
+ # end
15
+ # setup_actions
16
+ # end
17
+
18
+ # def setup_actions
19
+ # end
20
+
21
+ # def render(method, url_pattern_suffix, template, layout = nil)
22
+ # Ruil::Resource.new(method, "#{@url_pattern_prefix}/#{url_pattern_suffix}", layout) do |resource|
23
+ # Dir[File.join(@templates_dir, "#{template}.*.*.*")].each do |file|
24
+ # resource << Ruil::Template.new(file, layout) if /\.(html|xhtml|css|js)$/ === file
25
+ # end
26
+ # if block_given?
27
+ # resource.content_generator = Proc.new { |e| yield e }
28
+ # end
29
+ # end
30
+ # end
31
+
32
+ # def redirect(request_methods, url_pattern_suffix, redirect_to)
33
+ # Ruil::Register << Ruil::Redirector.new(request_methods, redirect_to) do |env|
34
+ # yield env if block_given?
35
+ # end
36
+ # end
37
+ # end
38
+
39
+ # end
data/lib/ruil.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'rack'
2
+
3
+ Dir[File.dirname(File.expand_path(__FILE__)) + '/**/*.rb'].each do |f|
4
+ require f
5
+ end
data/rakefile CHANGED
@@ -1,16 +1,23 @@
1
+ # -*- coding: utf-8 -*-
1
2
  require 'rubygems'
2
3
  require 'rake'
3
- require 'spec/rake/spectask'
4
- require 'rake/rdoctask'
4
+ require 'rspec'
5
+ require 'rspec/core/rake_task'
6
+ require 'yard'
7
+ require 'rcov'
5
8
 
6
- desc 'Default: run rspec tests.'
7
- task :default => :spec
9
+ task :default => :specs
8
10
 
9
- desc 'Run all tests'
10
- Spec::Rake::SpecTask.new(:spec) do |t|
11
- t.spec_files = Dir.glob('test/*_test.rb')
12
- t.spec_opts << '--format specdoc'
11
+ desc 'Run all specs'
12
+ RSpec::Core::RakeTask.new(:specs) do |t|
13
+ t.rspec_opts = ["--colour", "--format", "documentation"]
14
+ end
15
+
16
+ desc 'Coverage for all specs'
17
+ RSpec::Core::RakeTask.new(:rcov) do |t|
13
18
  t.rcov = true
19
+ t.rcov_opts = %q[--exclude "spec"]
20
+ t.verbose = true
14
21
  end
15
22
 
16
23
  begin
@@ -20,7 +27,7 @@ begin
20
27
  gemspec.authors = ["Daniel Hernández"]
21
28
  gemspec.email = "daniel@degu.cl"
22
29
  gemspec.homepage = "http://github.com/danielhz/ruil"
23
- gemspec.summary = "Basic tools for build web appplications on top of rack"
30
+ gemspec.summary = "Minimalist library to build web appplications on top of rack"
24
31
  gemspec.rubyforge_project = "ruil"
25
32
  gemspec.description = "It provides a class to derivate the application resources\n" +
26
33
  "and a delegator that select the appropiate resource to answer\n" +
@@ -29,25 +36,15 @@ begin
29
36
  rescue LoadError
30
37
  end
31
38
 
32
- begin
33
- require 'darkfish-rdoc'
34
- DARKFISH_ENABLED = true
35
- rescue LoadError => ex
36
- DARKFISH_ENABLED = false
39
+ YARD::Rake::YardocTask.new do |t|
40
+ t.options += ['--title', "Ruil Documentation"]
37
41
  end
38
42
 
39
- BASE_RDOC_OPTIONS = [
40
- '--line-numbers', '--inline-source',
41
- '--main' , 'README.rdoc',
42
- '--title', 'uagent'
43
- ]
44
-
45
- rd = Rake::RDocTask.new do |rdoc|
46
- rdoc.rdoc_dir = 'html'
47
- rdoc.title = "ruil"
48
- rdoc.options = BASE_RDOC_OPTIONS.dup
49
- rdoc.options << '-SHN' << '-f' << 'darkfish' if DARKFISH_ENABLED
50
- rdoc.options << '--charset' << 'utf-8'
51
- rdoc.rdoc_files.include('README.rdoc')
52
- rdoc.rdoc_files.include('lib/**/*.rb', 'doc/**/*.rdoc')
43
+ desc 'Build and upload the last gem file'
44
+ task :gem_push => :build do
45
+ gem = Dir['pkg/*.gem'].map { |f|
46
+ [f, File.basename(f).gsub(/.gem$/, '').gsub(/^ruil-/, '').split('.').map{ |x| x.to_i}]
47
+ }.sort.last
48
+ puts "gem push #{gem[0]}"
49
+ system "gem push #{gem[0]}"
53
50
  end
@@ -0,0 +1,50 @@
1
+ require 'rubygems'
2
+ require 'ruil'
3
+ require 'json'
4
+ require 'rspec'
5
+
6
+ describe Ruil::HTMLResponder do
7
+
8
+ before(:all) do
9
+ # Templates
10
+ Dir.mkdir '/tmp/spec'
11
+ ['html', 'xhtml'].each do |suffix|
12
+ file = File.new("/tmp/spec/ruil.desktop.tenjin.#{suffix}", 'w')
13
+ file << '<p id="' + suffix + '">#{@x}</p>'
14
+ file.close
15
+ end
16
+ # Test a request
17
+ @test_request = lambda do |responder, path_info, generated_data, content_type, layout|
18
+ # Defining request
19
+ request = Ruil::Request.new(Rack::Request.new({'rack.input' => ''}))
20
+ request.rack_request.path_info = path_info
21
+ request.generated_data = {:x => generated_data}
22
+ # Checking response
23
+ response = responder.call(request)
24
+ response.status.should == 200
25
+ suffix = path_info.sub(/^.*\./, '')
26
+ suffix = 'html' if suffix == path_info
27
+ response.body.should == ["<p id=\"#{suffix}\">#{generated_data}</p>"]
28
+ response.header['Content-Type'].should == content_type
29
+ end
30
+ end
31
+
32
+ after(:all) do
33
+ Dir['/tmp/spec/*'].each { |f| File.delete f }
34
+ Dir.delete '/tmp/spec'
35
+ end
36
+
37
+ it 'should respond files without layout' do
38
+ responder = Ruil::HTMLResponder.new('/tmp/spec/ruil')
39
+ @test_request.call(responder, '/ruil.html', 'x', 'text/html', nil)
40
+ @test_request.call(responder, '/ruil', 'x', 'text/html', nil)
41
+ @test_request.call(responder, '/ruil/', 'x', 'text/html', nil)
42
+ @test_request.call(responder, '/ruil/#', 'x', 'text/html', nil)
43
+ @test_request.call(responder, '/ruil.xhtml', 'x', 'application/xhtml+xml', nil)
44
+ end
45
+
46
+ it 'should respond using a html file with layout' do
47
+ # TODO
48
+ end
49
+
50
+ end
@@ -0,0 +1,30 @@
1
+ require 'rubygems'
2
+ require 'ruil'
3
+ require 'json'
4
+ require 'rspec'
5
+
6
+ describe Ruil::JSONResponder do
7
+
8
+ before(:all) do
9
+ request = Ruil::Request.new(Rack::Request.new({'PATH_INFO' => 'foo.js'}))
10
+ @data = { :r => (1...10).map { |x| rand } }
11
+ request.generated_data = @data
12
+ @response = Ruil::JSONResponder.instance.call(request)
13
+ end
14
+
15
+ it 'should get an OK status' do
16
+ @response.status.should == 200
17
+ end
18
+
19
+ it 'should get the JSON media type' do
20
+ @response.header['Content-Type'].should == 'application/json'
21
+ end
22
+
23
+ it 'should render json files' do
24
+ rendered = JSON.parse(@response.body.join)
25
+ rendered['r'].each_index do |i|
26
+ rendered['r'][i].to_s.should == @data[:r][i].to_s
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'ruil'
3
+ require 'rspec'
4
+
5
+ describe "Ruil::PathInfoParser" do
6
+
7
+ it 'should parse paths' do
8
+ parser = Ruil::PathInfoParser.new('/foo/:type/:id')
9
+ (parser === '/foo/bar/1').should == {:type => 'bar', :id => '1'}
10
+ (parser === '/foo/bar/3.js').should == {:type => 'bar', :id => '3'}
11
+ (parser === '/foo').should == false
12
+ (parser === '/bar').should == false
13
+ end
14
+
15
+ end
@@ -0,0 +1,22 @@
1
+ require 'rubygems'
2
+ require 'ruil'
3
+ require 'rspec'
4
+
5
+ describe Ruil::Redirector do
6
+ before(:all) do
7
+ @url = '/unauthorized_url'
8
+ rack_request = Rack::Request.new({})
9
+ rack_request.path_info = @url
10
+ ruil_request = Ruil::Request.new(rack_request)
11
+ @response = Ruil::Redirector.new('/login').call(ruil_request)
12
+ end
13
+
14
+ it 'should get an redirection status' do
15
+ @response.status.should == 302
16
+ end
17
+
18
+ it 'should get the url to be redirected' do
19
+ @response.header['Location'].should == "/login?redirected_from=" + @url
20
+ end
21
+
22
+ end
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ require 'ruil'
3
+ require 'rspec'
4
+
5
+ describe Ruil::Register do
6
+
7
+ before(:all) do
8
+ class MockResponse
9
+ def initialize(value)
10
+ @value = value
11
+ end
12
+ def finish
13
+ @value
14
+ end
15
+ end
16
+ class MockResource
17
+ def initialize(value)
18
+ @value = value
19
+ end
20
+ def call(request)
21
+ request.path_info == @value ? MockResponse.new(@value) : false
22
+ end
23
+ def request_methods
24
+ ['GET']
25
+ end
26
+ end
27
+ (0..9).each do |value|
28
+ Ruil::Register << MockResource.new(value.to_s)
29
+ end
30
+ end
31
+
32
+ it 'should get responses for requests' do
33
+ (1..10).each do
34
+ value = rand(10).to_s
35
+ request = Rack::Request.new({
36
+ 'REQUEST_METHOD' => 'GET',
37
+ 'PATH_INFO' => value
38
+ })
39
+ Ruil::Register.call(request).should == value
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'ruil'
3
+ require 'rspec'
4
+
5
+ describe "Ruil::Request" do
6
+
7
+ before(:all) do
8
+ @rack_request = Rack::Request.new({})
9
+ @ruil_request = Ruil::Request.new(@rack_request)
10
+ end
11
+
12
+ it 'should contain the rack request' do
13
+ @ruil_request.rack_request.should == @rack_request
14
+ end
15
+
16
+ it 'should allow access to generated data' do
17
+ @ruil_request.generated_data.should == {}
18
+ @ruil_request.generated_data[:x] = "y"
19
+ @ruil_request.generated_data.should == {:x => "y"}
20
+ end
21
+
22
+ it 'should get the default html mode' do
23
+ @ruil_request.html_mode.should == :desktop
24
+ end
25
+
26
+ end
@@ -0,0 +1,31 @@
1
+ require 'rubygems'
2
+ require 'ruil'
3
+ require 'rspec'
4
+
5
+ describe Ruil::Resource do
6
+
7
+ before(:all) do
8
+ @resource = Ruil::Resource.new('GET', '/test/:id') do |request|
9
+ request.generated_data = request.generated_data[:path_info_params]
10
+ end
11
+ end
12
+
13
+ it 'should get responses for requests' do
14
+ request = Rack::Request.new({
15
+ 'REQUEST_METHOD' => 'GET',
16
+ 'HTTP_USER_AGENT' => 'Mobile',
17
+ 'PATH_INFO' => '/test/12.js'
18
+ })
19
+ response = @resource.call(request)
20
+ response.status.should == 200
21
+ response.headers["Content-Type"].should == "application/json"
22
+ response.body.should == ['{"id":"12"}']
23
+ request = Rack::Request.new({
24
+ 'REQUEST_METHOD' => 'GET',
25
+ 'HTTP_USER_AGENT' => 'Mobile',
26
+ 'PATH_INFO' => '/test/12/aaa'
27
+ })
28
+ @resource.call(request).should == false
29
+ end
30
+
31
+ end
@@ -0,0 +1,38 @@
1
+ require 'rubygems'
2
+ require 'ruil'
3
+ require 'rspec'
4
+
5
+ describe Ruil::StaticResource do
6
+
7
+ before(:all) do
8
+ @resource = Ruil::StaticResource.new do |resource|
9
+ Dir.mkdir '/tmp/spec'
10
+ ['foo', 'bar'].each do |f|
11
+ file_name = "/tmp/spec/#{f}.html"
12
+ file = File.new(file_name, 'w')
13
+ file << f
14
+ file.close
15
+ resource.add(file_name, "/#{f}.html", 'text/html')
16
+ end
17
+ end
18
+ end
19
+
20
+ after(:all) do
21
+ Dir['/tmp/spec/*'].each { |f| File.delete f }
22
+ Dir.delete '/tmp/spec'
23
+ end
24
+
25
+ it 'should respond files without layout' do
26
+ ['foo', 'bar'].each do |f|
27
+ request = Rack::Request.new({
28
+ 'REQUEST_METHOD' => 'GET',
29
+ 'PATH_INFO' => "/#{f}.html"
30
+ })
31
+ response = @resource.call(request)
32
+ response.status.should == 200
33
+ response.body.should == ["#{f}"]
34
+ response.header['Content-Type'].should == 'text/html'
35
+ end
36
+ end
37
+
38
+ end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruil
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 27
5
+ prerelease:
5
6
  segments:
6
7
  - 0
7
- - 0
8
8
  - 1
9
- version: 0.0.1
9
+ - 0
10
+ version: 0.1.0
10
11
  platform: ruby
11
12
  authors:
12
13
  - "Daniel Hern\xC3\xA1ndez"
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-09-26 00:00:00 -04:00
18
+ date: 2011-05-25 00:00:00 -04:00
18
19
  default_executable:
19
20
  dependencies: []
20
21
 
@@ -30,49 +31,69 @@ extensions: []
30
31
  extra_rdoc_files:
31
32
  - README.rdoc
32
33
  files:
33
- - .gitignore
34
34
  - README.rdoc
35
35
  - VERSION
36
- - lib/ruil/delegator.rb
36
+ - lib/ruil.rb
37
+ - lib/ruil/html_responder.rb
38
+ - lib/ruil/json_responder.rb
39
+ - lib/ruil/mongo_resource.rb
40
+ - lib/ruil/path_info_parser.rb
41
+ - lib/ruil/redirector.rb
42
+ - lib/ruil/register.rb
43
+ - lib/ruil/request.rb
37
44
  - lib/ruil/resource.rb
38
- - lib/ruil/tenjin_template.rb
45
+ - lib/ruil/session_widget.rb
46
+ - lib/ruil/static_resource.rb
47
+ - lib/ruil/widget.rb
39
48
  - rakefile
40
- - test/delegator_test.rb
41
- - test/resource_test.rb
42
- - test/templates/a.desktop.html
43
- - test/templates/a.mobile.html
44
- - test/templates/b.desktop.html
45
- - test/templates/b.mobile.html
49
+ - spec/html_responder_spec.rb
50
+ - spec/json_responder_spec.rb
51
+ - spec/path_info_parser_spec.rb
52
+ - spec/redirector_spec.rb
53
+ - spec/register_spec.rb
54
+ - spec/request_spec.rb
55
+ - spec/resource_spec.rb
56
+ - spec/static_resource_spec.rb
46
57
  has_rdoc: true
47
58
  homepage: http://github.com/danielhz/ruil
48
59
  licenses: []
49
60
 
50
61
  post_install_message:
51
- rdoc_options:
52
- - --charset=UTF-8
62
+ rdoc_options: []
63
+
53
64
  require_paths:
54
65
  - lib
55
66
  required_ruby_version: !ruby/object:Gem::Requirement
67
+ none: false
56
68
  requirements:
57
69
  - - ">="
58
70
  - !ruby/object:Gem::Version
71
+ hash: 3
59
72
  segments:
60
73
  - 0
61
74
  version: "0"
62
75
  required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
63
77
  requirements:
64
78
  - - ">="
65
79
  - !ruby/object:Gem::Version
80
+ hash: 3
66
81
  segments:
67
82
  - 0
68
83
  version: "0"
69
84
  requirements: []
70
85
 
71
86
  rubyforge_project: ruil
72
- rubygems_version: 1.3.6
87
+ rubygems_version: 1.5.0
73
88
  signing_key:
74
89
  specification_version: 3
75
- summary: Basic tools for build web appplications on top of rack
90
+ summary: Minimalist library to build web appplications on top of rack
76
91
  test_files:
77
- - test/resource_test.rb
78
- - test/delegator_test.rb
92
+ - spec/html_responder_spec.rb
93
+ - spec/json_responder_spec.rb
94
+ - spec/path_info_parser_spec.rb
95
+ - spec/redirector_spec.rb
96
+ - spec/register_spec.rb
97
+ - spec/request_spec.rb
98
+ - spec/resource_spec.rb
99
+ - spec/static_resource_spec.rb
data/.gitignore DELETED
@@ -1,5 +0,0 @@
1
- coverage
2
- html
3
- pkg
4
- *~
5
- *.html.cache
@@ -1,42 +0,0 @@
1
- require 'rubygems'
2
-
3
- module Ruil
4
-
5
- class Delegator
6
-
7
- # Initialize a delegator
8
- def initialize(user_agent_parser, template_dir, template_engine, &block)
9
- @user_agent_parser = user_agent_parser
10
- @template_engine = template_engine
11
- @template_dir = template_dir
12
- @resources = []
13
- yield self
14
- end
15
-
16
- # Default action
17
- def default(env)
18
- [ 302, {"Content-Type" => "text/html", 'Location'=> '/' }, [] ]
19
- end
20
-
21
- def add_resource(resource_class)
22
- resource_class.new(@user_agent_parser) do |r|
23
- Dir[File.join(@template_dir, r.template_pattern)].each do |file|
24
- user_agent = File.basename(file).split('.')[1]
25
- template = @template_engine.new(file)
26
- r.add_template user_agent.to_sym, template
27
- end
28
- @resources << [r.path_pattern, r]
29
- end
30
- end
31
-
32
- # Call method
33
- def call(env)
34
- @resources.each do |path_pattern, proc|
35
- return proc.call(env) if path_pattern === env['PATH_INFO']
36
- end
37
- default(env)
38
- end
39
-
40
- end
41
-
42
- end
@@ -1,20 +0,0 @@
1
- require 'rubygems'
2
- require 'tenjin'
3
-
4
- module Ruil
5
-
6
- class TenjinTemplate
7
-
8
- @@engine = Tenjin::Engine.new
9
-
10
- def initialize(file)
11
- @file = file
12
- end
13
-
14
- def call(options)
15
- @@engine.render(@file, options)
16
- end
17
-
18
- end
19
-
20
- end