nakajima-protocov 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +14 -0
- data/LICENSE.txt +22 -0
- data/Manifest.txt +25 -0
- data/README.txt +42 -0
- data/Rakefile +19 -0
- data/bin/protocov +8 -0
- data/lib/protocov.rb +14 -0
- data/lib/protocov/base.rb +59 -0
- data/lib/protocov/ext/array_extensions.rb +11 -0
- data/lib/protocov/ext/object_extensions.rb +9 -0
- data/lib/protocov/ext/string_extensions.rb +29 -0
- data/lib/protocov/runner.rb +60 -0
- data/lib/protocov/source_file.rb +16 -0
- data/lib/protocov/test_file.rb +16 -0
- data/test/fixtures/src/array_extensions.js +11 -0
- data/test/fixtures/src/classy_behaviors.js +103 -0
- data/test/fixtures/src/number_extensions.js +18 -0
- data/test/fixtures/test/unit/array_extensions_test.html +35 -0
- data/test/fixtures/test/unit/number_extensions_test.html +35 -0
- data/test/helper.rb +26 -0
- data/test/test_protocov.rb +9 -0
- data/test/test_runner.rb +29 -0
- data/test/test_source_file.rb +23 -0
- data/test/test_string_extensions.rb +39 -0
- data/test/test_test_file.rb +26 -0
- metadata +86 -0
data/History.txt
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
=== 0.0.2 / 2008-05-21 ===
|
2
|
+
|
3
|
+
* Initial release
|
4
|
+
|
5
|
+
* Super-basic code coverage generator
|
6
|
+
* Super-basic file annotator (shows methods, classes and modules defined in file)
|
7
|
+
|
8
|
+
|
9
|
+
=== 0.0.1 / 2008-05-21 ===
|
10
|
+
|
11
|
+
* Hello World
|
12
|
+
|
13
|
+
* Added initial files
|
14
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2008 Pat Nakajima
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest.txt
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
LICENSE.txt
|
4
|
+
README.txt
|
5
|
+
Rakefile
|
6
|
+
bin/protocov
|
7
|
+
lib/protocov/ext/array_extensions.rb
|
8
|
+
lib/protocov/ext/string_extensions.rb
|
9
|
+
lib/protocov/ext/object_extensions.rb
|
10
|
+
lib/protocov.rb
|
11
|
+
lib/protocov/base.rb
|
12
|
+
lib/protocov/runner.rb
|
13
|
+
lib/protocov/source_file.rb
|
14
|
+
lib/protocov/test_file.rb
|
15
|
+
test/helper.rb
|
16
|
+
test/test_protocov.rb
|
17
|
+
test/test_runner.rb
|
18
|
+
test/test_source_file.rb
|
19
|
+
test/test_test_file.rb
|
20
|
+
test/test_string_extensions.rb
|
21
|
+
test/fixtures/src/classy_behaviors.js
|
22
|
+
test/fixtures/src/array_extensions.js
|
23
|
+
test/fixtures/src/number_extensions.js
|
24
|
+
test/fixtures/test/unit/array_extensions_test.html
|
25
|
+
test/fixtures/test/unit/number_extensions_test.html
|
data/README.txt
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
= ProtoCov =
|
2
|
+
|
3
|
+
== DESCRIPTION ==
|
4
|
+
|
5
|
+
Code coverage docs for Prototype-style Javascript projects
|
6
|
+
|
7
|
+
Nothing to look at yet, but stay tuned.
|
8
|
+
|
9
|
+
== USAGE ==
|
10
|
+
|
11
|
+
First, you need to make sure your project is organized like so:
|
12
|
+
|
13
|
+
project/
|
14
|
+
src/
|
15
|
+
test/
|
16
|
+
|
17
|
+
Where the src directory contains all of your implementation code and
|
18
|
+
your test directory contains all of your test code.
|
19
|
+
|
20
|
+
Find code coverage for your project:
|
21
|
+
|
22
|
+
protocov .
|
23
|
+
|
24
|
+
View method, class and module definitions by file for you project:
|
25
|
+
|
26
|
+
protocov --annotate .
|
27
|
+
|
28
|
+
== INSTALL ==
|
29
|
+
|
30
|
+
If you want to install ProtoCov, run the following command:
|
31
|
+
|
32
|
+
sudo gem install nakajima-protocov --source=http://gems.github.com
|
33
|
+
|
34
|
+
Please keep in mind that this project is still in a very early
|
35
|
+
stage of development and is prone to being buggy as all hell.
|
36
|
+
|
37
|
+
== TODO ==
|
38
|
+
|
39
|
+
* It's messy.
|
40
|
+
* DRY things up.. a lot
|
41
|
+
* Look into using Treetop.
|
42
|
+
* Remove directory structure requirements
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
require './lib/protocov.rb'
|
6
|
+
|
7
|
+
Hoe.new('protocov', ProtoCov::VERSION) do |p|
|
8
|
+
# p.rubyforge_name = 'protocovx' # if different than lowercase project name
|
9
|
+
p.developer('Pat Nakajima', 'patnakajima@gmail.com')
|
10
|
+
p.description = 'Code coverage docs for Prototype-style Javascript projects'
|
11
|
+
p.homepage = 'http://github.com/nakajima/protocov'
|
12
|
+
end
|
13
|
+
|
14
|
+
# vim: syntax=Ruby
|
15
|
+
|
16
|
+
desc "Uninstall gem"
|
17
|
+
task :uninstall_gem do
|
18
|
+
exec 'gem uninstall protocov'
|
19
|
+
end
|
data/bin/protocov
ADDED
data/lib/protocov.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'protocov/base'
|
4
|
+
require 'protocov/ext/array_extensions'
|
5
|
+
require 'protocov/ext/object_extensions'
|
6
|
+
require 'protocov/ext/string_extensions'
|
7
|
+
require 'protocov/test_file'
|
8
|
+
require 'protocov/source_file'
|
9
|
+
require 'protocov/runner'
|
10
|
+
|
11
|
+
module ProtoCov
|
12
|
+
VERSION = '0.0.2'
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module ProtoCov
|
2
|
+
class NoPathSpecified < StandardError
|
3
|
+
def initialize(message)
|
4
|
+
puts message unless PROTOCOV_ENV.match(/test/)
|
5
|
+
exit
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.run(args)
|
10
|
+
Runner.new(args)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Parent class of SourceFile and TestFile. Defines common methods.
|
14
|
+
class GenericFile
|
15
|
+
class << self
|
16
|
+
def find_files_in(dir)
|
17
|
+
dir.entries \
|
18
|
+
.select { |file| valid?(file) } \
|
19
|
+
.collect { |file| new(file, File.expand_path(dir.path)) }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def path
|
24
|
+
File.expand_path(File.join(path_prefix, filename))
|
25
|
+
end
|
26
|
+
|
27
|
+
def body
|
28
|
+
@body ||= File.read(path)
|
29
|
+
end
|
30
|
+
|
31
|
+
def lines
|
32
|
+
@lines ||= body.split(/\n/)
|
33
|
+
end
|
34
|
+
|
35
|
+
def defined_methods
|
36
|
+
@defined_methods ||= body.parse_for(:method_definitions)
|
37
|
+
end
|
38
|
+
|
39
|
+
def invoked_methods
|
40
|
+
@invoked_methods ||= body.parse_for(:method_invocations)
|
41
|
+
end
|
42
|
+
|
43
|
+
def classes
|
44
|
+
@classes ||= body.parse_for(:classes)
|
45
|
+
end
|
46
|
+
|
47
|
+
def modules
|
48
|
+
@modules ||= body.parse_for(:modules)
|
49
|
+
end
|
50
|
+
|
51
|
+
def annotate!
|
52
|
+
puts "== #{filename.bold} =="
|
53
|
+
puts "Methods:\n#{defined_methods.map { |m| "- #{m}\n" }}" unless defined_methods.empty?
|
54
|
+
puts "Modules:\n#{modules.map { |m| "- #{m}\n" }}" unless modules.empty?
|
55
|
+
puts "Classes:\n#{classes.map { |m| "- #{m}\n" }}" unless classes.empty?
|
56
|
+
puts ""
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module ProtoCov
|
2
|
+
module ArrayExtensions
|
3
|
+
# Quicker than Symbol#to_proc since we don't need
|
4
|
+
# to worry about passing in args and such
|
5
|
+
def invoke(attr_name)
|
6
|
+
map { |entry| entry.send(attr_name) }
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
Array.send :include, ProtoCov::ArrayExtensions
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module ProtoCov
|
2
|
+
module StringExtensions
|
3
|
+
def bold
|
4
|
+
"\e[1m" + self + "\e[0m"
|
5
|
+
end
|
6
|
+
|
7
|
+
# Doing this with regular expressions is a headache.
|
8
|
+
# TODO: Look into Treetop
|
9
|
+
def parse_for(thing)
|
10
|
+
string = self.dup
|
11
|
+
string.gsub!(/\bvar\b/, '')
|
12
|
+
result = case thing
|
13
|
+
when :method_definitions: self.scan(/(\w+)\s*:\s*function\s*\(|[A-Z][A-Za-z0-9]*\.prototype\.(\w+)/i)
|
14
|
+
when :method_invocations: self.scan(/\.([a-zA-Z\_*]\w*)\(/)
|
15
|
+
when :modules: self.scan(/\s*[^\/{2}]*\s+([A-Z][A-Za-z0-9]+)\s*[\=\:]\s*\{/)
|
16
|
+
when :classes: self.scan(/\s*([A-Z][A-Za-z0-9]+)\s*[\=\:]\s*Class\.create/)
|
17
|
+
else
|
18
|
+
[]
|
19
|
+
end
|
20
|
+
result.flatten!
|
21
|
+
result.compact!
|
22
|
+
result.uniq!
|
23
|
+
result.sort!
|
24
|
+
result
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
String.send :include, ProtoCov::StringExtensions
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module ProtoCov
|
2
|
+
class Runner
|
3
|
+
attr_reader :source_dir, :test_dir, :source_files, :test_files
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
parse_args(args)
|
7
|
+
get_files
|
8
|
+
@source_files.invoke(:annotate!) and return if @annotate
|
9
|
+
report!
|
10
|
+
end
|
11
|
+
|
12
|
+
# This could definitely be smarter
|
13
|
+
def get_files
|
14
|
+
@source_files = SourceFile.find_files_in(Dir.new(File.join(@dir.path, 'src')))
|
15
|
+
@test_files = TestFile.find_files_in(Dir.new(File.join(@dir.path, 'test')))
|
16
|
+
@test_files += TestFile.find_files_in(Dir.new(File.join(@dir.path, 'test', 'unit'))) if @dir.entries.include?('unit')
|
17
|
+
end
|
18
|
+
|
19
|
+
# Holy cow this method is ugly.
|
20
|
+
def report!
|
21
|
+
puts "Source Files:\n#{@source_files.map { |f| "#{File.basename(f.filename)}" }.join(', ')}\n\n"
|
22
|
+
puts "Test Files:\n#{@test_files.map { |f| "#{File.basename(f.filename)}" }.join(', ')}\n\n"
|
23
|
+
@source_files.each do |file|
|
24
|
+
untested_methods = file.defined_methods - invoked_methods
|
25
|
+
tested_methods = file.defined_methods.select { |f| invoked_methods.include?(f) }
|
26
|
+
puts "==== #{File.basename(file.filename)} ====\n".bold
|
27
|
+
case
|
28
|
+
when file.defined_methods.empty?
|
29
|
+
puts "No methods found."
|
30
|
+
when untested_methods.empty?
|
31
|
+
puts "All methods tested!"
|
32
|
+
else
|
33
|
+
puts "Untested Methods (#{untested_methods.length}/#{file.defined_methods.length}):\n#{untested_methods.map { |m| "- #{m}\n" }}" unless untested_methods.empty?
|
34
|
+
puts "\nTested Methods (#{tested_methods.length}/#{file.defined_methods.length}):\n#{tested_methods.map { |m| "- #{m}\n" }}" unless tested_methods.empty?
|
35
|
+
end
|
36
|
+
puts "\n"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Perhaps I ought to be looking at methods invoked in source files too for this.
|
41
|
+
def invoked_methods
|
42
|
+
@invoked_methods ||= @test_files.invoke(:invoked_methods).flatten
|
43
|
+
end
|
44
|
+
|
45
|
+
# Pretty plain.
|
46
|
+
def parse_args(args)
|
47
|
+
begin
|
48
|
+
args = args.dup
|
49
|
+
raise NoPathSpecified.new("Please specify your project's root directory, e.g. `protocov .") if args.empty?
|
50
|
+
@annotate = args.delete('--annotate') ? true : false
|
51
|
+
@dir = Dir.new(File.join(Dir.pwd, args.shift))
|
52
|
+
|
53
|
+
rescue Errno::ENOENT => e
|
54
|
+
d = e.to_s.match(/src/) ? 'src/' : 'test/'
|
55
|
+
puts "Make sure your project's root directory has a #{d} directory."
|
56
|
+
exit
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ProtoCov
|
2
|
+
class SourceFile < GenericFile
|
3
|
+
attr_reader :filename, :path_prefix
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def valid?(file)
|
7
|
+
file.match(/\.js\z/)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(filename, path_prefix)
|
12
|
+
@filename = filename
|
13
|
+
@path_prefix = path_prefix
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ProtoCov
|
2
|
+
class TestFile < GenericFile
|
3
|
+
attr_reader :filename, :path_prefix
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def valid?(file)
|
7
|
+
file.match(/\.(html|js)\z/)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(filename, path_prefix)
|
12
|
+
@path_prefix = path_prefix
|
13
|
+
@filename = filename
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
// Classy.js contains class-based conveniences
|
2
|
+
|
3
|
+
Event.observe(document, 'dom:loaded', function() {
|
4
|
+
var Classy = { }; // Setup the namespace
|
5
|
+
Object.extend(Classy, {
|
6
|
+
|
7
|
+
// Validator: Simple client-side form validation.
|
8
|
+
//
|
9
|
+
// Usage: Add the class name "required" to any required fields.
|
10
|
+
// When the user attempts to submit the form, any required
|
11
|
+
// fields left blank will have the class name "err" added to
|
12
|
+
// them, which you can style appropriately.
|
13
|
+
Validator: {
|
14
|
+
// TODO: Use event delegation for this.
|
15
|
+
findForms: function() {
|
16
|
+
Classy.Validator.forms = $$('.required').pluck('form').uniq();
|
17
|
+
Classy.Validator.forms.invoke('observe', 'submit', Classy.Validator.performCheck);
|
18
|
+
},
|
19
|
+
|
20
|
+
performCheck: function(event) {
|
21
|
+
function isBlank(element) { return $F(element).blank(); }
|
22
|
+
var form = event.element();
|
23
|
+
var requiredInputs = form.select('.required');
|
24
|
+
if ( requiredInputs.any(isBlank) ) {
|
25
|
+
requiredInputs.invoke('addClassName', 'err');
|
26
|
+
event.stop();
|
27
|
+
}
|
28
|
+
}
|
29
|
+
},
|
30
|
+
|
31
|
+
// Confirmable: Simple action confirmation controls
|
32
|
+
//
|
33
|
+
// Usage: Add the class name "confirmable" to any link or form that needs confirmation.
|
34
|
+
// When the user attempts to click/submit the "confirmable" element, the element's title
|
35
|
+
// attribute will be used as a confirmation message. If the user clicks "Cancel", the
|
36
|
+
// event will be stopped. Otherwise, it will be allowed to continue.
|
37
|
+
//
|
38
|
+
// Note: This script requires event_delegations.js and form_submit_bubbler.js
|
39
|
+
Confirmable: {
|
40
|
+
setup: function() {
|
41
|
+
var body = $$('body')[0];
|
42
|
+
body.delegators('form:submitted', { 'form.confirmable': Classy.Confirmable.submitted });
|
43
|
+
body.delegators('click', { 'a.confirmable': Classy.Confirmable.clicked });
|
44
|
+
},
|
45
|
+
|
46
|
+
submitted: function(event) {
|
47
|
+
var element = event.element();
|
48
|
+
var message = element.readAttribute('title');
|
49
|
+
if ( !confirm(message) ) { event.stop(); event.memo['originalEvent'].stop(); }
|
50
|
+
},
|
51
|
+
|
52
|
+
clicked: function(event) {
|
53
|
+
var element = event.element();
|
54
|
+
var message = element.readAttribute('title');
|
55
|
+
if ( !confirm(message) ) { event.stop(); }
|
56
|
+
}
|
57
|
+
},
|
58
|
+
|
59
|
+
// Defaultable: Simple default text behaviors
|
60
|
+
//
|
61
|
+
// Usage: Add the class name "defaultify" to text fields or textareas. When a user
|
62
|
+
// element, the default text will be cleared, allowing for user input. When the element
|
63
|
+
// loses focus, if the user has entered text, the text will remain. Otherwise, the
|
64
|
+
// default text will be restored.
|
65
|
+
Defaultable: Class.create({
|
66
|
+
initialize: function(element) {
|
67
|
+
this.element = $(element);
|
68
|
+
this.value = $F(element);
|
69
|
+
this.setupBehaviors();
|
70
|
+
},
|
71
|
+
|
72
|
+
setupBehaviors: function() {
|
73
|
+
this.element.observe('focus', this.clear.bindAsEventListener(this));
|
74
|
+
this.element.observe('blur', this.restore.bindAsEventListener(this));
|
75
|
+
},
|
76
|
+
|
77
|
+
clear: function(event) {
|
78
|
+
var value = $F(this.element);
|
79
|
+
if ( value.blank() || (value == this.value) ) {
|
80
|
+
this.element.removeClassName('hasContent');
|
81
|
+
this.element.clear();
|
82
|
+
}
|
83
|
+
},
|
84
|
+
|
85
|
+
restore: function(event) {
|
86
|
+
var value = $F(this.element);
|
87
|
+
if ( value.blank() ) {
|
88
|
+
this.element.removeClassName('hasContent');
|
89
|
+
this.element.value = this.value;
|
90
|
+
}
|
91
|
+
else { this.element.addClassName('hasContent'); }
|
92
|
+
}
|
93
|
+
})
|
94
|
+
});
|
95
|
+
|
96
|
+
Classy.Validator.findForms();
|
97
|
+
Classy.Confirmable.setup();
|
98
|
+
$$('.highlightify').invoke('highlight');
|
99
|
+
$$('.fadify').invoke('fade');
|
100
|
+
$$('.pulsate').invoke('pulsate');
|
101
|
+
$$('textarea.defaultify').each(function(element) { new Classy.Defaultable(element); });
|
102
|
+
$$('input[type=text].defaultify').each(function(element) { new Classy.Defaultable(element); });
|
103
|
+
});
|
@@ -0,0 +1,18 @@
|
|
1
|
+
// Extensions to Numbers
|
2
|
+
Object.extend(Number.prototype, {
|
3
|
+
// Seconds to a more readable format: 0:12 or something like that.
|
4
|
+
toDuration: function() {
|
5
|
+
var seconds = this + 0;
|
6
|
+
h = parseInt(seconds / 3600);
|
7
|
+
m = parseInt((seconds % 3600) / 60);
|
8
|
+
s = parseInt(seconds % 60).toPaddedString(2);
|
9
|
+
var resultString = '';
|
10
|
+
resultString = resultString + (m + ':' + s);
|
11
|
+
return (h > 0) ? (h + ':' + resultString) : resultString;
|
12
|
+
},
|
13
|
+
|
14
|
+
// Bytes to kilobytes
|
15
|
+
kilobytes: function() {
|
16
|
+
return Math.ceil(this / 1000);
|
17
|
+
}
|
18
|
+
});
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
4
|
+
<head>
|
5
|
+
<title>Array Extensions Tests</title>
|
6
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
7
|
+
<script src="../vendor/prototype.js" type="text/javascript"></script>
|
8
|
+
<script src="../lib/unittest.js" type="text/javascript"></script>
|
9
|
+
<script src="../../src/array_extensions.js" type="text/javascript" charset="utf-8"></script>
|
10
|
+
<link rel="stylesheet" href="../test.css" type="text/css" />
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<h1>Array Extensions Tests</h1>
|
14
|
+
<p>Test of functions in array_extensions.js</p>
|
15
|
+
|
16
|
+
<!-- Log output -->
|
17
|
+
<div id="testlog"> </div>
|
18
|
+
|
19
|
+
<!-- Tests follow -->
|
20
|
+
<script type="text/javascript" language="javascript" charset="utf-8">
|
21
|
+
|
22
|
+
// <![CDATA[
|
23
|
+
new Test.Unit.Runner({
|
24
|
+
|
25
|
+
testShouldFindSum: function() {
|
26
|
+
var testArray = [1,2,3];
|
27
|
+
this.assertEqual(6, testArray.sum());
|
28
|
+
}
|
29
|
+
|
30
|
+
});
|
31
|
+
|
32
|
+
// ]]>
|
33
|
+
</script>
|
34
|
+
</body>
|
35
|
+
</html>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
4
|
+
<head>
|
5
|
+
<title>Number Extensions Tests</title>
|
6
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
7
|
+
<script src="../vendor/prototype.js" type="text/javascript"></script>
|
8
|
+
<script src="../lib/unittest.js" type="text/javascript"></script>
|
9
|
+
<script src="../../src/number_extensions.js" type="text/javascript" charset="utf-8"></script>
|
10
|
+
<link rel="stylesheet" href="../test.css" type="text/css" />
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<h1>Number Extensions Tests</h1>
|
14
|
+
<p>Test of functions in number_extensions.js</p>
|
15
|
+
|
16
|
+
<!-- Log output -->
|
17
|
+
<div id="testlog"> </div>
|
18
|
+
|
19
|
+
<!-- Tests follow -->
|
20
|
+
<script type="text/javascript" language="javascript" charset="utf-8">
|
21
|
+
|
22
|
+
// <![CDATA[
|
23
|
+
new Test.Unit.Runner({
|
24
|
+
|
25
|
+
testShouldFindKilobyes: function() {
|
26
|
+
var i = 6000;
|
27
|
+
this.assertEqual(6, i.kilobytes());
|
28
|
+
}
|
29
|
+
|
30
|
+
});
|
31
|
+
|
32
|
+
// ]]>
|
33
|
+
</script>
|
34
|
+
</body>
|
35
|
+
</html>
|
data/test/helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
2
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib', 'protocov')
|
3
|
+
|
4
|
+
PROTOCOV_ENV = 'test'
|
5
|
+
PROTOCOV_FIXTURE_ROOT = File.expand_path(File.dirname(__FILE__) + '/fixtures')
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
require 'mocha'
|
9
|
+
require 'protocov'
|
10
|
+
require 'test/unit'
|
11
|
+
|
12
|
+
module TestHelpers
|
13
|
+
def assert_difference(expression, difference=1, &block)
|
14
|
+
initial_value = instance_eval(expression)
|
15
|
+
yield
|
16
|
+
assert_equal initial_value+difference, instance_eval(expression)
|
17
|
+
end
|
18
|
+
|
19
|
+
def assert_no_difference(expression, &block)
|
20
|
+
initial_value = instance_eval(expression)
|
21
|
+
yield
|
22
|
+
assert_equal initial_value, instance_eval(expression)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
Test::Unit::TestCase.send(:include, TestHelpers)
|
data/test/test_runner.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestRunner < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@_dir = Dir.new(File.join(File.dirname(__FILE__), 'fixtures'))
|
7
|
+
@_runner = ProtoCov::Runner.new([File.join(File.dirname(__FILE__), 'fixtures')])
|
8
|
+
end
|
9
|
+
|
10
|
+
# This test might belong in test_source_file.rb
|
11
|
+
def test_should_get_source_files
|
12
|
+
assert_equal 3, @_runner.source_files.length
|
13
|
+
filenames = @_runner.source_files.invoke(:filename)
|
14
|
+
assert filenames.include?('array_extensions.js')
|
15
|
+
assert filenames.include?('number_extensions.js')
|
16
|
+
assert ! filenames.include?('.')
|
17
|
+
assert ! filenames.include?('..')
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_should_get_test_files
|
21
|
+
assert_equal 2, @_runner.test_files.length
|
22
|
+
filenames = @_runner.test_files.invoke(:filename)
|
23
|
+
assert filenames.include?('array_extensions_test.html')
|
24
|
+
assert filenames.include?('number_extensions_test.html')
|
25
|
+
assert ! filenames.include?('.')
|
26
|
+
assert ! filenames.include?('..')
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestSourceFile < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@_test_file = ProtoCov::SourceFile.new('array_extensions.js', PROTOCOV_FIXTURE_ROOT + '/src')
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_should_get_path
|
10
|
+
assert_equal "#{PROTOCOV_FIXTURE_ROOT}/src/array_extensions.js", @_test_file.path
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_should_get_lines
|
14
|
+
assert_equal 11, @_test_file.lines.length
|
15
|
+
assert_equal ' sum: function() {', @_test_file.lines[1]
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_should_get_body
|
19
|
+
str = File.read("#{PROTOCOV_FIXTURE_ROOT}/src/array_extensions.js")
|
20
|
+
assert_equal str, @_test_file.body
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestStringExtensions < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@_test_string_1 = File.read(PROTOCOV_FIXTURE_ROOT + '/src/array_extensions.js')
|
7
|
+
@_test_string_2 = File.read(PROTOCOV_FIXTURE_ROOT + '/src/classy_behaviors.js')
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_should_get_method_definitions
|
11
|
+
method_definitions = @_test_string_1.parse_for(:method_definitions)
|
12
|
+
assert_equal 2, method_definitions.length
|
13
|
+
assert method_definitions.include?('sum')
|
14
|
+
assert method_definitions.include?('mean')
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_should_get_method_invocations
|
18
|
+
method_invocations = @_test_string_2.parse_for(:method_invocations)
|
19
|
+
assert_equal 10, method_invocations.length
|
20
|
+
%w(any bindAsEventListener blank clear element findForms setup setupBehaviors stop uniq).each do |method|
|
21
|
+
assert method_invocations.include?(method)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_should_get_modules
|
26
|
+
module_names = @_test_string_2.parse_for(:modules)
|
27
|
+
assert_equal 3, module_names.length
|
28
|
+
assert module_names.include?('Validator')
|
29
|
+
assert module_names.include?('Confirmable')
|
30
|
+
assert module_names.include?('Classy')
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_should_get_classes
|
34
|
+
class_names = @_test_string_2.parse_for(:classes)
|
35
|
+
assert 1, class_names.length
|
36
|
+
assert class_names.include?('Defaultable')
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
# This is a stupid name for a class.
|
4
|
+
# Convention over configuration my foot.
|
5
|
+
class TestTestFile < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@_test_file = ProtoCov::TestFile.new('array_extensions_test.html', PROTOCOV_FIXTURE_ROOT + '/test/unit')
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_should_get_path
|
12
|
+
assert_equal "#{PROTOCOV_FIXTURE_ROOT}/test/unit/array_extensions_test.html", @_test_file.path
|
13
|
+
end
|
14
|
+
|
15
|
+
# This is nowhere near good enough
|
16
|
+
def test_should_get_lines
|
17
|
+
assert_equal 35, @_test_file.lines.length
|
18
|
+
assert_equal '<h1>Array Extensions Tests</h1>', @_test_file.lines[12]
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_should_get_body
|
22
|
+
str = File.read("#{PROTOCOV_FIXTURE_ROOT}/test/unit/array_extensions_test.html")
|
23
|
+
assert_equal str, @_test_file.body
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nakajima-protocov
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pat Nakajima
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-05-22 00:00:00 -07:00
|
13
|
+
default_executable: protocov
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email:
|
18
|
+
- patnakajima@gmail.com
|
19
|
+
executables:
|
20
|
+
- protocov
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files:
|
24
|
+
- History.txt
|
25
|
+
- Manifest.txt
|
26
|
+
- LICENSE.txt
|
27
|
+
- README.txt
|
28
|
+
files:
|
29
|
+
- History.txt
|
30
|
+
- Manifest.txt
|
31
|
+
- LICENSE.txt
|
32
|
+
- README.txt
|
33
|
+
- Rakefile
|
34
|
+
- bin/protocov
|
35
|
+
- lib/protocov/ext/array_extensions.rb
|
36
|
+
- lib/protocov/ext/string_extensions.rb
|
37
|
+
- lib/protocov/ext/object_extensions.rb
|
38
|
+
- lib/protocov.rb
|
39
|
+
- lib/protocov/base.rb
|
40
|
+
- lib/protocov/runner.rb
|
41
|
+
- lib/protocov/source_file.rb
|
42
|
+
- lib/protocov/test_file.rb
|
43
|
+
- test/helper.rb
|
44
|
+
- test/test_protocov.rb
|
45
|
+
- test/test_runner.rb
|
46
|
+
- test/test_source_file.rb
|
47
|
+
- test/test_test_file.rb
|
48
|
+
- test/test_string_extensions.rb
|
49
|
+
- test/fixtures/src/classy_behaviors.js
|
50
|
+
- test/fixtures/src/array_extensions.js
|
51
|
+
- test/fixtures/src/number_extensions.js
|
52
|
+
- test/fixtures/test/unit/array_extensions_test.html
|
53
|
+
- test/fixtures/test/unit/number_extensions_test.html
|
54
|
+
has_rdoc: true
|
55
|
+
homepage: http://github.com/nakajima/protocov
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options:
|
58
|
+
- --main
|
59
|
+
- README.txt
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
version:
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.0.1
|
78
|
+
signing_key:
|
79
|
+
specification_version: 2
|
80
|
+
summary: ""
|
81
|
+
test_files:
|
82
|
+
- test/test_protocov.rb
|
83
|
+
- test/test_runner.rb
|
84
|
+
- test/test_source_file.rb
|
85
|
+
- test/test_string_extensions.rb
|
86
|
+
- test/test_test_file.rb
|