merb_screw_unit 0.9.4
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/LICENSE +20 -0
- data/README +170 -0
- data/Rakefile +70 -0
- data/TODO +15 -0
- data/app/controllers/application.rb +5 -0
- data/app/controllers/main.rb +7 -0
- data/app/helpers/application_helper.rb +76 -0
- data/app/views/layout/merb_screw_unit.html.erb +37 -0
- data/app/views/main/index.html.erb +1 -0
- data/lib/merb_screw_unit/merbtasks.rb +166 -0
- data/lib/merb_screw_unit/slicetasks.rb +18 -0
- data/lib/merb_screw_unit.rb +84 -0
- data/public/javascripts/jquery-1.2.3.js +3408 -0
- data/public/javascripts/jquery.fn.js +29 -0
- data/public/javascripts/jquery.print.js +108 -0
- data/public/javascripts/master.js +0 -0
- data/public/javascripts/screw.behaviors.js +91 -0
- data/public/javascripts/screw.builder.js +84 -0
- data/public/javascripts/screw.events.js +38 -0
- data/public/javascripts/screw.matchers.js +74 -0
- data/public/javascripts/screw.mock.js +78 -0
- data/public/stylesheets/master.css +2 -0
- data/public/stylesheets/screw.css +90 -0
- data/spec/controllers/main_spec.rb +61 -0
- data/spec/merb_screw_unit_spec.rb +130 -0
- data/spec/spec_helper.rb +44 -0
- data/stubs/app/controllers/application.rb +2 -0
- data/stubs/app/controllers/main.rb +2 -0
- metadata +111 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
(function($) {
|
2
|
+
$.fn.fn = function() {
|
3
|
+
var self = this;
|
4
|
+
var extension = arguments[0], name = arguments[0];
|
5
|
+
if (typeof name == "string") {
|
6
|
+
return apply(self, name, $.makeArray(arguments).slice(1, arguments.length));
|
7
|
+
} else {
|
8
|
+
$.each(extension, function(key, value) {
|
9
|
+
define(self, key, value);
|
10
|
+
});
|
11
|
+
return self;
|
12
|
+
}
|
13
|
+
}
|
14
|
+
function define(self, name, fn) {
|
15
|
+
self.data(namespacedName(name), fn);
|
16
|
+
};
|
17
|
+
function apply(self, name, args) {
|
18
|
+
var result;
|
19
|
+
self.each(function(i, item) {
|
20
|
+
var fn = $(item).data(namespacedName(name));
|
21
|
+
if (fn) result = fn.apply(item, args)
|
22
|
+
else throw(name + " is not defined");
|
23
|
+
});
|
24
|
+
return result;
|
25
|
+
};
|
26
|
+
function namespacedName(name) {
|
27
|
+
return 'fn.' + name;
|
28
|
+
}
|
29
|
+
})(jQuery);
|
@@ -0,0 +1,108 @@
|
|
1
|
+
(function($) {
|
2
|
+
|
3
|
+
function print_array(obj, opts) {
|
4
|
+
var result = [];
|
5
|
+
for (var i = 0; i < Math.min(opts.max_array, obj.length); i++)
|
6
|
+
result.push($.print(obj[i], $.extend({}, opts, { max_array: 3, max_string: 40 })));
|
7
|
+
|
8
|
+
if (obj.length > opts.max_array)
|
9
|
+
result.push((obj.length - opts.max_array) + ' more...');
|
10
|
+
if (result.length == 0) return "[]"
|
11
|
+
return "[ " + result.join(", ") + " ]";
|
12
|
+
}
|
13
|
+
|
14
|
+
function print_element(obj) {
|
15
|
+
if (obj.nodeType == 1) {
|
16
|
+
var result = [];
|
17
|
+
var properties = [ 'className', 'id' ];
|
18
|
+
var extra = {
|
19
|
+
'input': ['type', 'name', 'value'],
|
20
|
+
'a': ['href', 'target'],
|
21
|
+
'form': ['method', 'action']
|
22
|
+
};
|
23
|
+
$.each(properties.concat(extra[obj.tagName.toLowerCase()] || []), function() {
|
24
|
+
if (obj[this])
|
25
|
+
result.push(' ' + this.replace('className', 'class') + "=" + $.print(obj[this]))
|
26
|
+
});
|
27
|
+
return "<" + obj.tagName.toLowerCase()
|
28
|
+
+ result.join('') + ">";
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
function print_object(obj, opts) {
|
33
|
+
var seen = opts.seen || [];
|
34
|
+
|
35
|
+
var result = [], key, value;
|
36
|
+
for (var k in obj) {
|
37
|
+
if (obj.hasOwnProperty(k) && $.inArray(obj[k], seen) < 0) {
|
38
|
+
seen.push(obj[k]);
|
39
|
+
value = $.print(obj[k], $.extend({}, opts, { max_array: 6, max_string: 40, seen: seen }));
|
40
|
+
} else
|
41
|
+
value = "...";
|
42
|
+
result.push(k + ": " + value);
|
43
|
+
}
|
44
|
+
if (result.length == 0) return "{}";
|
45
|
+
return "{ " + result.join(", ") + " }";
|
46
|
+
}
|
47
|
+
|
48
|
+
function print_jquery(obj) {
|
49
|
+
}
|
50
|
+
|
51
|
+
function print_string(value, opts) {
|
52
|
+
var character_substitutions = {
|
53
|
+
'\b': '\\b',
|
54
|
+
'\t': '\\t',
|
55
|
+
'\n': '\\n',
|
56
|
+
'\f': '\\f',
|
57
|
+
'\r': '\\r',
|
58
|
+
'"' : '\\"',
|
59
|
+
'\\': '\\\\'
|
60
|
+
};
|
61
|
+
var r = /["\\\x00-\x1f\x7f-\x9f]/g;
|
62
|
+
|
63
|
+
var str = r.test(value)
|
64
|
+
? '"' + value.replace(r, function (a) {
|
65
|
+
var c = character_substitutions[a];
|
66
|
+
if (c) return c;
|
67
|
+
c = a.charCodeAt();
|
68
|
+
return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
|
69
|
+
}) + '"'
|
70
|
+
: '"' + value + '"';
|
71
|
+
if (str.length > opts.max_string)
|
72
|
+
return str.slice(0, opts.max_string + 1) + '..."';
|
73
|
+
else
|
74
|
+
return str;
|
75
|
+
}
|
76
|
+
|
77
|
+
$.print = function(obj, options) {
|
78
|
+
var opts = $.extend({}, { max_array: 10, max_string: 100 }, options);
|
79
|
+
|
80
|
+
if (typeof obj == 'undefined')
|
81
|
+
return "undefined";
|
82
|
+
else if (typeof obj == 'boolean')
|
83
|
+
return obj.toString();
|
84
|
+
else if (!obj && typeof obj == 'number')
|
85
|
+
return 'NaN';
|
86
|
+
else if (!obj)
|
87
|
+
return "null";
|
88
|
+
else if (typeof obj == 'string')
|
89
|
+
return print_string(obj, opts);
|
90
|
+
else if (obj instanceof RegExp)
|
91
|
+
return obj.toString();
|
92
|
+
else if (typeof obj == 'function' || obj instanceof Function)
|
93
|
+
return obj.toString().match(/^([^)]*\))/)[1];
|
94
|
+
else if (obj instanceof Array)
|
95
|
+
return print_array(obj, opts);
|
96
|
+
else if (obj.nodeType)
|
97
|
+
return print_element(obj);
|
98
|
+
else if (obj instanceof jQuery)
|
99
|
+
return "$(" + $.print(obj.get()) + ")";
|
100
|
+
else if (obj instanceof Error)
|
101
|
+
return print_object(obj, $.extend({}, options, { max_string: 200 }));
|
102
|
+
else if (obj instanceof Object)
|
103
|
+
return print_object(obj, opts);
|
104
|
+
else
|
105
|
+
return obj.toString().replace(/\n\s*/g, '');
|
106
|
+
}
|
107
|
+
|
108
|
+
})(jQuery);
|
File without changes
|
@@ -0,0 +1,91 @@
|
|
1
|
+
(function($) {
|
2
|
+
$(Screw).bind('loaded', function() {
|
3
|
+
$('.status').fn({
|
4
|
+
display: function() {
|
5
|
+
$(this).text(
|
6
|
+
$('.passed').length + $('.failed').length + ' test(s), ' + $('.failed').length + ' failure(s)'
|
7
|
+
);
|
8
|
+
}
|
9
|
+
});
|
10
|
+
|
11
|
+
$('.describe').fn({
|
12
|
+
parent: function() {
|
13
|
+
return $(this).parent('.describes').parent('.describe');
|
14
|
+
},
|
15
|
+
|
16
|
+
run_befores: function() {
|
17
|
+
$(this).fn('parent').fn('run_befores');
|
18
|
+
$(this).children('.befores').children('.before').fn('run');
|
19
|
+
},
|
20
|
+
|
21
|
+
run_afters: function() {
|
22
|
+
$(this).fn('parent').fn('run_afters');
|
23
|
+
$(this).children('.afters').children('.after').fn('run');
|
24
|
+
},
|
25
|
+
|
26
|
+
enqueue: function() {
|
27
|
+
$(this).children('.its').children('.it').fn('enqueue');
|
28
|
+
$(this).children('.describes').children('.describe').fn('enqueue');
|
29
|
+
},
|
30
|
+
|
31
|
+
selector: function() {
|
32
|
+
return $(this).fn('parent').fn('selector')
|
33
|
+
+ ' > .describes > .describe:eq(' + $(this).parent('.describes').children('.describe').index(this) + ')';
|
34
|
+
}
|
35
|
+
});
|
36
|
+
|
37
|
+
$('body > .describe').fn({
|
38
|
+
selector: function() { return 'body > .describe' }
|
39
|
+
});
|
40
|
+
|
41
|
+
$('.it').fn({
|
42
|
+
parent: function() {
|
43
|
+
return $(this).parent('.its').parent('.describe');
|
44
|
+
},
|
45
|
+
|
46
|
+
run: function() {
|
47
|
+
try {
|
48
|
+
try {
|
49
|
+
$(this).fn('parent').fn('run_befores');
|
50
|
+
$(this).data('screwunit.run')();
|
51
|
+
} finally {
|
52
|
+
$(this).fn('parent').fn('run_afters');
|
53
|
+
}
|
54
|
+
$(this).trigger('passed');
|
55
|
+
} catch(e) {
|
56
|
+
$(this).trigger('failed', [e]);
|
57
|
+
}
|
58
|
+
},
|
59
|
+
|
60
|
+
enqueue: function() {
|
61
|
+
var self = $(this).trigger('enqueued');
|
62
|
+
$(Screw)
|
63
|
+
.queue(function() {
|
64
|
+
self.fn('run');
|
65
|
+
setTimeout(function() { $(Screw).dequeue() }, 0);
|
66
|
+
});
|
67
|
+
},
|
68
|
+
|
69
|
+
selector: function() {
|
70
|
+
return $(this).fn('parent').fn('selector')
|
71
|
+
+ ' > .its > .it:eq(' + $(this).parent('.its').children('.it').index(this) + ')';
|
72
|
+
}
|
73
|
+
});
|
74
|
+
|
75
|
+
$('.before').fn({
|
76
|
+
run: function() { $(this).data('screwunit.run')() }
|
77
|
+
});
|
78
|
+
|
79
|
+
$('.after').fn({
|
80
|
+
run: function() { $(this).data('screwunit.run')() }
|
81
|
+
});
|
82
|
+
|
83
|
+
$(Screw).trigger('before');
|
84
|
+
var to_run = unescape(location.search.slice(1)) || 'body > .describe > .describes > .describe';
|
85
|
+
$(to_run)
|
86
|
+
.focus()
|
87
|
+
.eq(0).trigger('scroll').end()
|
88
|
+
.fn('enqueue');
|
89
|
+
$(Screw).queue(function() { $(Screw).trigger('after') });
|
90
|
+
})
|
91
|
+
})(jQuery);
|
@@ -0,0 +1,84 @@
|
|
1
|
+
var Screw = (function($) {
|
2
|
+
var screw = {
|
3
|
+
Unit: function(fn) {
|
4
|
+
var contents = fn.toString().match(/^[^\{]*{((.*\n*)*)}/m)[1];
|
5
|
+
var fn = new Function("matchers", "specifications",
|
6
|
+
"with (specifications) { with (matchers) { " + contents + " } }"
|
7
|
+
);
|
8
|
+
|
9
|
+
$(Screw).queue(function() {
|
10
|
+
Screw.Specifications.context.push($('body > .describe'));
|
11
|
+
fn.call(this, Screw.Matchers, Screw.Specifications);
|
12
|
+
Screw.Specifications.context.pop();
|
13
|
+
$(this).dequeue();
|
14
|
+
});
|
15
|
+
},
|
16
|
+
|
17
|
+
Specifications: {
|
18
|
+
context: [],
|
19
|
+
|
20
|
+
describe: function(name, fn) {
|
21
|
+
var describe = $('<li class="describe">')
|
22
|
+
.append($('<h1>').text(name))
|
23
|
+
.append('<ol class="befores">')
|
24
|
+
.append('<ul class="its">')
|
25
|
+
.append('<ul class="describes">')
|
26
|
+
.append('<ol class="afters">');
|
27
|
+
|
28
|
+
this.context.push(describe);
|
29
|
+
fn.call();
|
30
|
+
this.context.pop();
|
31
|
+
|
32
|
+
this.context[this.context.length-1]
|
33
|
+
.children('.describes')
|
34
|
+
.append(describe);
|
35
|
+
},
|
36
|
+
|
37
|
+
it: function(name, fn) {
|
38
|
+
var it = $('<li class="it">')
|
39
|
+
.append($('<h2>').text(name))
|
40
|
+
.data('screwunit.run', fn);
|
41
|
+
|
42
|
+
this.context[this.context.length-1]
|
43
|
+
.children('.its')
|
44
|
+
.append(it);
|
45
|
+
},
|
46
|
+
|
47
|
+
before: function(fn) {
|
48
|
+
var before = $('<li class="before">')
|
49
|
+
.data('screwunit.run', fn);
|
50
|
+
|
51
|
+
this.context[this.context.length-1]
|
52
|
+
.children('.befores')
|
53
|
+
.append(before);
|
54
|
+
},
|
55
|
+
|
56
|
+
after: function(fn) {
|
57
|
+
var after = $('<li class="after">')
|
58
|
+
.data('screwunit.run', fn);
|
59
|
+
|
60
|
+
this.context[this.context.length-1]
|
61
|
+
.children('.afters')
|
62
|
+
.append(after);
|
63
|
+
}
|
64
|
+
}
|
65
|
+
};
|
66
|
+
|
67
|
+
$(screw).queue(function() { $(screw).trigger('loading') });
|
68
|
+
$(function() {
|
69
|
+
$('<div class="describe">')
|
70
|
+
.append('<h3 class="status">')
|
71
|
+
.append('<ol class="befores">')
|
72
|
+
.append('<ul class="describes">')
|
73
|
+
.append('<ol class="afters">')
|
74
|
+
.appendTo('body');
|
75
|
+
|
76
|
+
$(screw).dequeue();
|
77
|
+
$("#dom")[0].onload = function() {
|
78
|
+
setTimeout(function() {
|
79
|
+
$(screw).trigger('loaded');
|
80
|
+
}, 200);
|
81
|
+
};
|
82
|
+
});
|
83
|
+
return screw;
|
84
|
+
})(jQuery);
|
@@ -0,0 +1,38 @@
|
|
1
|
+
(function($) {
|
2
|
+
$(Screw)
|
3
|
+
.bind('loaded', function() {
|
4
|
+
$('.describe, .it')
|
5
|
+
.click(function() {
|
6
|
+
document.location = location.href.split('?')[0] + '?' + $(this).fn('selector');
|
7
|
+
return false;
|
8
|
+
})
|
9
|
+
.focus(function() {
|
10
|
+
return $(this).addClass('focused');
|
11
|
+
})
|
12
|
+
.bind('scroll', function() {
|
13
|
+
document.body.scrollTop = $(this).offset().top;
|
14
|
+
});
|
15
|
+
|
16
|
+
$('.it')
|
17
|
+
.bind('enqueued', function() {
|
18
|
+
$(this).addClass('enqueued');
|
19
|
+
})
|
20
|
+
.bind('running', function() {
|
21
|
+
$(this).addClass('running');
|
22
|
+
})
|
23
|
+
.bind('passed', function() {
|
24
|
+
$(this).addClass('passed');
|
25
|
+
})
|
26
|
+
.bind('failed', function(e, reason) {
|
27
|
+
$(this)
|
28
|
+
.addClass('failed')
|
29
|
+
.append($('<p class="error">').text(reason.toString()));
|
30
|
+
})
|
31
|
+
})
|
32
|
+
.bind('before', function() {
|
33
|
+
$('.status').text('Running...');
|
34
|
+
})
|
35
|
+
.bind('after', function() {
|
36
|
+
$('.status').fn('display')
|
37
|
+
})
|
38
|
+
})(jQuery);
|
@@ -0,0 +1,74 @@
|
|
1
|
+
Screw.Matchers = (function($) {
|
2
|
+
return matchers = {
|
3
|
+
expect: function(actual) {
|
4
|
+
return {
|
5
|
+
to: function(matcher, expected, not) {
|
6
|
+
var matched = matcher.match(expected, actual);
|
7
|
+
if (not ? matched : !matched) {
|
8
|
+
throw(matcher.failure_message(expected, actual, not));
|
9
|
+
}
|
10
|
+
},
|
11
|
+
|
12
|
+
to_not: function(matcher, expected) {
|
13
|
+
this.to(matcher, expected, true);
|
14
|
+
}
|
15
|
+
}
|
16
|
+
},
|
17
|
+
|
18
|
+
have: {
|
19
|
+
match: function(expected, actual) {
|
20
|
+
return actual.find(expected).length > 0;
|
21
|
+
},
|
22
|
+
failure_message: function(expected, actual, not) {
|
23
|
+
return 'expected ' + $.print(actual) + (not ? ' to not have ' : ' to have ') + $.print(expected);
|
24
|
+
}
|
25
|
+
},
|
26
|
+
|
27
|
+
equal: {
|
28
|
+
match: function(expected, actual) {
|
29
|
+
if (expected instanceof Array) {
|
30
|
+
for (var i = 0; i < actual.length; i++)
|
31
|
+
if (!Screw.Matchers.equal.match(expected[i], actual[i])) return false;
|
32
|
+
return actual.length == expected.length;
|
33
|
+
} else if (expected instanceof Object) {
|
34
|
+
for (var key in expected)
|
35
|
+
if (expected[key] != actual[key]) return false;
|
36
|
+
for (var key in actual)
|
37
|
+
if (actual[key] != expected[key]) return false;
|
38
|
+
return true;
|
39
|
+
} else {
|
40
|
+
return expected == actual;
|
41
|
+
}
|
42
|
+
},
|
43
|
+
|
44
|
+
failure_message: function(expected, actual, not) {
|
45
|
+
return 'expected ' + $.print(actual) + (not ? ' to not equal ' : ' to equal ') + $.print(expected);
|
46
|
+
}
|
47
|
+
},
|
48
|
+
|
49
|
+
match: {
|
50
|
+
match: function(expected, actual) {
|
51
|
+
if (expected.constructor == RegExp)
|
52
|
+
return expected.exec(actual.toString());
|
53
|
+
else
|
54
|
+
return actual.indexOf(expected) > -1;
|
55
|
+
},
|
56
|
+
|
57
|
+
failure_message: function(expected, actual, not) {
|
58
|
+
return 'expected ' + $.print(actual) + (not ? ' to not match ' : ' to match ') + $.print(expected);
|
59
|
+
}
|
60
|
+
},
|
61
|
+
|
62
|
+
be_empty: {
|
63
|
+
match: function(expected, actual) {
|
64
|
+
if (actual.length == undefined) throw(actual.toString() + " does not respond to length");
|
65
|
+
|
66
|
+
return actual.length == 0;
|
67
|
+
},
|
68
|
+
|
69
|
+
failure_message: function(expected, actual, not) {
|
70
|
+
return 'expected ' + $.print(actual) + (not ? ' to not be empty' : ' to be empty');
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
})(jQuery);
|
@@ -0,0 +1,78 @@
|
|
1
|
+
Screw.Mock = {
|
2
|
+
confirmWith: function(val) {
|
3
|
+
Screw.Mock.confirmText = null;
|
4
|
+
iframeWindow.confirm = function(str) {
|
5
|
+
Screw.Mock.confirmText = str;
|
6
|
+
return val;
|
7
|
+
};
|
8
|
+
}
|
9
|
+
};
|
10
|
+
Screw.XHR = function() {};
|
11
|
+
Screw.XHR.returns = function(str, type, status) {
|
12
|
+
codes = {
|
13
|
+
100: "Continue",
|
14
|
+
101: "Switching Protocols",
|
15
|
+
200: "OK",
|
16
|
+
201: "Created",
|
17
|
+
202: "Accepted",
|
18
|
+
203: "Non-Authoritative Information",
|
19
|
+
204: "No Content",
|
20
|
+
205: "Reset Content",
|
21
|
+
206: "Partial Content",
|
22
|
+
300: "Multiple Choices",
|
23
|
+
301: "Moved Permanently",
|
24
|
+
302: "Found",
|
25
|
+
303: "See Other",
|
26
|
+
304: "Not Modified",
|
27
|
+
305: "Use Proxy",
|
28
|
+
307: "Temporary Redirect",
|
29
|
+
400: "Bad Request",
|
30
|
+
401: "Unauthorized",
|
31
|
+
402: "Payment Required",
|
32
|
+
403: "Forbidden",
|
33
|
+
404: "Not Found",
|
34
|
+
405: "Method Not Allowed",
|
35
|
+
406: "Not Acceptable",
|
36
|
+
407: "Proxy Authentication Required",
|
37
|
+
408: "Request Timeout",
|
38
|
+
409: "Conflict",
|
39
|
+
410: "Gone",
|
40
|
+
411: "Length Required",
|
41
|
+
412: "Precondition Failed",
|
42
|
+
413: "Request Entity Too Large",
|
43
|
+
414: "Request-URI Too Long",
|
44
|
+
415: "Unsupported Media Type",
|
45
|
+
416: "Requested Range Not Satisfiable",
|
46
|
+
417: "Expectation Failed",
|
47
|
+
422: "Unprocessable Entity",
|
48
|
+
500: "Internal Server Error",
|
49
|
+
501: "Not Implemented",
|
50
|
+
502: "Bad Gateway",
|
51
|
+
503: "Service Unavailable",
|
52
|
+
504: "Gateway Timeout",
|
53
|
+
505: "HTTP Version Not Supported"
|
54
|
+
} ;
|
55
|
+
Screw.XHR.prototype.responseText = str;
|
56
|
+
Screw.XHR.prototype.status = status || 200;
|
57
|
+
Screw.XHR.prototype.statusText = codes[status || 200];
|
58
|
+
Screw.XHR.prototype.headers = Screw.XHR.prototype.headers || {};
|
59
|
+
Screw.XHR.prototype.headers["content-type"] = type;
|
60
|
+
if(type == "xml") Screw.XHR.prototype.responseXML = $(str).get();
|
61
|
+
};
|
62
|
+
Screw.XHR.headers = function(headers) {
|
63
|
+
Screw.XHR.prototype.headers = headers;
|
64
|
+
};
|
65
|
+
Screw.XHR.prototype = {
|
66
|
+
abort: function() {},
|
67
|
+
getAllResponseHeaders: function() {},
|
68
|
+
getResponseHeader: function(header) {
|
69
|
+
return this.headers[header.toLowerCase()];
|
70
|
+
},
|
71
|
+
open: function(method, url, async, user, pass) {
|
72
|
+
Screw.XHR.url = url;
|
73
|
+
},
|
74
|
+
send: function(content) {
|
75
|
+
this.readyState = 4;
|
76
|
+
},
|
77
|
+
setRequestHeader: function(label, value) {}
|
78
|
+
};
|
@@ -0,0 +1,90 @@
|
|
1
|
+
html {
|
2
|
+
padding: 0.5em;
|
3
|
+
font-family: Georgia, serif;
|
4
|
+
background: #EDEBD5;
|
5
|
+
}
|
6
|
+
|
7
|
+
li {
|
8
|
+
list-style-type: none;
|
9
|
+
}
|
10
|
+
|
11
|
+
.focused {
|
12
|
+
background-color: #F4F2E4;
|
13
|
+
}
|
14
|
+
|
15
|
+
.focused * {
|
16
|
+
opacity: 1.0;
|
17
|
+
}
|
18
|
+
|
19
|
+
h1, h2, p {
|
20
|
+
opacity: 0.4;
|
21
|
+
}
|
22
|
+
|
23
|
+
.describes {
|
24
|
+
padding-left: 0;
|
25
|
+
}
|
26
|
+
|
27
|
+
.describes h1 {
|
28
|
+
font-size: 1.1em;
|
29
|
+
color: #877C21;
|
30
|
+
line-height: 1.8em;
|
31
|
+
margin: 0pt 0pt 0.6em;
|
32
|
+
border-bottom: 1px solid transparent;
|
33
|
+
}
|
34
|
+
|
35
|
+
.describes h1:hover {
|
36
|
+
cursor: pointer;
|
37
|
+
color: #000;
|
38
|
+
background-color: #F4F2E4;
|
39
|
+
border-bottom: 1px solid #9A8E51;
|
40
|
+
}
|
41
|
+
|
42
|
+
.describes .describe {
|
43
|
+
margin-left: 0.6em;
|
44
|
+
padding-left: 0.6em;
|
45
|
+
border: 1px dashed grey;
|
46
|
+
}
|
47
|
+
|
48
|
+
.describes .describe .its {}
|
49
|
+
|
50
|
+
.describes .describe .its .it {
|
51
|
+
list-style-type: lower-roman;
|
52
|
+
list-style-position: outside;
|
53
|
+
}
|
54
|
+
|
55
|
+
.describes .describe .its .it h2 {
|
56
|
+
font-weight: normal;
|
57
|
+
font-style: italic;
|
58
|
+
padding-left: 0.5em;
|
59
|
+
font-size: 1.0em;
|
60
|
+
color: #877C21;
|
61
|
+
line-height: 1.8em;
|
62
|
+
margin: 0 0 0.5em;
|
63
|
+
border-bottom: 1px solid transparent;
|
64
|
+
}
|
65
|
+
|
66
|
+
.describes .describe .its .it.enqueued h2 {
|
67
|
+
background-color: #CC6600;
|
68
|
+
color: white !important;
|
69
|
+
}
|
70
|
+
|
71
|
+
.describes .describe .its .it.passed h2 {
|
72
|
+
background-color: #5A753D;
|
73
|
+
color: white !important;
|
74
|
+
}
|
75
|
+
|
76
|
+
.describes .describe .its .it.failed h2 {
|
77
|
+
background-color: #993300;
|
78
|
+
color: white !important;
|
79
|
+
}
|
80
|
+
|
81
|
+
.describes .describe .its .it.failed p {
|
82
|
+
margin-left: 1em;
|
83
|
+
color: #993300;
|
84
|
+
}
|
85
|
+
|
86
|
+
.describes .describe .its .it h2:hover {
|
87
|
+
cursor: pointer;
|
88
|
+
color: #000 !important;
|
89
|
+
border-bottom: 1px solid #9A8E51;
|
90
|
+
}
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe "MerbScrewUnit::Main (controller)" do
|
4
|
+
|
5
|
+
# Feel free to remove the specs below
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
Merb::Router.prepare { |r| r.add_slice(:MerbScrewUnit) } if standalone?
|
9
|
+
end
|
10
|
+
|
11
|
+
after :all do
|
12
|
+
Merb::Router.reset! if standalone?
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should have access to the slice module" do
|
16
|
+
controller = dispatch_to(MerbScrewUnit::Main, :index)
|
17
|
+
controller.slice.should == MerbScrewUnit
|
18
|
+
controller.slice.should == MerbScrewUnit::Main.slice
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should have an index action" do
|
22
|
+
controller = dispatch_to(MerbScrewUnit::Main, :index)
|
23
|
+
controller.status.should == 200
|
24
|
+
controller.body.should contain('MerbScrewUnit')
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should work with the default route" do
|
28
|
+
controller = get("/merb_screw_unit/main/index")
|
29
|
+
controller.should be_kind_of(MerbScrewUnit::Main)
|
30
|
+
controller.action_name.should == 'index'
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should work with the example named route" do
|
34
|
+
controller = get("/merb_screw_unit/index.html")
|
35
|
+
controller.should be_kind_of(MerbScrewUnit::Main)
|
36
|
+
controller.action_name.should == 'index'
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should have routes in MerbScrewUnit.routes" do
|
40
|
+
MerbScrewUnit.routes.should_not be_empty
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should have a slice_url helper method for slice-specific routes" do
|
44
|
+
controller = dispatch_to(MerbScrewUnit::Main, 'index')
|
45
|
+
controller.slice_url(:action => 'show', :format => 'html').should == "/merb_screw_unit/main/show.html"
|
46
|
+
controller.slice_url(:merb_screw_unit_index, :format => 'html').should == "/merb_screw_unit/index.html"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should have helper methods for dealing with public paths" do
|
50
|
+
controller = dispatch_to(MerbScrewUnit::Main, :index)
|
51
|
+
controller.public_path_for(:image).should == "/slices/merb_screw_unit/images"
|
52
|
+
controller.public_path_for(:javascript).should == "/slices/merb_screw_unit/javascripts"
|
53
|
+
controller.public_path_for(:stylesheet).should == "/slices/merb_screw_unit/stylesheets"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should have a slice-specific _template_root" do
|
57
|
+
MerbScrewUnit::Main._template_root.should == MerbScrewUnit.dir_for(:view)
|
58
|
+
MerbScrewUnit::Main._template_root.should == MerbScrewUnit::Application._template_root
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|