eyeballs 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +15 -0
- data/README.md +293 -0
- data/Rakefile +45 -0
- data/bin/eyeballs +9 -0
- data/config.ru +2 -0
- data/dist/jquery-1.4.2.min.js +154 -0
- data/dist/jquery.livequery.js +226 -0
- data/dist/mustache.js +324 -0
- data/eyeballs.gemspec +86 -0
- data/eyeballs.js.gemspec +83 -0
- data/lib/eyeballs.rb +11 -0
- data/lib/eyeballs/app_detector.rb +29 -0
- data/lib/eyeballs/app_generator.rb +30 -0
- data/lib/eyeballs/cli.rb +14 -0
- data/lib/eyeballs/controller_generator.rb +26 -0
- data/lib/eyeballs/model_generator.rb +26 -0
- data/lib/eyeballs/scaffold_generator.rb +66 -0
- data/spec/app_generator_spec.rb +51 -0
- data/spec/controller_generator_spec.rb +22 -0
- data/spec/model_generator_spec.rb +23 -0
- data/spec/rack_app_detector_spec.rb +25 -0
- data/spec/scaffold_generator_spec.rb +42 -0
- data/spec/spec_helper.rb +42 -0
- data/src/jquery.o_O.couchdb.js +107 -0
- data/src/jquery.o_O.dom.js +37 -0
- data/src/jquery.o_O.js +120 -0
- data/src/jquery.o_O.rails.js +68 -0
- data/src/o_O.js +286 -0
- data/src/o_O.localstorage.js +60 -0
- data/templates/app_root/index.html +26 -0
- data/templates/controller.js +3 -0
- data/templates/model.js +3 -0
- data/templates/scaffold_controller.js +75 -0
- data/templates/scaffold_edit.html.mustache +13 -0
- data/templates/scaffold_index.html +47 -0
- data/templates/scaffold_partial.html.mustache +12 -0
- data/test/unit/qunit.css +119 -0
- data/test/unit/qunit.js +1069 -0
- data/test/unit/test_controller.html +137 -0
- data/test/unit/test_dom.html +81 -0
- data/test/unit/test_dom_with_callbacks.html +121 -0
- data/test/unit/test_form.html +42 -0
- data/test/unit/test_localstorage.html +79 -0
- data/test/unit/test_model.html +136 -0
- data/test/unit/test_model_with_callbacks.html +118 -0
- data/test/unit/test_rails.html +97 -0
- metadata +117 -0
@@ -0,0 +1,137 @@
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/html4/loose.dtd">
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<script src="../../dist/jquery-1.4.2.min.js"></script>
|
6
|
+
<script src="../../dist/jquery.livequery.js"></script>
|
7
|
+
<script src="../../src/o_O.js"></script>
|
8
|
+
<script src="../../src/jquery.o_O.js"></script>
|
9
|
+
<link rel="stylesheet" href="qunit.css" type="text/css" media="screen" />
|
10
|
+
<script type="text/javascript" src="qunit.js"></script>
|
11
|
+
|
12
|
+
<script>
|
13
|
+
o_O('ReviewsController', {
|
14
|
+
create: function(){
|
15
|
+
$(this).html('created!');
|
16
|
+
},
|
17
|
+
show: function(){
|
18
|
+
$(this).html('shown!');
|
19
|
+
},
|
20
|
+
other: function(){
|
21
|
+
$(this).html('other!');
|
22
|
+
},
|
23
|
+
another: function(){
|
24
|
+
$(this).html('another!')
|
25
|
+
},
|
26
|
+
check: function(){
|
27
|
+
$(this).val('bacon')
|
28
|
+
},
|
29
|
+
shortcut: function(){
|
30
|
+
$(this).html('shortcut!')
|
31
|
+
},
|
32
|
+
multi: function(){
|
33
|
+
$(this).html($(this).html() + ' multi!')
|
34
|
+
}
|
35
|
+
});
|
36
|
+
|
37
|
+
$(document).ready(function(){
|
38
|
+
|
39
|
+
module("Controller");
|
40
|
+
|
41
|
+
test('bind to global',1,function(){
|
42
|
+
equals(typeof ReviewsController, 'object', 'ReviewsController should be an object')
|
43
|
+
})
|
44
|
+
|
45
|
+
test('submitting an auto-bound form', 1, function(){
|
46
|
+
$('form#myForm').trigger('submit');
|
47
|
+
equals($('form#myForm').html(), 'created!', 'html should have been updated');
|
48
|
+
});
|
49
|
+
|
50
|
+
test('submitting an auto-bound form with data-bind shortcut', 1, function(){
|
51
|
+
$('form#myShortcutForm').trigger('submit');
|
52
|
+
equals($('form#myShortcutForm').html(), 'created!', 'html should have been updated');
|
53
|
+
});
|
54
|
+
|
55
|
+
test('clicking an auto-bound link', 1, function(){
|
56
|
+
$('a#myLink').trigger('click');
|
57
|
+
equals($('a#myLink').html(), 'shown!', 'html should have been updated');
|
58
|
+
});
|
59
|
+
|
60
|
+
test('clicking an auto-bound link with data-bind shortcut', 1, function(){
|
61
|
+
$('a#myShortcutLink').trigger('click');
|
62
|
+
equals($('a#myShortcutLink').html(), 'shown!', 'html should have been updated');
|
63
|
+
});
|
64
|
+
|
65
|
+
test('hovering a custom bound element', 1, function(){
|
66
|
+
$('div#myDiv').trigger('mouseover');
|
67
|
+
equals($('div#myDiv').html(), 'other!', 'html should have been updated');
|
68
|
+
});
|
69
|
+
|
70
|
+
new_element = $('<a id="anotherLink" data-controller="reviews" data-action="another">another link</a>')
|
71
|
+
$('div#anotherDiv').append(new_element);
|
72
|
+
|
73
|
+
|
74
|
+
setTimeout(function(){
|
75
|
+
test("a new link", 1, function(){
|
76
|
+
$('a#anotherLink').trigger('click');
|
77
|
+
equals($('a#anotherLink').html(), 'another!', 'it should have some dynamic behavior');
|
78
|
+
})
|
79
|
+
}, 100);
|
80
|
+
|
81
|
+
test('should allow default behavior', 1, function(){
|
82
|
+
$('input#myCheckbox').trigger('click');
|
83
|
+
equals($('input#myCheckbox:checked').length, 1, "check box should be checked")
|
84
|
+
})
|
85
|
+
|
86
|
+
test('should allow default behavior with data-bind', 2, function(){
|
87
|
+
$('input#myOtherCheckbox').trigger('click');
|
88
|
+
equals($('input#myOtherCheckbox:checked').val(), 'bacon', "check box value should change")
|
89
|
+
equals($('input#myOtherCheckbox:checked').length, 1, "check box should be checked")
|
90
|
+
})
|
91
|
+
|
92
|
+
test('should bind on shortcuts',2, function(){
|
93
|
+
$('div#shortcut').trigger('click');
|
94
|
+
equals($("div#shortcut").html(), 'shortcut!', 'it should be bound with the data-bind keyword')
|
95
|
+
$('div#shortcut').trigger('mouseover');
|
96
|
+
equals($("div#shortcut").html(), 'shortcut! multi!', 'it should bind multiple events')
|
97
|
+
})
|
98
|
+
|
99
|
+
});
|
100
|
+
</script>
|
101
|
+
|
102
|
+
</head>
|
103
|
+
<body>
|
104
|
+
<h1 id="qunit-header">Controller Tests</h1>
|
105
|
+
<h2 id="qunit-banner"></h2>
|
106
|
+
<h2 id="qunit-userAgent"></h2>
|
107
|
+
<ol id="qunit-tests"></ol>
|
108
|
+
|
109
|
+
<div data-id="paul">
|
110
|
+
<form id="myForm" data-controller="reviews" data-action="create">
|
111
|
+
test form
|
112
|
+
</form>
|
113
|
+
|
114
|
+
<form id="myShortcutForm" data-bind="reviews/create">
|
115
|
+
test form
|
116
|
+
</form>
|
117
|
+
|
118
|
+
<a id="myLink" data-controller="reviews" data-action="show">
|
119
|
+
test link
|
120
|
+
</a>
|
121
|
+
|
122
|
+
<a id="myShortcutLink" data-bind="reviews/show">
|
123
|
+
test link
|
124
|
+
</a>
|
125
|
+
|
126
|
+
<div id="myDiv" data-controller="reviews" data-action="other" data-event="mouseenter">stuff</div>
|
127
|
+
<div id="shortcut" data-bind="click:reviews/shortcut; mouseenter:reviews/multi">
|
128
|
+
I'm a shortcut
|
129
|
+
</div>
|
130
|
+
<div id="anotherDiv">
|
131
|
+
|
132
|
+
</div>
|
133
|
+
<input id="myCheckbox" data-controller="reviews" data-action="check" data-default="true" type="checkbox">
|
134
|
+
<input id="myOtherCheckbox" data-bind="+click:reviews/check" type="checkbox" value="toast">
|
135
|
+
</div>
|
136
|
+
</body>
|
137
|
+
</html>
|
@@ -0,0 +1,81 @@
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/html4/loose.dtd">
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<script src="../../dist/jquery-1.4.2.min.js"></script>
|
6
|
+
<script src="../../dist/jquery.livequery.js"></script>
|
7
|
+
<script src="../../src/o_O.js"></script>
|
8
|
+
<script src="../../src/jquery.o_O.dom.js"></script>
|
9
|
+
<script src="../../src/jquery.o_O.js"></script>
|
10
|
+
<link rel="stylesheet" href="qunit.css" type="text/css" media="screen" />
|
11
|
+
<script type="text/javascript" src="qunit.js"></script>
|
12
|
+
|
13
|
+
<script>
|
14
|
+
|
15
|
+
|
16
|
+
$(document).ready(function(){
|
17
|
+
|
18
|
+
module("DOM Test",{
|
19
|
+
setup: function(){
|
20
|
+
localStorage.clear();
|
21
|
+
}
|
22
|
+
});
|
23
|
+
|
24
|
+
o_O.model.adapter = o_O.dom;
|
25
|
+
|
26
|
+
o_O('Review', function(){})
|
27
|
+
|
28
|
+
asyncTest('storing a basic basic thing', 1, function(){
|
29
|
+
var review = Review.initialize({title: 'Magic!'})
|
30
|
+
review.save(function(saved_review){
|
31
|
+
equals(saved_review.title, 'Magic!', 'Should save the title')
|
32
|
+
start();
|
33
|
+
});
|
34
|
+
});
|
35
|
+
|
36
|
+
asyncTest('pulling something in', 2, function(){
|
37
|
+
Review.find('big-whoop', function(found_review){
|
38
|
+
equals(found_review.title, 'Whoop!', 'should be able to find stuff in the dom')
|
39
|
+
equals(found_review.id, 'big-whoop', 'should persist the id')
|
40
|
+
start();
|
41
|
+
});
|
42
|
+
})
|
43
|
+
|
44
|
+
asyncTest('getting all', 1, function(){
|
45
|
+
Review.all(function(all_reviews){
|
46
|
+
equals(all_reviews[0].title, 'Whoop!', 'It should pull in everything')
|
47
|
+
start();
|
48
|
+
})
|
49
|
+
})
|
50
|
+
|
51
|
+
o_O('Deletable', function(){})
|
52
|
+
|
53
|
+
asyncTest('deleting', 1, function(){
|
54
|
+
Deletable.find('delete-me', function(delete_me){
|
55
|
+
delete_me.destroy(function(){
|
56
|
+
equals($('[data-id=delete-me]').length, 0, 'it should have been deleted')
|
57
|
+
start();
|
58
|
+
})
|
59
|
+
});
|
60
|
+
})
|
61
|
+
|
62
|
+
});
|
63
|
+
</script>
|
64
|
+
|
65
|
+
</head>
|
66
|
+
<body>
|
67
|
+
<h1 id="qunit-header">DOM Tests</h1>
|
68
|
+
<h2 id="qunit-banner"></h2>
|
69
|
+
<h2 id="qunit-userAgent"></h2>
|
70
|
+
<ol id="qunit-tests"></ol>
|
71
|
+
|
72
|
+
<div data-id="big-whoop" data-model="Review">
|
73
|
+
<h1 data-attribute="title">Whoop!</h1>
|
74
|
+
<p data-attribute="content">Awesome!</p>
|
75
|
+
</div>
|
76
|
+
|
77
|
+
<div data-id="delete-me" data-model="Deletable">
|
78
|
+
Nice!
|
79
|
+
</div>
|
80
|
+
</body>
|
81
|
+
</html>
|
@@ -0,0 +1,121 @@
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/html4/loose.dtd">
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<script src="../../dist/jquery-1.4.2.min.js"></script>
|
6
|
+
<script src="../../src/o_O.js"></script>
|
7
|
+
<script src="../../src/jquery.o_O.js"></script>
|
8
|
+
<script src="../../src/jquery.o_O.dom.js"></script>
|
9
|
+
<link rel="stylesheet" href="qunit.css" type="text/css" media="screen" />
|
10
|
+
<script type="text/javascript" src="qunit.js"></script>
|
11
|
+
|
12
|
+
<script>
|
13
|
+
|
14
|
+
o_O.model.adapter = o_O.dom;
|
15
|
+
|
16
|
+
o_O('Review', function(that){
|
17
|
+
that.validates_presence_of('title');
|
18
|
+
that.validates_presence_of('content');
|
19
|
+
that.validates_length_of('title', {min: 5, max: 15});
|
20
|
+
that.validates(function(review){
|
21
|
+
if(review.score != 99 && review.test === true)
|
22
|
+
{
|
23
|
+
review.errors.push({message: 'Score should be 99'})
|
24
|
+
}
|
25
|
+
})
|
26
|
+
that.methods.title_numbered = function(){
|
27
|
+
return '1. ' + this.title;
|
28
|
+
}
|
29
|
+
return that;
|
30
|
+
});
|
31
|
+
|
32
|
+
$(document).ready(function(){
|
33
|
+
|
34
|
+
module("Models");
|
35
|
+
|
36
|
+
|
37
|
+
asyncTest('a valid, successful model', 2, function(){
|
38
|
+
var myReview = Review.initialize({title: "Biscuit", content: "Some Content"});
|
39
|
+
myReview.save({
|
40
|
+
loading: function(){
|
41
|
+
ok('should call the loading callback before success')
|
42
|
+
},
|
43
|
+
success: function(){
|
44
|
+
ok('should call the success callback')
|
45
|
+
start();
|
46
|
+
}
|
47
|
+
});
|
48
|
+
});
|
49
|
+
|
50
|
+
asyncTest('an invalid review',1, function(){
|
51
|
+
var myReview = Review.initialize();
|
52
|
+
myReview.save({
|
53
|
+
success:function(){
|
54
|
+
ok('should not call the success callback');
|
55
|
+
},
|
56
|
+
invalid: function(){
|
57
|
+
ok('should call the invalid callback');
|
58
|
+
start();
|
59
|
+
},
|
60
|
+
loading: function(){
|
61
|
+
ok('should not call the loading callback');
|
62
|
+
}
|
63
|
+
});
|
64
|
+
});
|
65
|
+
|
66
|
+
asyncTest('updating a review', 2, function(){
|
67
|
+
var myReview = Review.initialize({title: "Biscuit", content: "Some Content"});
|
68
|
+
myReview.update_attributes({title: 'No! is it', content: 'Dublin'}, {
|
69
|
+
success: function(){
|
70
|
+
ok('should call the success callback');
|
71
|
+
start();
|
72
|
+
},
|
73
|
+
invalid: function(){
|
74
|
+
ok('should not cal the invalid callback');
|
75
|
+
},
|
76
|
+
loading: function(){
|
77
|
+
ok('should call the loading callback');
|
78
|
+
}
|
79
|
+
});
|
80
|
+
})
|
81
|
+
|
82
|
+
asyncTest('updating an invalid review', 1, function(){
|
83
|
+
var myReview = Review.initialize();
|
84
|
+
myReview.update_attributes({}, {
|
85
|
+
success: function(){
|
86
|
+
ok('should call the success callback');
|
87
|
+
},
|
88
|
+
invalid: function(){
|
89
|
+
ok('should not cal the invalid callback');
|
90
|
+
start();
|
91
|
+
},
|
92
|
+
loading: function(){
|
93
|
+
ok('should call the loading callback');
|
94
|
+
}
|
95
|
+
});
|
96
|
+
})
|
97
|
+
|
98
|
+
test('destroying a review', 2, function(){
|
99
|
+
var myReview = Review.initialize();
|
100
|
+
myReview.destroy({
|
101
|
+
loading: function(){
|
102
|
+
ok('loading should be run');
|
103
|
+
},
|
104
|
+
success: function(){
|
105
|
+
ok('success should be run');
|
106
|
+
}
|
107
|
+
})
|
108
|
+
})
|
109
|
+
|
110
|
+
});
|
111
|
+
</script>
|
112
|
+
|
113
|
+
</head>
|
114
|
+
<body>
|
115
|
+
<h1 id="qunit-header">Model Tests (with callbacks)</h1>
|
116
|
+
<h2 id="qunit-banner"></h2>
|
117
|
+
<h2 id="qunit-userAgent"></h2>
|
118
|
+
<ol id="qunit-tests"></ol>
|
119
|
+
</div>
|
120
|
+
</body>
|
121
|
+
</html>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/html4/loose.dtd">
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<script src="../../dist/jquery-1.4.2.min.js"></script>
|
6
|
+
<script src="../../src/o_O.js"></script>
|
7
|
+
<script src="../../src/jquery.o_O.js"></script>
|
8
|
+
<link rel="stylesheet" href="qunit.css" type="text/css" media="screen" />
|
9
|
+
<script type="text/javascript" src="qunit.js"></script>
|
10
|
+
|
11
|
+
<script>
|
12
|
+
var Review = o_O(function(that){
|
13
|
+
that.validates_presence_of('title');
|
14
|
+
that.validates_presence_of('content');
|
15
|
+
return that;
|
16
|
+
});
|
17
|
+
|
18
|
+
$(document).ready(function(){
|
19
|
+
|
20
|
+
module("Forms");
|
21
|
+
|
22
|
+
test('getting form attributes', 2, function(){
|
23
|
+
equals(o_O.params($('form#test-form')).title, 'Biscuit', 'form attributes should come in nicely')
|
24
|
+
equals(o_O.params($('form#test-form')).selection, "1", 'should work with checkboxes')
|
25
|
+
});
|
26
|
+
|
27
|
+
});
|
28
|
+
</script>
|
29
|
+
|
30
|
+
</head>
|
31
|
+
<body>
|
32
|
+
<h1 id="qunit-header">Form Tests</h1>
|
33
|
+
<h2 id="qunit-banner"></h2>
|
34
|
+
<h2 id="qunit-userAgent"></h2>
|
35
|
+
<ol id="qunit-tests"></ol>
|
36
|
+
<form id="test-form">
|
37
|
+
<input type="title" data-attribute="title" type="text" value="Biscuit">
|
38
|
+
<input type="radio" data-attribute="selection" value="1" checked>
|
39
|
+
<input type="radio" data-attribute="selection" value="-1">
|
40
|
+
</form>
|
41
|
+
</body>
|
42
|
+
</html>
|
@@ -0,0 +1,79 @@
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/html4/loose.dtd">
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<script src="../../dist/jquery-1.4.2.min.js"></script>
|
6
|
+
<script src="../../dist/jquery.livequery.js"></script>
|
7
|
+
<script src="../../src/o_O.js"></script>
|
8
|
+
<script src="../../src/o_O.localstorage.js"></script>
|
9
|
+
<script src="../../src/jquery.o_O.js"></script>
|
10
|
+
<link rel="stylesheet" href="qunit.css" type="text/css" media="screen" />
|
11
|
+
<script type="text/javascript" src="qunit.js"></script>
|
12
|
+
|
13
|
+
<script>
|
14
|
+
|
15
|
+
|
16
|
+
$(document).ready(function(){
|
17
|
+
|
18
|
+
module("Local Storage Test",{
|
19
|
+
setup: function(){
|
20
|
+
localStorage.clear();
|
21
|
+
}
|
22
|
+
});
|
23
|
+
|
24
|
+
o_O.model.adapter = o_O.localstorage;
|
25
|
+
|
26
|
+
o_O('Review', function(){})
|
27
|
+
|
28
|
+
asyncTest('storing a basic basic thing', 1, function(){
|
29
|
+
var review = Review.initialize({title: 'Magic!'})
|
30
|
+
review.save(function(saved_review){
|
31
|
+
var all_reviews = JSON.parse(localStorage.getItem('reviews'));
|
32
|
+
equals(all_reviews[review.id].title, 'Magic!', 'it should have saved to local storage');
|
33
|
+
start();
|
34
|
+
});
|
35
|
+
});
|
36
|
+
|
37
|
+
asyncTest('pulling something in', 2, function(){
|
38
|
+
var review = Review.initialize({title: 'More Magic!'})
|
39
|
+
review.save(function(saved_review){
|
40
|
+
Review.find(review.id, function(found_review){
|
41
|
+
equals(found_review.title, 'More Magic!', 'should be able to find stuff in local storage')
|
42
|
+
equals(found_review.id, review.id, 'should persist the id')
|
43
|
+
start();
|
44
|
+
});
|
45
|
+
});
|
46
|
+
})
|
47
|
+
|
48
|
+
asyncTest('getting all', 1, function(){
|
49
|
+
var review = Review.initialize({title: 'Local, baby'})
|
50
|
+
review.save(function(){
|
51
|
+
Review.all(function(all_reviews){
|
52
|
+
equals(all_reviews[0].title, 'Local, baby', 'It should pull in everything')
|
53
|
+
start();
|
54
|
+
})
|
55
|
+
});
|
56
|
+
})
|
57
|
+
|
58
|
+
test('deleting', 2, function(){
|
59
|
+
var review = Review.initialize({title: 'Doomed!'});
|
60
|
+
review.save(function(saved_review){
|
61
|
+
equals(localStorage.length, 1, 'local storage should be used');
|
62
|
+
saved_review.destroy(function(){
|
63
|
+
equals(localStorage.getItem('reviews'), '{}', 'local storage should be empty!');
|
64
|
+
start();
|
65
|
+
});
|
66
|
+
});
|
67
|
+
})
|
68
|
+
|
69
|
+
});
|
70
|
+
</script>
|
71
|
+
|
72
|
+
</head>
|
73
|
+
<body>
|
74
|
+
<h1 id="qunit-header">Controller Tests</h1>
|
75
|
+
<h2 id="qunit-banner"></h2>
|
76
|
+
<h2 id="qunit-userAgent"></h2>
|
77
|
+
<ol id="qunit-tests"></ol>
|
78
|
+
</body>
|
79
|
+
</html>
|