rspectacles 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +46 -0
- data/Rakefile +1 -0
- data/bin/rspectacles +16 -0
- data/lib/rspectacles/app/public/css/style.css +24 -0
- data/lib/rspectacles/app/public/js/chart.js +129 -0
- data/lib/rspectacles/app/public/js/d3.js +8810 -0
- data/lib/rspectacles/app/public/js/exampleStream.js +42 -0
- data/lib/rspectacles/app/public/js/jquery.js +8829 -0
- data/lib/rspectacles/app/public/js/pathtree.js +51 -0
- data/lib/rspectacles/app/public/js/plates.js +666 -0
- data/lib/rspectacles/app/public/js/require.js +2053 -0
- data/lib/rspectacles/app/public/js/riffle.js +200 -0
- data/lib/rspectacles/app/public/js/script.js +26 -0
- data/lib/rspectacles/app/views/index.erb +29 -0
- data/lib/rspectacles/app.rb +60 -0
- data/lib/rspectacles/redis_formatter.rb +84 -0
- data/lib/rspectacles/version.rb +3 -0
- data/lib/rspectacles.rb +1 -0
- data/rspectacles.gemspec +27 -0
- data/spec/javascripts/resources/qunit.css +244 -0
- data/spec/javascripts/resources/qunit.js +2212 -0
- data/spec/javascripts/test.html +20 -0
- data/spec/javascripts/tests/pathtree_spec.js +21 -0
- metadata +155 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg/*
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
rspectacles (0.0.1)
|
5
|
+
em-hiredis (~> 0.2.1)
|
6
|
+
rake
|
7
|
+
sinatra (~> 1.4.3)
|
8
|
+
thin (>= 1.5.0)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: http://rubygems.org/
|
12
|
+
specs:
|
13
|
+
daemons (1.1.9)
|
14
|
+
diff-lcs (1.1.3)
|
15
|
+
em-hiredis (0.2.1)
|
16
|
+
hiredis (~> 0.4.0)
|
17
|
+
eventmachine (1.0.3)
|
18
|
+
hiredis (0.4.5)
|
19
|
+
rack (1.5.2)
|
20
|
+
rack-protection (1.5.0)
|
21
|
+
rack
|
22
|
+
rake (10.1.0)
|
23
|
+
rspec (2.12.0)
|
24
|
+
rspec-core (~> 2.12.0)
|
25
|
+
rspec-expectations (~> 2.12.0)
|
26
|
+
rspec-mocks (~> 2.12.0)
|
27
|
+
rspec-core (2.12.2)
|
28
|
+
rspec-expectations (2.12.1)
|
29
|
+
diff-lcs (~> 1.1.3)
|
30
|
+
rspec-mocks (2.12.2)
|
31
|
+
sinatra (1.4.3)
|
32
|
+
rack (~> 1.4)
|
33
|
+
rack-protection (~> 1.4)
|
34
|
+
tilt (~> 1.3, >= 1.3.4)
|
35
|
+
thin (1.5.1)
|
36
|
+
daemons (>= 1.0.9)
|
37
|
+
eventmachine (>= 0.12.6)
|
38
|
+
rack (>= 1.0.0)
|
39
|
+
tilt (1.4.1)
|
40
|
+
|
41
|
+
PLATFORMS
|
42
|
+
ruby
|
43
|
+
|
44
|
+
DEPENDENCIES
|
45
|
+
rspec
|
46
|
+
rspectacles!
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/bin/rspectacles
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
|
4
|
+
require 'eventmachine'
|
5
|
+
EM.run do
|
6
|
+
begin
|
7
|
+
require 'rspectacles/app.rb'
|
8
|
+
rescue LoadError => e
|
9
|
+
require 'rubygems'
|
10
|
+
path = File.expand_path '../../lib', __FILE__
|
11
|
+
$:.unshift(path) if File.directory?(path) && !$:.include?(path)
|
12
|
+
require 'rspectacles/app.rb'
|
13
|
+
end
|
14
|
+
|
15
|
+
Thin::Server.start RSpectacles::App, '0.0.0.0', 4567
|
16
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
body {
|
2
|
+
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
3
|
+
margin: auto;
|
4
|
+
position: relative;
|
5
|
+
width: 960px;
|
6
|
+
}
|
7
|
+
|
8
|
+
form {
|
9
|
+
position: absolute;
|
10
|
+
right: 10px;
|
11
|
+
top: 10px;
|
12
|
+
}
|
13
|
+
|
14
|
+
.example-details {
|
15
|
+
position: fixed;
|
16
|
+
top: 0;
|
17
|
+
left: 0;
|
18
|
+
padding: 20px;
|
19
|
+
background: rgba(255, 255, 255, 0.5);
|
20
|
+
width: 100%
|
21
|
+
z-index: 100;
|
22
|
+
overflow: auto;
|
23
|
+
max-width: 300px;
|
24
|
+
}
|
@@ -0,0 +1,129 @@
|
|
1
|
+
/*global define: true */
|
2
|
+
define(['jquery', 'pathtree'], function ($, PathTree) {
|
3
|
+
'use strict';
|
4
|
+
|
5
|
+
function chart(options) {
|
6
|
+
var svg, partition, arc, me
|
7
|
+
, tmpl = $('#template').html()
|
8
|
+
;
|
9
|
+
|
10
|
+
options = $.extend({
|
11
|
+
width: 960
|
12
|
+
, height: 700
|
13
|
+
, color: d3.scale.category20c()
|
14
|
+
, isCount: false
|
15
|
+
}, options);
|
16
|
+
|
17
|
+
options.radius = Math.min(options.width, options.height) / 2;
|
18
|
+
|
19
|
+
svg = d3.select("body").append("svg")
|
20
|
+
.attr("width", options.width)
|
21
|
+
.attr("height", options.height)
|
22
|
+
.append("g")
|
23
|
+
.attr("transform", "translate(" +
|
24
|
+
options.width / 2 + "," +
|
25
|
+
options.height * 0.52 + ")");
|
26
|
+
|
27
|
+
partition = d3.layout.partition()
|
28
|
+
.sort(null)
|
29
|
+
.size([2 * Math.PI, options.radius * options.radius]);
|
30
|
+
|
31
|
+
arc = d3.svg.arc()
|
32
|
+
.startAngle(function (d) { return d.x; })
|
33
|
+
.endAngle(function (d) { return d.x + d.dx; })
|
34
|
+
.innerRadius(function (d) { return Math.sqrt(d.y); })
|
35
|
+
.outerRadius(function (d) { return Math.sqrt(d.y + d.dy); });
|
36
|
+
|
37
|
+
// Stash the old values for transition.
|
38
|
+
function stash(d) {
|
39
|
+
d.x0 = d.x;
|
40
|
+
d.dx0 = d.dx;
|
41
|
+
}
|
42
|
+
|
43
|
+
// Interpolate the arcs in data space.
|
44
|
+
function arcTween(a) {
|
45
|
+
var i = d3.interpolate({x: a.x0, dx: a.dx0}, a);
|
46
|
+
return function tweener(t) {
|
47
|
+
var b = i(t);
|
48
|
+
a.x0 = b.x;
|
49
|
+
a.dx0 = b.dx;
|
50
|
+
return arc(b);
|
51
|
+
};
|
52
|
+
}
|
53
|
+
|
54
|
+
function showDetails(data) {
|
55
|
+
var mappedData = $.extend({
|
56
|
+
name: ''
|
57
|
+
, line_number: ''
|
58
|
+
, status: ''
|
59
|
+
, duration: ''
|
60
|
+
, time_or_count: options.isCount ? 'Examples' : 'Seconds'
|
61
|
+
}, data)
|
62
|
+
;
|
63
|
+
|
64
|
+
!options.isCount && (mappedData.value = mappedData.value.toFixed(3));
|
65
|
+
|
66
|
+
$('.example-wrapper').html(Plates.bind(tmpl, mappedData));
|
67
|
+
}
|
68
|
+
|
69
|
+
function getValue() {
|
70
|
+
return options.isCount ?
|
71
|
+
function () { return 1; } :
|
72
|
+
function (d) { return d.size; };
|
73
|
+
}
|
74
|
+
|
75
|
+
function render() {
|
76
|
+
var path = svg.datum(me.tree.nodes).selectAll("path")
|
77
|
+
.data(partition.value(getValue()).nodes);
|
78
|
+
|
79
|
+
path
|
80
|
+
.attr("d", arc)
|
81
|
+
.each(stash);
|
82
|
+
|
83
|
+
path.enter().append("path")
|
84
|
+
.attr("display", function (d) { return d.depth ? null : "none"; }) // hide inner ring
|
85
|
+
.attr("d", arc)
|
86
|
+
.style("stroke", function (d) { return '#fff'; })
|
87
|
+
.style("fill", function (d) {
|
88
|
+
if (d.status && d.status === 'failed') {
|
89
|
+
return '#f00';
|
90
|
+
} else {
|
91
|
+
return options.color(((d.children ? d : d.parent) || {}).name);
|
92
|
+
}
|
93
|
+
})
|
94
|
+
.style("fill-rule", "evenodd")
|
95
|
+
.each(stash)
|
96
|
+
.on('mouseover', showDetails);
|
97
|
+
|
98
|
+
path.exit().remove();
|
99
|
+
|
100
|
+
d3.selectAll("input").on("change", function change() {
|
101
|
+
options.isCount = this.value === 'count';
|
102
|
+
|
103
|
+
path
|
104
|
+
.data(partition.value(getValue()).nodes)
|
105
|
+
.transition()
|
106
|
+
.duration(1500)
|
107
|
+
.attrTween("d", arcTween);
|
108
|
+
});
|
109
|
+
}
|
110
|
+
|
111
|
+
return me = {
|
112
|
+
tree: new PathTree()
|
113
|
+
|
114
|
+
, render: render
|
115
|
+
|
116
|
+
, reset: function () {
|
117
|
+
me.tree = new PathTree();
|
118
|
+
me.render();
|
119
|
+
}
|
120
|
+
|
121
|
+
, push: function (data) {
|
122
|
+
me.tree.add(data);
|
123
|
+
me.render();
|
124
|
+
}
|
125
|
+
};
|
126
|
+
}
|
127
|
+
|
128
|
+
return chart;
|
129
|
+
});
|