Dex_Rack 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/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+
6
+ coverage
7
+ rdoc
8
+ .yardoc
data/Dex_Rack.gemspec ADDED
@@ -0,0 +1,36 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $:.push File.expand_path("../lib", __FILE__)
4
+ require "Dex_Rack/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "Dex_Rack"
8
+ s.version = Dex_Rack::VERSION
9
+ s.authors = ["da99"]
10
+ s.email = ["i-hate-spam-45671204@mailinator.com"]
11
+ s.homepage = "https://github.com/da99/Dex_Rack"
12
+ s.summary = %q{A Rack app to display Dex exceptions.}
13
+ s.description = %q{
14
+ It is a web-frontend for Dex.
15
+ Update and view exceptions logged with the Dex gem.
16
+ }
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
23
+ s.add_development_dependency 'bacon'
24
+ s.add_development_dependency 'rake'
25
+ s.add_development_dependency 'Bacon_Colored'
26
+ s.add_development_dependency 'pry'
27
+ s.add_development_dependency 'rack-test'
28
+
29
+ # Specify any dependencies here; for example:
30
+ s.add_runtime_dependency 'sinatra'
31
+ s.add_runtime_dependency 'markaby'
32
+ s.add_runtime_dependency 'thin'
33
+ s.add_runtime_dependency 'sinatra-reloader'
34
+ s.add_runtime_dependency 'chronic_duration'
35
+ s.add_runtime_dependency 'Dex'
36
+ end
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ source "http://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in Bob.gemspec
6
+ gemspec
data/README.md ADDED
@@ -0,0 +1,36 @@
1
+
2
+ Dex\_Rack
3
+ ================
4
+
5
+ A Ruby gem.
6
+
7
+ Installation
8
+ ------------
9
+
10
+ gem install Dex_Rack
11
+
12
+ Usage
13
+ ------
14
+
15
+ Create a `config.ru` file:
16
+
17
+ require "Dex_Rack"
18
+
19
+ Dex_Rack.set :dex, ( Dex.db("My.SQLITE.file.db") && Dex )
20
+ run Dex_Rack
21
+
22
+ In your shell:
23
+
24
+ rackup -p 3000
25
+
26
+ Visit: [http://localhost:3000](http://localhost:3000)
27
+
28
+ Run Tests
29
+ ---------
30
+
31
+ git clone git@github.com:da99/Dex_Rack.git
32
+ cd Dex_Rack
33
+ bundle update
34
+ bundle exec bacon spec/lib/main.rb
35
+
36
+
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/gem_tasks"
data/lib/Dex_Rack.rb ADDED
@@ -0,0 +1,194 @@
1
+ require 'Dex_Rack/version'
2
+ require 'Dex'
3
+ require 'markaby'
4
+ require 'chronic_duration'
5
+ require 'cgi'
6
+
7
+ class Dex_Rack
8
+
9
+ RACK_DIR = File.join( File.dirname( __FILE__ ) , "/Dex_Rack" )
10
+
11
+ set :dex, ( Dex.db("/tmp/dex.rack.sample.db") && Dex )
12
+
13
+ use Rack::Lint
14
+
15
+ set :public_folder, RACK_DIR + "/public"
16
+ set :views_folder, RACK_DIR + "/views"
17
+
18
+ # use Rack::Static, \
19
+ # :urls=>%w{ /stylesheets/ /javascripts/ /images/ /index.html }, \
20
+ # :root=> RACK_DIR
21
+
22
+ configure :development do
23
+ require 'sinatra/reloader'
24
+ register Sinatra::Reloader
25
+ use Rack::CommonLogger
26
+ end
27
+
28
+ get "/" do
29
+ recent
30
+ end
31
+
32
+ get "/recent/:page" do | page |
33
+ recent page
34
+ end
35
+
36
+ get %r!\A/(\d+)\Z! do | id |
37
+ r = dex.filter(:id=>id).first
38
+
39
+ if r
40
+ vars= Hash[
41
+ :title=>"#{r[:exception]}: #{r[:message]}",
42
+ :record=>r,
43
+ :table_keys=>(r.keys - [:exception, :message, :backtrace, :status]),
44
+ :app=>self
45
+ ]
46
+
47
+ s = self
48
+ status = status_to_word(r[:status])
49
+ vars[:status_class] = status.downcase
50
+ vars[:status_word] = status
51
+ r[:human_time] = human_time(r[:created_at])
52
+ r[:backtrace] = backtrace_to_html(r[:backtrace])
53
+ vars[:table_keys] << :human_time
54
+ layout vars, :record
55
+ else
56
+ status 404
57
+ layout Hash[:id=>id, :title=>"Not Found: Record ##{id}"], :record_404
58
+ end
59
+
60
+ end
61
+
62
+ get "/:id/toggle" do |id|
63
+ r = dex.filter(:id=>id).first
64
+ s = r[:status] == 0 ? 1 : 0
65
+ dex.filter(:id=>id).update(:status=>s)
66
+ redirect to("/#{r[:id]}"), 302
67
+ end
68
+
69
+ delete "/:id" do | id |
70
+ dex.filter(:id=>id).delete
71
+ redirect to('/'), 303
72
+ end
73
+
74
+ get "/create-sample" do
75
+ begin
76
+ raise ArgumentError, request.path_info
77
+ rescue ArgumentError => e
78
+ dex.insert e
79
+ end
80
+ redirect to("/"), 302
81
+ end
82
+
83
+ %w{ dex dex? }.each { |m|
84
+ eval %~
85
+ def #{m} *args
86
+ settings.#{m}(*args)
87
+ end
88
+ ~
89
+ }
90
+
91
+ def recent page = :last, limit = 10
92
+ nav = page_nav( dex.count, limit, page)
93
+
94
+ return redirect(to('/'), 302) if !nav
95
+
96
+ nav[:prev_url] = "/recent/#{nav[:prev]}" if nav[:prev]
97
+ nav[:next_url] = "/recent/#{nav[:next]}" if nav[:next]
98
+ nav[:next_url] = "/" if nav[:next] == nav[:total]
99
+
100
+ vars = nav.merge(
101
+ Hash[
102
+ :title => "Dex List",
103
+ :list => dex.limit(nav[:limit], nav[:offset]).to_a.reverse,
104
+ :app => self
105
+ ])
106
+
107
+ layout(vars, :index)
108
+ end
109
+
110
+ def layout vars, file_name
111
+ Markaby::Builder.set(:indent, 2)
112
+ mab = Markaby::Builder.new
113
+ file = File.join(settings.views_folder, "/layout.rb")
114
+ vars[:view_file] = File.join(settings.views_folder, "#{file_name}.rb" )
115
+ vars[:app] = self
116
+ mab.instance_eval {
117
+ eval File.read(file), nil, file, 1
118
+ }
119
+ mab.to_s
120
+ end
121
+
122
+ def status_to_word num
123
+ case num
124
+ when 0
125
+ "Unresolved"
126
+ when 1
127
+ "Resolved"
128
+ end
129
+ end
130
+
131
+ def backtrace_to_html s
132
+ last_file = nil
133
+ str = ""
134
+ s.split("\n").map { |l|
135
+ file, num, code = l.split(':')
136
+ str.<< %!
137
+ <div class="line">
138
+ <span class="num">#{CGI::escapeHTML num}</span>
139
+ <span class="code">#{CGI::escapeHTML code}</span>
140
+ </div>!
141
+ str.<< %!
142
+ <div class="file">#{CGI::escapeHTML file}</div>
143
+ ! if file != last_file
144
+
145
+ last_file = file
146
+ str
147
+ }.join
148
+ end
149
+
150
+ def human_time t
151
+ target = Time.now.utc.to_i - t.to_i
152
+ if target < 61
153
+ return "<1m ago"
154
+ else
155
+ ChronicDuration.output(target, :format=>:short).sub(/\d+s\Z/, '') + " ago"
156
+ end
157
+ end
158
+
159
+ def page_nav count, div, page = :last
160
+ count = count.to_i
161
+
162
+ div = div.to_i
163
+ total = ( count / Float(div) ).ceil
164
+ page = total if page == :last
165
+ page = page.to_i
166
+
167
+ if count > 0
168
+ if total < 1 || page < 1 || page > total || div < 2
169
+ return nil
170
+ end
171
+ end
172
+
173
+ n = page + 1
174
+ n = nil if n > total
175
+ p = page - 1
176
+ p = nil if p < 1
177
+ offset = div * (page - 1)
178
+ offset = 0 if offset < 1
179
+
180
+ Hash[
181
+
182
+ :total => total,
183
+ :next => n,
184
+ :prev => p,
185
+ :page => page,
186
+
187
+ :count => count,
188
+ :limit => div,
189
+ :offset => offset
190
+
191
+ ]
192
+ end
193
+
194
+ end # === class Dex_Rack
@@ -0,0 +1,4 @@
1
+
2
+ require "Dex_Rack"
3
+
4
+ run Dex_Rack
Binary file
@@ -0,0 +1,16 @@
1
+ $(document).ready(function() {
2
+
3
+ $("#show_backtrace").click(function() {
4
+ $("#show_backtrace").css("visibility", "hidden");
5
+ $("#hide_backtrace").css("visibility", "visible");
6
+ $("#backtrace").show();
7
+ });
8
+
9
+ $("#hide_backtrace").click(function() {
10
+ $("#show_backtrace").css("visibility", "visible");
11
+ $("#hide_backtrace").css("visibility", "hidden");
12
+ $("#backtrace").hide();
13
+ });
14
+
15
+ });
16
+
@@ -0,0 +1,29 @@
1
+
2
+ /**
3
+ * Skeleton V1.1
4
+ * Copyright 2011, Dave Gamache
5
+ * www.getskeleton.com
6
+ * Free to use under the MIT license.
7
+ * http://www.opensource.org/licenses/mit-license.php
8
+ * 8/17/2011
9
+ */
10
+
11
+ (function ($) {
12
+ // hash change handler
13
+ function hashchange () {
14
+ var hash = window.location.hash
15
+ , el = $('ul.tabs [href*="' + hash + '"]')
16
+ , content = $(hash)
17
+
18
+ if (el.length && !el.hasClass('active') && content.length) {
19
+ el.closest('.tabs').find('.active').removeClass('active');
20
+ el.addClass('active');
21
+ content.show().addClass('active').siblings().hide().removeClass('active');
22
+ }
23
+ }
24
+
25
+ // listen on event and fire right away
26
+ $(window).on('hashchange.skeleton', hashchange);
27
+ hashchange();
28
+ $(hashchange);
29
+ })(jQuery);
@@ -0,0 +1,5 @@
1
+ # www.robotstxt.org/
2
+ # www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449
3
+
4
+ User-agent: *
5
+
@@ -0,0 +1,207 @@
1
+ /* From: http://css-tricks.com/perfect-full-page-background-image/ */
2
+ body {
3
+ background: url("/images/texture/straw-flowers.gif") repeat-x 0 29px #FCFBF0;
4
+ background: #FCFBF0;
5
+ background: #FAFAFA;
6
+ font-family: 'Oxygen', sans-serif;
7
+ padding: 0 40px 40px 40px;
8
+ }
9
+
10
+ div.container {
11
+ background: white;
12
+ -moz-border-radius: 0 0 10px 10px;
13
+ border-radius: 0 0 10px 10px;
14
+ }
15
+
16
+ #header, #footer {
17
+ background: url('/images/texture/9.jpg') grey;
18
+ padding: 5px 10px 10px 20px ;
19
+ }
20
+
21
+ #header, h1, h2, h3 {
22
+ font-family: 'Bree Serif', serif;
23
+ }
24
+
25
+ #footer {
26
+ color: lightgrey;
27
+ font-size: 80%;
28
+ -moz-border-radius: 0 0 10px 10px;
29
+ border-radius: 0 0 10px 10px;
30
+ min-height: 30px;
31
+ }
32
+
33
+ #header h1 {
34
+ font-size: 200%;
35
+ color: white;
36
+ }
37
+
38
+ body.unresolved #header h1 {
39
+ color: pink;
40
+ }
41
+
42
+ body.unresolved #header h1 span.message {
43
+ color: white;
44
+ }
45
+
46
+ body.resolved #header h1 {
47
+ color: white;
48
+ }
49
+
50
+ #nav {
51
+ padding: 0 20px;
52
+ font-size: small;
53
+ background: white;
54
+ }
55
+
56
+ #content {
57
+ padding: 10px 20px 20px 20px;
58
+ background: white;
59
+ }
60
+
61
+ a#hide_backtrace {
62
+ visibility: hidden;
63
+ }
64
+
65
+ div.line:hover, div.file:hover {
66
+ background: lightyellow;
67
+ }
68
+
69
+ #more_info div.key {
70
+ font-weight: bold;
71
+ text-align: right;
72
+ display: inline-block;
73
+ min-width: 200px;
74
+ }
75
+
76
+ #more_info div.val {
77
+ display: inline-block;
78
+ }
79
+
80
+
81
+ table {
82
+ margin: 10px 10px 10px 0;
83
+ }
84
+
85
+ table tr:first-child td:first-child {
86
+ -moz-border-radius: 5px 0 0 0;
87
+ border-radius: 5px 0 0 0;
88
+ }
89
+
90
+ table tr:first-child td:last-child {
91
+ -moz-border-radius: 0 5px 0 0;
92
+ border-radius: 0 5px 0 0;
93
+ }
94
+
95
+ table tr:last-child td:first-child {
96
+ -moz-border-radius: 0 0 0 5px;
97
+ border-radius: 0 0 0 5px;
98
+ }
99
+
100
+ table tr:last-child td:last-child {
101
+ -moz-border-radius: 0 0 5px 0;
102
+ border-radius: 0 0 5px 0;
103
+ }
104
+
105
+ td {
106
+ background: lightgrey;
107
+ padding: 8px;
108
+ }
109
+
110
+ td.key {
111
+ text-align: right;
112
+ font-weight: bold;
113
+ padding: 8px 10px 8px 10px;
114
+ }
115
+
116
+ td.val {
117
+ background: #FFFFE6;
118
+ }
119
+
120
+ span.exception {
121
+ font-weight: bold;
122
+ }
123
+
124
+
125
+ span.status, a.button, a:link {
126
+ display: inline-block;
127
+ padding: 5px 8px;
128
+ font-size: 8pt;
129
+ font-weight: bold;
130
+ text-transform: uppercase;
131
+ text-align: center;
132
+ -moz-border-radius: 5px;
133
+ border-radius: 5px;
134
+ color: white;
135
+ }
136
+
137
+ a:link {
138
+ color: #8C728A;
139
+ text-shadow: none;
140
+ }
141
+
142
+ a:visited {
143
+ color: #B87FB3;
144
+ }
145
+
146
+ a:hover {
147
+ color: pink;
148
+ background: grey;
149
+ }
150
+
151
+ span.status {
152
+ background: grey;
153
+ }
154
+
155
+ a.button:link {
156
+ background: lightgrey;
157
+ color: #B87FB3;
158
+ }
159
+
160
+ a.button:visited {
161
+ color: grey;
162
+ }
163
+
164
+ a.button:hover, a.button:active {
165
+ color: pink;
166
+ background: grey;
167
+ }
168
+
169
+ div.unresolved h1, span.unresolved {
170
+ color: pink;
171
+ }
172
+
173
+ div.resolved h1, span.resolved {
174
+ color: white;
175
+ }
176
+
177
+ span.num {
178
+ font-weight: bold;
179
+ }
180
+
181
+ div.line {
182
+ padding: 5px;
183
+ }
184
+
185
+ div.file {
186
+ margin: 0 0 10px 0;
187
+ font-weight: bold;
188
+ padding: 5px;
189
+ }
190
+
191
+
192
+ div.record_in_list {
193
+ padding: 2px 0;
194
+ }
195
+
196
+ #toggle_backtrace {
197
+ display: none;
198
+ }
199
+
200
+ h3 {
201
+ font-size: 150%;
202
+ margin-bottom: 10px;
203
+ }
204
+ #backtrace {
205
+ padding-left: 20px;
206
+ }
207
+
@@ -0,0 +1,48 @@
1
+ /* http://meyerweb.com/eric/tools/css/reset/
2
+ v2.0 | 20110126
3
+ License: none (public domain)
4
+ */
5
+
6
+ html, body, div, span, applet, object, iframe,
7
+ h1, h2, h3, h4, h5, h6, p, blockquote, pre,
8
+ a, abbr, acronym, address, big, cite, code,
9
+ del, dfn, em, img, ins, kbd, q, s, samp,
10
+ small, strike, strong, sub, sup, tt, var,
11
+ b, u, i, center,
12
+ dl, dt, dd, ol, ul, li,
13
+ fieldset, form, label, legend,
14
+ table, caption, tbody, tfoot, thead, tr, th, td,
15
+ article, aside, canvas, details, embed,
16
+ figure, figcaption, footer, header, hgroup,
17
+ menu, nav, output, ruby, section, summary,
18
+ time, mark, audio, video {
19
+ margin: 0;
20
+ padding: 0;
21
+ border: 0;
22
+ font-size: 100%;
23
+ font: inherit;
24
+ vertical-align: baseline;
25
+ }
26
+ /* HTML5 display-role reset for older browsers */
27
+ article, aside, details, figcaption, figure,
28
+ footer, header, hgroup, menu, nav, section {
29
+ display: block;
30
+ }
31
+ body {
32
+ line-height: 1;
33
+ }
34
+ ol, ul {
35
+ list-style: none;
36
+ }
37
+ blockquote, q {
38
+ quotes: none;
39
+ }
40
+ blockquote:before, blockquote:after,
41
+ q:before, q:after {
42
+ content: '';
43
+ content: none;
44
+ }
45
+ table {
46
+ border-collapse: collapse;
47
+ border-spacing: 0;
48
+ }
@@ -0,0 +1,5 @@
1
+ require "sinatra/base"
2
+
3
+ class Dex_Rack < Sinatra::Base
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,68 @@
1
+ div.header! {
2
+ h1 {
3
+ span.exception vars[:title]
4
+ span.message vars[:message]
5
+ }
6
+ }
7
+
8
+ if vars[:app].request.path_info != '/'
9
+ div.nav! {
10
+ a(:href=>'/') { "Home"}
11
+ span.towards ">>"
12
+ span.location vars[:title]
13
+ }
14
+ end
15
+
16
+ div.content! {
17
+
18
+ if vars[:app].request.path_info == '/'
19
+ table {
20
+ tr {
21
+ td.key "Database:"
22
+ td.val vars[:app].dex.db_name.to_s
23
+ }
24
+ tr {
25
+ td.key "Table:"
26
+ td.val vars[:app].dex.table_name.to_s
27
+ }
28
+ }
29
+ end
30
+
31
+ div.recent_nav! {
32
+
33
+ if vars[:prev_url]
34
+ a(:href=>vars[:prev_url]) { "<< Back in Time" }
35
+ end
36
+
37
+ if vars[:next_url]
38
+ a(:href=>vars[:next_url]) { "Forward In Time >>" }
39
+ end
40
+
41
+ }
42
+
43
+ if vars[:list].empty?
44
+ div.empty {
45
+ p "No exceptions created."
46
+ a.button( :href=>"/create-sample" ) {
47
+ "Create Sample Exception"
48
+ }
49
+ }
50
+
51
+ else
52
+
53
+ vars[:list].each { |db|
54
+ div.record_in_list {
55
+ p {
56
+ a.button(:href=>"/#{db[:id]}") {
57
+ "View"
58
+ }
59
+ span.time( vars[:app].human_time(db[:created_at]) )
60
+ span.status.send(vars[:app].status_to_word(db[:status]).downcase, vars[:app].status_to_word(db[:status]))
61
+ span.exception "#{db[:exception]}:"
62
+ span.message db[:message]
63
+ }
64
+ }
65
+ }
66
+
67
+ end
68
+ }
@@ -0,0 +1,36 @@
1
+ xhtml_strict do
2
+
3
+ head {
4
+
5
+ link( :href=>'http://fonts.googleapis.com/css?family=Bree+Serif|Oxygen', :rel=>'stylesheet', :type=>'text/css' )
6
+
7
+ title vars[:title]
8
+ %w{ reset dex }.each { |name|
9
+ link(:rel=>"stylesheet", :href=>"/stylesheets/#{name}.css")
10
+ }
11
+ script(
12
+ :type=>"text/javascript",
13
+ :src=>"http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"
14
+ ) {}
15
+ script(
16
+ :type=>"text/javascript",
17
+ :src=>"/javascripts/dex.js"
18
+ ) {}
19
+ }
20
+
21
+ body(:class=>[vars[:status_class]].compact.join(' ')) {
22
+
23
+ eval File.read(vars[:view_file]), nil, vars[:view_file], 1
24
+
25
+
26
+ div.footer! {
27
+ if vars[:app].request.path_info == '/'
28
+ %~
29
+ <span>Background from: </span>
30
+ <a href="http://www.backgroundlabs.com" title="Background Labs"><img src="http://www.backgroundlabs.com/images/backgroundlabs88x15.gif" border="0" alt="Background Labs"/></a>
31
+ ~
32
+ end
33
+ }
34
+ }
35
+ end
36
+
@@ -0,0 +1,51 @@
1
+
2
+
3
+
4
+ div.header! {
5
+ h1 {
6
+ span.exception "#{vars[:record][:exception]}:"
7
+ span.message vars[:record][:message]
8
+ }
9
+ }
10
+
11
+ if vars[:app].request.path_info != '/'
12
+ div.nav! {
13
+ a(:href=>'/') { "Home"}
14
+ span.towards ">>"
15
+ span.location vars[:title]
16
+ }
17
+ end
18
+
19
+ div.content! {
20
+ div {
21
+ span.status.send vars[:status_class].downcase, vars[:status_word]
22
+ a.button(:href=>"/#{vars[:record][:id]}/toggle") { "Toggle" }
23
+ }
24
+
25
+ unless vars[:table_keys].empty?
26
+ table {
27
+ vars[:table_keys].each { |k|
28
+ tr {
29
+ td.key k.inspect
30
+ td.val vars[:record][k]
31
+ }
32
+ }
33
+ }
34
+ end
35
+
36
+ div.toggle_backtrace! {
37
+ div {
38
+ a.button.show_backtrace!(:href=>"#show") { "Show Backtrace" }
39
+ }
40
+ div.omega {
41
+ a.button.hide_backtrace!(:href=>"#hide") { "Hide Backtrace" }
42
+ }
43
+ }
44
+
45
+ h3 "Backtrace:"
46
+ div.backtrace! {
47
+ vars[:record][:backtrace]
48
+ }
49
+
50
+
51
+ }
@@ -0,0 +1,3 @@
1
+ div.sixteen.columns {
2
+ h2 vars[:title]
3
+ }
data/spec/Dex_App.rb ADDED
@@ -0,0 +1,88 @@
1
+
2
+ describe "get /" do
3
+
4
+ behaves_like 'Test DB'
5
+
6
+ it "renders message when there are no exceptions" do
7
+ get "/"
8
+ should_render %!No exceptions!
9
+ end
10
+
11
+ it "renders a recent list of 10" do
12
+ 5.times { |i| Dex.insert except("Err: #{i}") }
13
+
14
+ get "/"
15
+ 5.times { |i|
16
+ last_response.body.should.match %r!Err: #{i}!
17
+ }
18
+ end
19
+
20
+ end # === get /
21
+
22
+ describe "get /recent/:num" do
23
+
24
+ behaves_like 'Test DB'
25
+
26
+ it "/recent/:num renders a list" do
27
+ n = rand(10) + 1
28
+ n.times { |i| Dex.insert except("N: #{i}") }
29
+
30
+ get "/recent/#{1}"
31
+ n.times { |i|
32
+ last_response.body.should.match %r!N: #{i}!
33
+ }
34
+ end
35
+
36
+ end # === get /recent/num
37
+
38
+ describe "get /:id" do
39
+
40
+ behaves_like 'Test DB'
41
+
42
+ it "displays record" do
43
+ id = Dex.insert(except "rand err")
44
+ get "/#{id}"
45
+ should_render "rand err"
46
+ end
47
+
48
+ end # === get /:id
49
+
50
+ describe "get /:id/toggle" do
51
+
52
+ behaves_like 'Test DB'
53
+
54
+ it "updates status of record" do
55
+ id = Dex.insert(except "rand err")
56
+ get "/#{id}/toggle"
57
+ Dex.filter(:id=>id).first[:status]
58
+ .should == 1
59
+ end
60
+
61
+ it "redirects to /:id 302" do
62
+ id = Dex.insert(except "rand err")
63
+ get "/#{id}/toggle"
64
+ should_redirect_to "/#{id}", 302
65
+ end
66
+
67
+ end # === put /:id/status
68
+
69
+ describe "delete /:id" do
70
+
71
+ behaves_like 'Test DB'
72
+
73
+ it "deletes record" do
74
+ Dex.insert(except("Deleted"))
75
+ r = Dex.recent(1)
76
+ delete "/#{r[:id]}"
77
+ Dex.count.should == 0
78
+ end
79
+
80
+ it "redirects to / 303" do
81
+ Dex.insert(except("Deleted"))
82
+ r = Dex.recent(1)
83
+ delete "/#{r[:id]}"
84
+ should_redirect_to "/"
85
+ end
86
+
87
+ end # === delete /:id
88
+
data/spec/bin.rb ADDED
@@ -0,0 +1,13 @@
1
+
2
+ bins = Dir.glob("bin/*")
3
+
4
+ unless bins.empty?
5
+ describe "permissions of bin/" do
6
+ bins.each { |file|
7
+ it "should chmod 755 for: #{file}" do
8
+ `stat -c %a #{file}`.strip
9
+ .should.be == "755"
10
+ end
11
+ }
12
+ end # === permissions of bin/
13
+ end # === unless bins.empty?
data/spec/lib/main.rb ADDED
@@ -0,0 +1,75 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.print e.message, "\n"
7
+ $stderr.print "Run `bundle install` to install missing gems\n"
8
+ exit e.status_code
9
+ end
10
+ require 'bacon'
11
+
12
+ Gem_Dir = File.expand_path( File.join(File.dirname(__FILE__) + '/../..') )
13
+ $LOAD_PATH.unshift Gem_Dir
14
+ $LOAD_PATH.unshift( Gem_Dir + "/lib" )
15
+
16
+ Bacon.summary_on_exit
17
+
18
+ require 'Bacon_Colored'
19
+ require 'pry'
20
+ require 'rack/test'
21
+ require 'Dex_Rack'
22
+
23
+ Dex_Rack.set :environment, :test
24
+ Dex_Rack.set :dex, ( Dex.db(":memory:") && Dex )
25
+
26
+ def except e
27
+ begin
28
+ raise e
29
+ rescue Object => e
30
+ $!
31
+ end
32
+ end
33
+
34
+ shared "Test DB" do
35
+ before {
36
+ Dex.table.delete
37
+ }
38
+ end
39
+
40
+ class Bacon::Context
41
+ include Rack::Test::Methods
42
+
43
+ def app
44
+ Dex_Rack
45
+ end
46
+
47
+ def should_render txt
48
+ last_response.should.be.ok
49
+ r = txt.respond_to?(:~) ? txt : %r!#{txt}!
50
+ last_response.body.should.match r
51
+ end
52
+
53
+ def should_redirect_to url, status = 303
54
+ last_response.status.should == status
55
+ last_response['Location'].sub( %r!http://(www.)?example.(com|org)!, '' )
56
+ .should == url
57
+ end
58
+
59
+ end # === class Bacon::Context
60
+
61
+
62
+ # ======== Include the tests.
63
+ target_files = ARGV[1, ARGV.size - 1].select { |a| File.file?(a) }
64
+
65
+ if target_files.empty?
66
+
67
+ # include all files
68
+ Dir.glob('./spec/*.rb').each { |file|
69
+ require file.sub('.rb', '') if File.file?(file)
70
+ }
71
+
72
+ else
73
+ # Do nothing. Bacon grabs the file.
74
+
75
+ end
metadata ADDED
@@ -0,0 +1,244 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: Dex_Rack
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - da99
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bacon
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: Bacon_Colored
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: pry
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rack-test
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: sinatra
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: markaby
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: thin
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :runtime
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: sinatra-reloader
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :runtime
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: chronic_duration
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :runtime
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ - !ruby/object:Gem::Dependency
175
+ name: Dex
176
+ requirement: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ! '>='
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ type: :runtime
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ none: false
186
+ requirements:
187
+ - - ! '>='
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ description: ! "\nIt is a web-frontend for Dex. \nUpdate and view exceptions logged
191
+ with the Dex gem.\n "
192
+ email:
193
+ - i-hate-spam-45671204@mailinator.com
194
+ executables: []
195
+ extensions: []
196
+ extra_rdoc_files: []
197
+ files:
198
+ - .gitignore
199
+ - Dex_Rack.gemspec
200
+ - Gemfile
201
+ - README.md
202
+ - Rakefile
203
+ - lib/Dex_Rack.rb
204
+ - lib/Dex_Rack/config.ru
205
+ - lib/Dex_Rack/public/favicon.ico
206
+ - lib/Dex_Rack/public/images/texture/9.jpg
207
+ - lib/Dex_Rack/public/javascripts/dex.js
208
+ - lib/Dex_Rack/public/javascripts/tabs.js
209
+ - lib/Dex_Rack/public/robots.txt
210
+ - lib/Dex_Rack/public/stylesheets/dex.css
211
+ - lib/Dex_Rack/public/stylesheets/reset.css
212
+ - lib/Dex_Rack/version.rb
213
+ - lib/Dex_Rack/views/index.rb
214
+ - lib/Dex_Rack/views/layout.rb
215
+ - lib/Dex_Rack/views/record.rb
216
+ - lib/Dex_Rack/views/record_404.rb
217
+ - spec/Dex_App.rb
218
+ - spec/bin.rb
219
+ - spec/lib/main.rb
220
+ homepage: https://github.com/da99/Dex_Rack
221
+ licenses: []
222
+ post_install_message:
223
+ rdoc_options: []
224
+ require_paths:
225
+ - lib
226
+ required_ruby_version: !ruby/object:Gem::Requirement
227
+ none: false
228
+ requirements:
229
+ - - ! '>='
230
+ - !ruby/object:Gem::Version
231
+ version: '0'
232
+ required_rubygems_version: !ruby/object:Gem::Requirement
233
+ none: false
234
+ requirements:
235
+ - - ! '>='
236
+ - !ruby/object:Gem::Version
237
+ version: '0'
238
+ requirements: []
239
+ rubyforge_project:
240
+ rubygems_version: 1.8.23
241
+ signing_key:
242
+ specification_version: 3
243
+ summary: A Rack app to display Dex exceptions.
244
+ test_files: []