rspectacles 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1a11e46720615db03ab64f004c98feef3d72ca01
4
- data.tar.gz: bddfb9c9be4d000a0bf98c4159a8daa196999eff
3
+ metadata.gz: 7ad15310a5b2e9712ce803911cd98521cb89bf16
4
+ data.tar.gz: 7ac51e01e5634330dc9c5ff6f109ebc522d7fb83
5
5
  SHA512:
6
- metadata.gz: 3f64c551d1430a41e95aa4253d4110636ad904705f128521982b83fdaed38320992802bdbfbd221389972c7b1c61f3b75dfa69a32cd16856d74f5af23c2c9160
7
- data.tar.gz: 646ea8a1b97d395603222c6820ba36502a72b033fcbd5e7709818ea65f57726b8c831df876a2d38f26a803532f6e7cc1933283bdcf907ae7141cbc80111e7816
6
+ metadata.gz: 739fc4b1b8328491e6e97854718b607fad6e6c4ca3f6256689ad8cc39ff0ba1e70b1ce3358eb6edcaa769635e3286da4c60ecad63fcf309a1a67263005be8bd7
7
+ data.tar.gz: 106d48147ffc87cf7e8416920cf7e7b1529694810c50ec0e3100320edd323be292eeb69f5c44ddad3ba6a0d6bcff5addfdcdb860f4bfb43f9b2c5b4580b1323b
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rspectacles (0.3.1)
4
+ rspectacles (0.4.0)
5
5
  httparty
6
6
  pg
7
7
  puma
data/README.md CHANGED
@@ -54,33 +54,30 @@ Then run your specs and watch the magic happen!
54
54
 
55
55
  ## Web Server
56
56
 
57
- The server can be run in standalone mode:
57
+ The server uses ActiveRecord and Postgres to store the examples.
58
58
 
59
- rspectacles
59
+ Run migrations:
60
+
61
+ # set ENV['DATABASE_URL'] to point to your database, or else database.yml defaults will be used
62
+ rake db:create
63
+ rake db:migrate
60
64
 
61
- Or mounted directly on your app:
65
+ Start the server:
62
66
 
63
- # routes.rb
64
- mount RSpectacles::App => '/rspectacles'
67
+ puma
65
68
 
66
69
  ## Configuration
67
- If you need to change any settings, the best method is to create a yaml file
68
- with your settings, and set the ```RSPECTACLES_CONFIG``` environment variable so
69
- that both the server and formatter can locate the file.
70
-
71
- For instance:
72
-
73
- ```sh
74
- export RSPECTACLES_CONFIG='/path/to/config/rspectacles.yml'
75
- ```
76
-
77
- And in ```rspectacles.yml```:
78
- ```yaml
79
- sinatra_port: 4567
80
- batch_size: 500
81
- rspectacles_url: 'http://127.0.0.1:4567/'
82
- last_run_primary_key: 'redis-rspec-last-run'
83
- ```
70
+
71
+ Configuration settings can all be set through environment variables:
72
+
73
+ # server settings
74
+ RSPECTACLES_PORT = 4567
75
+
76
+ # client settings
77
+ RSPECTACLES_URL = nil
78
+ RSPECTACLES_RUN_KEY = 'rspec-current-run'
79
+ RSPECTACLES_BATCH_SIZE = 1000
80
+ RSPECTACLES_TIMEOUT = 15
84
81
 
85
82
  ## Contributing
86
83
 
data/bin/console ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bash
2
+
3
+ bundle exec irb -r rspectacles/app
@@ -0,0 +1,20 @@
1
+ require 'rspectacles/app/models/example'
2
+ require 'rspectacles/app/models/run'
3
+
4
+ class CreateRuns < ActiveRecord::Migration[5.1]
5
+ def change
6
+ create_table :runs do |t|
7
+ t.integer :total_time
8
+ t.string :rspec_run, null: false
9
+
10
+ t.timestamps
11
+ end
12
+
13
+ add_index :runs, :rspec_run, unique: true
14
+ add_reference :examples, :run
15
+
16
+ Example.all.distinct.pluck(:rspec_run).each do |run|
17
+ Run.where(rspec_run: run).first_or_create
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ class AssociateRuns < ActiveRecord::Migration[5.1]
2
+ def up
3
+ add_column :examples, :duration, :numeric, null: false, default: 0
4
+ remove_column :runs, :total_time
5
+
6
+ Run.all.find_each do |r|
7
+ r.update_attributes id: r.rspec_run
8
+ end
9
+
10
+ count = Example.all.size
11
+ Example.all.find_each do |e|
12
+ e.update_column :duration, e.properties['duration'].to_f
13
+
14
+ count -= 1
15
+ puts count
16
+ end
17
+ end
18
+
19
+ def down
20
+ remove_column :examples, :duration
21
+ add_column :runs, :total_time, :integer
22
+ end
23
+ end
data/db/schema.rb CHANGED
@@ -10,7 +10,7 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(version: 20170907205819) do
13
+ ActiveRecord::Schema.define(version: 20170912175547) do
14
14
 
15
15
  # These are extensions that must be enabled in order to support this database
16
16
  enable_extension "plpgsql"
@@ -18,7 +18,17 @@ ActiveRecord::Schema.define(version: 20170907205819) do
18
18
  create_table "examples", force: :cascade do |t|
19
19
  t.string "rspec_run", null: false
20
20
  t.text "properties"
21
+ t.bigint "run_id"
22
+ t.decimal "duration", default: "0.0", null: false
21
23
  t.index ["rspec_run"], name: "index_examples_on_rspec_run"
24
+ t.index ["run_id"], name: "index_examples_on_run_id"
25
+ end
26
+
27
+ create_table "runs", force: :cascade do |t|
28
+ t.string "rspec_run", null: false
29
+ t.datetime "created_at", null: false
30
+ t.datetime "updated_at", null: false
31
+ t.index ["rspec_run"], name: "index_runs_on_rspec_run", unique: true
22
32
  end
23
33
 
24
34
  end
@@ -39,7 +39,7 @@ module RSpectacles
39
39
  end
40
40
 
41
41
  def post_results(messages)
42
- HTTParty.post(full_uri, timeout: 5,
42
+ HTTParty.post(full_uri, timeout: config.timeout,
43
43
  body: { examples: messages }.to_json,
44
44
  headers: { 'Content-Type' => 'application/json' })
45
45
  rescue Net::ReadTimeout
@@ -1,4 +1,5 @@
1
1
  class Example < ActiveRecord::Base
2
+ belongs_to :run, primary_key: :rspec_run, foreign_key: :rspec_run
2
3
  serialize :properties, Hash
3
4
 
4
5
  def as_json(*_)
@@ -0,0 +1,11 @@
1
+ class Run < ActiveRecord::Base
2
+ has_many :examples, primary_key: :rspec_run, foreign_key: :rspec_run
3
+
4
+ def total_count
5
+ @total_count ||= examples.size
6
+ end
7
+
8
+ def runtime
9
+ @runtime ||= examples.sum(:duration)
10
+ end
11
+ end
@@ -1,3 +1,11 @@
1
+ table {
2
+ }
3
+
4
+ th, td {
5
+ text-align: left;
6
+ padding: 8px 16px;
7
+ }
8
+
1
9
  ul {
2
10
  border: 1px solid #eee;
3
11
  list-style-type: none;
@@ -1,5 +1,5 @@
1
1
  /*global define: true d3: true */
2
- define(['jquery', 'pathtree', 'mustache'], function ($, PathTree, Mustache) {
2
+ define(['jquery', 'pathtree', 'details', 'mustache'], function ($, PathTree, details) {
3
3
  'use strict';
4
4
 
5
5
 
@@ -62,31 +62,6 @@ define(['jquery', 'pathtree', 'mustache'], function ($, PathTree, Mustache) {
62
62
  return pad(min) + ':' + pad(sec);
63
63
  }
64
64
 
65
- function showDetails() {
66
- var data = showDetails.current
67
- , mappedData = $.extend({
68
- name: ''
69
- , line_number: ''
70
- , status: ''
71
- , duration: ''
72
- , time_or_count: options.isCount ? 'Examples' : 'ms'
73
- , minutes: ''
74
- , value: null
75
- }, data)
76
- , map
77
- ;
78
-
79
- if (mappedData.value) {
80
- if (!options.isCount) {
81
- mappedData.minutes = secToMin(mappedData.value);
82
- mappedData.value = parseInt(mappedData.value * 1000);
83
- }
84
- }
85
-
86
- $('.example-wrapper').html(Mustache.render(tmpl, mappedData));
87
- }
88
- showDetails.current = {};
89
-
90
65
  function getValue() {
91
66
  return options.isCount ?
92
67
  function () { return 1; } :
@@ -106,7 +81,7 @@ define(['jquery', 'pathtree', 'mustache'], function ($, PathTree, Mustache) {
106
81
  .attr("d", arc)
107
82
  .each(stash)
108
83
  .style("fill", getColor)
109
- .call(showDetails);
84
+ .call(details.update);
110
85
  }
111
86
 
112
87
  function onEnter(path) {
@@ -117,11 +92,8 @@ define(['jquery', 'pathtree', 'mustache'], function ($, PathTree, Mustache) {
117
92
  .style("fill", getColor)
118
93
  .style("fill-rule", "evenodd")
119
94
  .each(stash)
120
- .on('mouseover', function (d) {
121
- showDetails.current = d;
122
- showDetails();
123
- })
124
- .call(showDetails);
95
+ .on('mouseover', details.update)
96
+ .call(details.update);
125
97
  }
126
98
 
127
99
  function onExit(path) {
@@ -0,0 +1,51 @@
1
+ define(['jquery', 'mustache'], function ($, Mustache) {
2
+ var me
3
+ , defaults
4
+ , current = {}
5
+ , tmpl = $('#template').html()
6
+ , isCount = false
7
+ ;
8
+
9
+ defaults = function () {
10
+ return {
11
+ name: ''
12
+ , line_number: ''
13
+ , status: ''
14
+ , duration: ''
15
+ , time_or_count: isCount ? 'Examples' : 'ms'
16
+ , minutes: ''
17
+ , value: null
18
+ };
19
+ };
20
+
21
+ function secToMin(time) {
22
+ var pad = function (val) { return ('00' + val).slice(-2); }
23
+ , min = parseInt(time / 60)
24
+ , sec = parseInt(time % 60)
25
+ ;
26
+
27
+ return pad(min) + ':' + pad(sec);
28
+ }
29
+
30
+ function render() {
31
+ if (current.value) {
32
+ if (!isCount) {
33
+ current.minutes = secToMin(current.value);
34
+ current.value = parseInt(current.value * 1000);
35
+ }
36
+ }
37
+
38
+ $('.example-wrapper').html(Mustache.render(tmpl, current));
39
+ }
40
+
41
+ return {
42
+ update: function (d) {
43
+ current = $.extend({}, defaults(), d);
44
+ render();
45
+ }
46
+
47
+ , isCount: function (value) {
48
+ isCount = value;
49
+ }
50
+ };
51
+ });
@@ -22,28 +22,32 @@ define(['riffle'], function (riffle) {
22
22
 
23
23
  function batched(delay, maxSize) {
24
24
  var batch = []
25
+ , timer
25
26
  ;
26
27
 
27
28
  delay = delay || 100;
29
+ maxSize = maxSize || 100;
28
30
 
29
- return stream(function (o, i) {
30
- batch = batch.concat(i);
31
-
32
- function clear() {
33
- batch.length > 0 && o(batch);
34
- batch = [];
31
+ function clear(o) {
32
+ if (batch.length > 0) {
33
+ o(batch.splice(0, maxSize));
35
34
  }
36
35
 
37
- if (maxSize && batch.length > maxSize) {
38
- clear();
39
- } else {
40
- setTimeout(clear, delay);
36
+ if (batch.length < 1) {
37
+ clearInterval(timer);
38
+ timer = null;
41
39
  }
40
+ }
41
+
42
+ return stream(function (o, i) {
43
+ batch = batch.concat(i);
44
+
45
+ if (!timer) { timer = setInterval(function () { clear(o); }, delay); }
42
46
  });
43
47
  }
44
48
 
45
49
  jsonEvents = each.input(ajaxStream(ajaxUri).invoke());
46
50
 
47
- return { example: batched().input(jsonEvents) };
51
+ return { example: batched(10, 1000).input(jsonEvents) };
48
52
  };
49
53
  });
@@ -0,0 +1,24 @@
1
+ define(function () {
2
+ return function () {
3
+ var isCount = false;
4
+ var me;
5
+
6
+ d3.selectAll("input").on("change", function () {
7
+ var newCount = this.value === 'count';
8
+
9
+ if (newCount !== isCount) {
10
+ isCount = newCount;
11
+ me.onChange(isCount);
12
+ }
13
+ });
14
+
15
+ return me = {
16
+ isCount: function () {
17
+ return isCount;
18
+ },
19
+
20
+ onChange: function () {
21
+ }
22
+ }
23
+ }
24
+ });
@@ -1,5 +1,5 @@
1
1
  /*global require: true */
2
- require(['chart', 'exampleStream'], function (chart, examples) {
2
+ require(['zoomable', 'exampleStream'], function (chart, examples) {
3
3
  'use strict';
4
4
 
5
5
  var
@@ -0,0 +1,131 @@
1
+ define(['jquery', 'pathtree', 'details', 'form'], function ($, PathTree, details, countForm) {
2
+ return function (options) {
3
+ var width = 960,
4
+ height = 700,
5
+ radius = (Math.min(width, height) / 2) - 10,
6
+ form = countForm(),
7
+ me;
8
+
9
+ function arcTween(a) {
10
+ var i = d3.interpolate({ x: a.x0, dx: a.dx0 }, a);
11
+ return function tweener(t) {
12
+ var b = i(t);
13
+ a.x0 = b.x;
14
+ a.dx0 = b.dx;
15
+ return arc(b);
16
+ };
17
+ }
18
+
19
+ var x = d3.scale.linear()
20
+ .range([0, 2 * Math.PI]);
21
+
22
+ var y = d3.scale.sqrt()
23
+ .range([0, radius]);
24
+
25
+ var color = d3.scale.category20c();
26
+
27
+ var partition = d3.layout.partition()
28
+ .sort(function(a, b) { return d3.ascending(a.name, b.name); })
29
+ .value(function(d) { return d.size; });
30
+
31
+ var arc = d3.svg.arc()
32
+ .startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x))); })
33
+ .endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))); })
34
+ .innerRadius(function(d) { return Math.max(0, y(d.y)); })
35
+ .outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)); });
36
+
37
+ var svg = d3.select("body").append("svg")
38
+ .attr("width", width)
39
+ .attr("height", height)
40
+ .append("g")
41
+ .attr("transform", "translate(" + width / 2 + "," + (height / 2) + ")");
42
+
43
+ function getValue() {
44
+ return form.isCount() ?
45
+ function () { return 1; } :
46
+ function (d) { return d.size; };
47
+ }
48
+
49
+ function getColor(d) {
50
+ if (d.status && d.status === 'failed') {
51
+ return '#f00';
52
+ } else {
53
+ return color(((d.children ? d : d.parent) || {}).name);
54
+ }
55
+ }
56
+
57
+ function stash(d) {
58
+ d.x0 = d.x;
59
+ d.dx0 = d.dx;
60
+ }
61
+
62
+
63
+ function onUpdate(path) {
64
+ path
65
+ .attr("d", arc)
66
+ .each(stash)
67
+ .style("fill", getColor);
68
+ }
69
+
70
+ var render = function () {
71
+ var path = svg.datum(me.tree.nodes).selectAll("path")
72
+ .data(partition.value(getValue()).nodes);
73
+
74
+ onUpdate(path);
75
+ path
76
+ .enter().append("path")
77
+ .on('mouseover', details.update)
78
+ .attr("d", arc)
79
+ .style("fill", getColor)
80
+ .style("stroke", function (d) { return 'rgba(255,255,255,0.3)'; })
81
+ .style("fill-rule", "evenodd")
82
+ .on("click", click);
83
+
84
+ form.onChange = function (isCount) {
85
+ details.isCount(isCount);
86
+
87
+ path
88
+ .data(partition.value(getValue()).nodes)
89
+ .transition()
90
+ .duration(1500)
91
+ .attrTween("d", arcTween);
92
+ };
93
+
94
+ render = function () {
95
+ path.datum(me.tree.nodes)
96
+ .data(partition.value(getValue()).nodes);
97
+ };
98
+ };
99
+
100
+ function click(d) {
101
+ svg.transition()
102
+ .duration(750)
103
+ .tween("scale", function() {
104
+ var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
105
+ yd = d3.interpolate(y.domain(), [d.y, 1]),
106
+ yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
107
+ return function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); };
108
+ })
109
+ .selectAll("path")
110
+ .attrTween("d", function(d) { return function() { return arc(d); }; });
111
+ }
112
+
113
+ d3.select(self.frameElement).style("height", height + "px");
114
+
115
+ return me = {
116
+ tree: new PathTree(),
117
+
118
+ render: render,
119
+
120
+ reset: function () {
121
+ me.tree = new PathTree();
122
+ me.render();
123
+ },
124
+
125
+ push: function (data) {
126
+ me.tree.add(data);
127
+ me.render();
128
+ }
129
+ };
130
+ }
131
+ });
@@ -0,0 +1,34 @@
1
+ <!DOCTYPE html>
2
+
3
+ <html>
4
+ <head>
5
+ <title>RSpectacles</title>
6
+ <link rel='stylesheet' href='<%= versioned_stylesheet 'style' %>' />
7
+ </head>
8
+ <body>
9
+ <table>
10
+ <tr>
11
+ <th>Run</th>
12
+ <th>Examples</th>
13
+ <th>Time</th>
14
+ <th>Created At</th>
15
+ </tr>
16
+ <% @runs.each do |run| %>
17
+ <tr>
18
+ <td>
19
+ <a href='/watch/<%= run.rspec_run %>'>Run #<%= run.rspec_run %></a>
20
+ </td>
21
+ <td>
22
+ <%= run.examples.size %>
23
+ </td>
24
+ <td>
25
+ <% mm, ss = run.runtime.divmod(60) %>
26
+ <%= mm.to_i %>:<%= ss.to_i.to_s.rjust(2, '0') %>
27
+ </td>
28
+ <td>
29
+ <%= run.created_at.strftime('%Y-%m-%d %H:%M:%S') %>
30
+ </td>
31
+ </tr>
32
+ <% end %>
33
+ </table>
34
+ </body>
@@ -4,6 +4,7 @@ require 'json'
4
4
  require 'sinatra/activerecord'
5
5
  require 'rspectacles/config.rb'
6
6
  require 'rspectacles/app/models/example'
7
+ require 'rspectacles/app/models/run'
7
8
  require 'puma'
8
9
 
9
10
  module RSpectacles
@@ -27,6 +28,11 @@ module RSpectacles
27
28
  end
28
29
 
29
30
  # Routes
31
+ get '/' do
32
+ @runs = Run.all.limit(25).order(created_at: :desc)
33
+ erb :runs
34
+ end
35
+
30
36
  get '/watch/:key' do
31
37
  erb :index
32
38
  end
@@ -43,11 +49,14 @@ module RSpectacles
43
49
  post '/examples' do
44
50
  payload = JSON.parse(request.body.read)
45
51
 
52
+ run = Run.where(rspec_run: payload['examples'].first['rspec_run']).first_or_create
46
53
  data = payload['examples'].map do |args|
47
- { rspec_run: args['rspec_run'], properties: args }
54
+ { rspec_run: args['rspec_run'], duration: args['duration'].to_f, properties: args }
48
55
  end
49
56
 
50
- { errors: Example.create(data).count { |i| !i.persisted? } }.to_json
57
+ examples = Example.create(data)
58
+
59
+ { errors: examples.count { |i| !i.persisted? } }.to_json
51
60
  end
52
61
  end
53
62
  end
@@ -11,8 +11,9 @@ module RSpectacles
11
11
  def defaults
12
12
  {
13
13
  sinatra_port: ENV['RSPECTACLES_PORT'] || ENV['PORT'] || 4567,
14
- batch_size: (ENV['RSPECTACLES_BATCH_SIZE'] || 100).to_i,
15
- last_run_primary_key: ENV['RSPECTACLES_LAST_RUN_KEY'] || ENV['CIRCLE_BUILD_NUM'] || 'rspec-last-run',
14
+ batch_size: (ENV['RSPECTACLES_BATCH_SIZE'] || 1000).to_i,
15
+ last_run_primary_key: ENV['RSPECTACLES_RUN_KEY'] || ENV['CIRCLE_BUILD_NUM'] || 'rspec-current-run',
16
+ timeout: (ENV['RSPECTACLES_TIMEOUT'] || 15).to_i,
16
17
  rspectacles_url: ENV['RSPECTACLES_URL']
17
18
  }
18
19
  end
@@ -1,3 +1,3 @@
1
1
  module RSpectacles
2
- VERSION = '0.3.1'
2
+ VERSION = '0.4.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspectacles
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Wheeler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-08 00:00:00.000000000 Z
11
+ date: 2017-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -126,7 +126,7 @@ description: Visualize rspec test running in the browser
126
126
  email:
127
127
  - mwheeler@g2crowd.com
128
128
  executables:
129
- - rspectacles
129
+ - console
130
130
  extensions: []
131
131
  extra_rdoc_files: []
132
132
  files:
@@ -138,9 +138,11 @@ files:
138
138
  - Procfile
139
139
  - README.md
140
140
  - Rakefile
141
- - bin/rspectacles
141
+ - bin/console
142
142
  - config.ru
143
143
  - db/migrate/20170907205819_create_examples_table.rb
144
+ - db/migrate/20170912153508_create_runs.rb
145
+ - db/migrate/20170912175547_associate_runs.rb
144
146
  - db/schema.rb
145
147
  - lib/rspectacles.rb
146
148
  - lib/rspectacles/adapter/batched_logger.rb
@@ -148,10 +150,13 @@ files:
148
150
  - lib/rspectacles/app.rb
149
151
  - lib/rspectacles/app/helpers.rb
150
152
  - lib/rspectacles/app/models/example.rb
153
+ - lib/rspectacles/app/models/run.rb
151
154
  - lib/rspectacles/app/public/css/style.css
152
155
  - lib/rspectacles/app/public/js/chart.js
153
156
  - lib/rspectacles/app/public/js/d3.js
157
+ - lib/rspectacles/app/public/js/details.js
154
158
  - lib/rspectacles/app/public/js/exampleStream.js
159
+ - lib/rspectacles/app/public/js/form.js
155
160
  - lib/rspectacles/app/public/js/jquery.js
156
161
  - lib/rspectacles/app/public/js/mustache.js
157
162
  - lib/rspectacles/app/public/js/pathtree.js
@@ -159,7 +164,9 @@ files:
159
164
  - lib/rspectacles/app/public/js/require.js
160
165
  - lib/rspectacles/app/public/js/riffle.js
161
166
  - lib/rspectacles/app/public/js/script.js
167
+ - lib/rspectacles/app/public/js/zoomable.js
162
168
  - lib/rspectacles/app/views/index.erb
169
+ - lib/rspectacles/app/views/runs.erb
163
170
  - lib/rspectacles/config.rb
164
171
  - lib/rspectacles/config/database.yml
165
172
  - lib/rspectacles/formatter/base.rb
data/bin/rspectacles DELETED
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- begin
4
- require 'rspectacles/app.rb'
5
- rescue LoadError => e
6
- require 'rubygems'
7
- path = File.expand_path '../../lib', __FILE__
8
- $:.unshift(path) if File.directory?(path) && !$:.include?(path)
9
- require 'rspectacles/app.rb'
10
- end
11
-
12
- Thin::Server.start RSpectacles::App, '0.0.0.0', RSpectacles.config.sinatra_port