ruil 0.0.1 → 0.1.0

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.
@@ -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