cans 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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Bryce Kerley
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,20 @@
1
+ = cans
2
+
3
+ Interactive online source browser for Rack applications.
4
+
5
+ Experimental and unfinished. This gem will probably kill
6
+ you in your sleep if you try to use it right now.
7
+
8
+ == Note on Patches/Pull Requests
9
+
10
+ * Fork the project.
11
+ * Make your feature addition or bug fix.
12
+ * Add tests for it. This is important so I don't break it in a
13
+ future version unintentionally.
14
+ * Commit, do not mess with rakefile, version, or history.
15
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
16
+ * Send me a pull request. Bonus points for topic branches.
17
+
18
+ == Copyright
19
+
20
+ Copyright (c) 2010 Bryce Kerley. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,62 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "cans"
8
+ gem.summary = %Q{Source browser for Rack applications}
9
+ gem.description = %Q{Interactive on-line source browser for rack applications}
10
+ gem.email = "bkerley@brycekerley.net"
11
+ gem.homepage = "http://github.com/bkerley/cans"
12
+ gem.authors = ["Bryce Kerley"]
13
+
14
+ gem.add_dependency 'sinatra', '~> 1.1.0'
15
+ gem.add_dependency 'haml', '~> 3.0.22'
16
+ gem.add_dependency 'method_extensions', '~> 0.0.8'
17
+
18
+ gem.add_development_dependency "shoulda", "~> 2.11.3"
19
+ gem.add_development_dependency 'rack-test', '~> 0.5.6'
20
+
21
+ gem.required_ruby_version = '~> 1.9.2'
22
+
23
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
24
+ end
25
+ Jeweler::GemcutterTasks.new
26
+ rescue LoadError
27
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
28
+ end
29
+
30
+ require 'rake/testtask'
31
+ Rake::TestTask.new(:test) do |test|
32
+ test.libs << 'lib' << 'test'
33
+ test.pattern = 'test/**/test_*.rb'
34
+ test.verbose = true
35
+ end
36
+
37
+ begin
38
+ require 'rcov/rcovtask'
39
+ Rcov::RcovTask.new do |test|
40
+ test.libs << 'test'
41
+ test.pattern = 'test/**/test_*.rb'
42
+ test.verbose = true
43
+ end
44
+ rescue LoadError
45
+ task :rcov do
46
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
47
+ end
48
+ end
49
+
50
+ task :test => :check_dependencies
51
+
52
+ task :default => :test
53
+
54
+ require 'rake/rdoctask'
55
+ Rake::RDocTask.new do |rdoc|
56
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
57
+
58
+ rdoc.rdoc_dir = 'rdoc'
59
+ rdoc.title = "cans #{version}"
60
+ rdoc.rdoc_files.include('README*')
61
+ rdoc.rdoc_files.include('lib/**/*.rb')
62
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/config.ru ADDED
@@ -0,0 +1,4 @@
1
+ require File.join(File.dirname(__FILE__), 'lib', 'cans.rb')
2
+ use Rack::ContentLength
3
+
4
+ run(Cans::Application.new)
@@ -0,0 +1,49 @@
1
+ module Cans
2
+ class Address
3
+ METHOD_KIND_REGEX = %r{\.(.)}
4
+ MODULE_NAME_REGEX = /^(.+)\/\.|^(.+)$/
5
+ METHOD_NAME_REGEX = %r{\../(.+)$}
6
+
7
+ def initialize(address_string)
8
+ @string = address_string
9
+ end
10
+
11
+ def module_name
12
+ md = MODULE_NAME_REGEX.match @string
13
+ raise "No module_name found in #{@string.inspect}" unless md
14
+ return md.captures.detect{ |m| !(m.nil? || m.empty?) }.gsub('/','::')
15
+ end
16
+
17
+ def method_kind
18
+ md = METHOD_KIND_REGEX.match @string
19
+ raise "No method_kind found" unless md
20
+ return case md[1]
21
+ when 'i'
22
+ :instance
23
+ when 'm'
24
+ :module
25
+ else
26
+ raise 'Unexpected method_kind found'
27
+ end
28
+ end
29
+
30
+ def method_name
31
+ md = METHOD_NAME_REGEX.match @string
32
+ raise 'No method_name found' unless md
33
+ return md[1].gsub('/','')
34
+ end
35
+
36
+ def target_module
37
+ eval "::#{module_name}"
38
+ end
39
+
40
+ def target_method
41
+ case method_kind
42
+ when :instance
43
+ target_module.instance_method method_name
44
+ when :module
45
+ target_module.method method_name
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,33 @@
1
+ module Cans
2
+ class Application < Sinatra::Base
3
+ set :views, File.dirname(__FILE__) + '/views'
4
+
5
+ get '/' do
6
+ @constants = Object.constants
7
+ @modules = @constants.map{ |c| Object.const_get c}.select{ |c| c.kind_of? Module}.sort_by(&:name)
8
+ haml :index
9
+ end
10
+
11
+ get '/module/*' do
12
+ @address = Address.new(params[:splat].first)
13
+ @module = @address.target_module
14
+
15
+ @local_instance_methods = @module.instance_methods false
16
+ @all_instance_methods = @module.instance_methods true
17
+ @super_instance_methods = @all_instance_methods - @local_instance_methods
18
+
19
+ @class_methods = @module.methods
20
+
21
+ @ancestors = @module.ancestors
22
+ @child_modules = @module.constants.map{ |c| @module.const_get c}.select{ |c| c.kind_of? Module}.sort_by(&:name)
23
+ haml :module
24
+ end
25
+
26
+ get '/method/*' do
27
+ @address = Address.new(params[:splat].first)
28
+ @module = @address.target_module
29
+ @method = @address.target_method
30
+ haml :method
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,10 @@
1
+ !!! 5
2
+ %html
3
+ %head
4
+ %title Cans
5
+ %body
6
+ %h1 Top-Level Modules
7
+ %ul
8
+ - @modules.each do |m|
9
+ %li
10
+ %a{:href=>"/module/#{m.name}"}&= m.name
@@ -0,0 +1,11 @@
1
+ !!! 5
2
+ %html
3
+ %head
4
+ %title #{@module.name} #{@method.name} | Cans
5
+ %body
6
+ %h1 #{@module.name} #{@method.name}
7
+ - unless @method.source_location.nil?
8
+ %p #{@method.name} is defined at #{@method.source_location.map(&:inspect).join(', line ')}
9
+ %pre=@method.source_with_doc
10
+ - else
11
+ %p #{@method.name} is defined in the Ruby source code.
@@ -0,0 +1,36 @@
1
+ !!! 5
2
+ %html
3
+ %head
4
+ %title #{@module.name} | Cans
5
+ %body
6
+ %h1 #{@module.name}
7
+ %p #{@module.name} inherits from:
8
+ %ul
9
+ - @ancestors.sort_by(&:name).each do |a|
10
+ %li
11
+ %a{:href=>"/module/#{a.name.gsub('::','/')}"}
12
+ &=a.name
13
+ %h2 Child Modules
14
+ %ul
15
+ - @child_modules.each do |c|
16
+ %li
17
+ %a{:href=>"/module/#{c.name.gsub('::','/')}"}
18
+ &=c.name
19
+ %h2 Class/Module Methods
20
+ %ul
21
+ - @class_methods.sort_by(&:to_s).each do |m|
22
+ %li
23
+ %a{:href=>"/method/#{@module.name}/.m/#{m.to_s}"}
24
+ &=m.to_s
25
+ %h2 Local Instance Methods
26
+ %ul
27
+ - @local_instance_methods.sort_by(&:to_s).each do |m|
28
+ %li
29
+ %a{:href=>"/method/#{@module.name}/.i/#{m.to_s}"}
30
+ &=m.to_s
31
+ %h2 Inherited Instance Methods
32
+ %ul
33
+ - @super_instance_methods.sort_by(&:to_s).each do |m|
34
+ %li
35
+ %a{:href=>"/method/#{@module.name}/.i/#{m.to_s}"}
36
+ &=m.to_s
data/lib/cans.rb ADDED
@@ -0,0 +1,11 @@
1
+ %w{ method_extensions sinatra/base haml }.each do |g|
2
+ require g
3
+ end
4
+
5
+ %w{ address application }.each do |f|
6
+ require File.join(File.dirname(__FILE__), 'cans', f)
7
+ end
8
+
9
+ module Cans
10
+
11
+ end
@@ -0,0 +1,5 @@
1
+ class Beverage
2
+ def refreshing
3
+ 'quite'
4
+ end
5
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'rack/test'
4
+ require 'shoulda'
5
+
6
+ ENV['RACK_ENV'] = 'test'
7
+
8
+ require File.join(File.dirname(__FILE__), 'fixtures', 'beverage')
9
+
10
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
11
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
12
+ require 'cans'
13
+
14
+ class Test::Unit::TestCase
15
+ include Rack::Test::Methods
16
+ end
@@ -0,0 +1,45 @@
1
+ require 'helper'
2
+
3
+ class TestAddress < Test::Unit::TestCase
4
+ context 'an Address to an instance method on the Beverage class' do
5
+ setup do
6
+ @address = Cans::Address.new 'Beverage/.i/refreshing'
7
+ end
8
+ subject { @address }
9
+
10
+ should 'decode a module_name' do
11
+ assert_equal 'Beverage', subject.module_name
12
+ end
13
+
14
+ should 'decode a method_kind' do
15
+ assert_equal :instance, subject.method_kind
16
+ end
17
+
18
+ should 'decode a method_name' do
19
+ assert_equal 'refreshing', subject.method_name
20
+ end
21
+
22
+ should 'find the target_module' do
23
+ assert_equal Beverage, subject.target_module
24
+ end
25
+
26
+ should 'find the target_method' do
27
+ assert_equal Beverage.instance_method(:refreshing), subject.target_method
28
+ end
29
+ end
30
+
31
+ context 'an Address to the Beverage class' do
32
+ setup do
33
+ @address = Cans::Address.new 'Beverage'
34
+ end
35
+ subject { @address }
36
+
37
+ should 'decode the module_name' do
38
+ assert_equal 'Beverage', subject.module_name
39
+ end
40
+
41
+ should 'find the target_module' do
42
+ assert_equal Beverage, subject.target_module
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,69 @@
1
+ require 'helper'
2
+
3
+ class TestApplication < Test::Unit::TestCase
4
+ context 'an Application instance' do
5
+ subject { app.new }
6
+
7
+ context '#call method' do
8
+ subject { app.new.method :call }
9
+
10
+ should 'exist' do
11
+ assert subject
12
+ end
13
+
14
+ should 'have an arity of 1' do
15
+ assert_equal 1, subject.arity
16
+ end
17
+ end
18
+ end
19
+
20
+ context 'get to /' do
21
+ setup do
22
+ get '/'
23
+ end
24
+
25
+ should 'be ok' do
26
+ assert last_response.ok?
27
+ end
28
+
29
+ should 'list some known modules' do
30
+ expected_constants = %w{ Cans Beverage TestApplication }
31
+
32
+ expected_constants.each do |c|
33
+ assert_match c, last_response.body
34
+ end
35
+ end
36
+ end
37
+
38
+ context 'get to /method/Beverage/.i/refreshing' do
39
+ setup do
40
+ get '/method/Beverage/.i/refreshing'
41
+ end
42
+
43
+ should 'be ok' do
44
+ assert last_response.ok?
45
+ end
46
+
47
+ should 'include the source' do
48
+ assert_match /quite/, last_response.body
49
+ end
50
+ end
51
+
52
+ context 'get to /module/Beverage' do
53
+ setup do
54
+ get '/module/Beverage'
55
+ end
56
+
57
+ should 'be ok' do
58
+ assert last_response.ok?
59
+ end
60
+
61
+ should 'include the "refreshing" instance method' do
62
+ assert_match /refreshing/, last_response.body
63
+ end
64
+ end
65
+
66
+ def app
67
+ Cans::Application
68
+ end
69
+ end
data/test/test_cans.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'helper'
2
+
3
+ class TestCans < Test::Unit::TestCase
4
+ end
metadata ADDED
@@ -0,0 +1,162 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cans
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Bryce Kerley
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-10-24 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: sinatra
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 1
30
+ - 1
31
+ - 0
32
+ version: 1.1.0
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: haml
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 3
45
+ - 0
46
+ - 22
47
+ version: 3.0.22
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: method_extensions
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ~>
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
60
+ - 0
61
+ - 8
62
+ version: 0.0.8
63
+ type: :runtime
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: shoulda
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ~>
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 2
75
+ - 11
76
+ - 3
77
+ version: 2.11.3
78
+ type: :development
79
+ version_requirements: *id004
80
+ - !ruby/object:Gem::Dependency
81
+ name: rack-test
82
+ prerelease: false
83
+ requirement: &id005 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ~>
87
+ - !ruby/object:Gem::Version
88
+ segments:
89
+ - 0
90
+ - 5
91
+ - 6
92
+ version: 0.5.6
93
+ type: :development
94
+ version_requirements: *id005
95
+ description: Interactive on-line source browser for rack applications
96
+ email: bkerley@brycekerley.net
97
+ executables: []
98
+
99
+ extensions: []
100
+
101
+ extra_rdoc_files:
102
+ - LICENSE
103
+ - README.rdoc
104
+ files:
105
+ - .document
106
+ - .gitignore
107
+ - LICENSE
108
+ - README.rdoc
109
+ - Rakefile
110
+ - VERSION
111
+ - config.ru
112
+ - lib/cans.rb
113
+ - lib/cans/address.rb
114
+ - lib/cans/application.rb
115
+ - lib/cans/views/index.haml
116
+ - lib/cans/views/method.haml
117
+ - lib/cans/views/module.haml
118
+ - test/fixtures/beverage.rb
119
+ - test/helper.rb
120
+ - test/test_address.rb
121
+ - test/test_application.rb
122
+ - test/test_cans.rb
123
+ has_rdoc: true
124
+ homepage: http://github.com/bkerley/cans
125
+ licenses: []
126
+
127
+ post_install_message:
128
+ rdoc_options:
129
+ - --charset=UTF-8
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ none: false
134
+ requirements:
135
+ - - ~>
136
+ - !ruby/object:Gem::Version
137
+ segments:
138
+ - 1
139
+ - 9
140
+ - 2
141
+ version: 1.9.2
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ none: false
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ segments:
148
+ - 0
149
+ version: "0"
150
+ requirements: []
151
+
152
+ rubyforge_project:
153
+ rubygems_version: 1.3.7
154
+ signing_key:
155
+ specification_version: 3
156
+ summary: Source browser for Rack applications
157
+ test_files:
158
+ - test/fixtures/beverage.rb
159
+ - test/helper.rb
160
+ - test/test_address.rb
161
+ - test/test_application.rb
162
+ - test/test_cans.rb