jsmetric 0.1

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.
Files changed (45) hide show
  1. data/.gitignore +6 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile +2 -0
  4. data/README +36 -0
  5. data/Rakefile +37 -0
  6. data/bin/jsmetric +16 -0
  7. data/boot.rb +5 -0
  8. data/build +1 -0
  9. data/features/cyclometric_complexity/boolean_complexity_counting.feature +46 -0
  10. data/features/cyclometric_complexity/case_complexity_counting.feature +117 -0
  11. data/features/cyclometric_complexity/exception_complexity_counting.feature +81 -0
  12. data/features/cyclometric_complexity/function_detection.feature +128 -0
  13. data/features/cyclometric_complexity/if_else_complexity_counting.feature +178 -0
  14. data/features/cyclometric_complexity/loop_complexity_counting.feature +81 -0
  15. data/features/graphing/draw_basic_graph.feature +14 -0
  16. data/features/reporting/report.feature +13 -0
  17. data/features/sample_js_files_for_test/foobar.js +30 -0
  18. data/features/step_definitions/cyclometric_complexity_steps.rb +31 -0
  19. data/features/step_definitions/graph_steps.rb +10 -0
  20. data/features/step_definitions/reporting_steps.rb +14 -0
  21. data/features/support/env.rb +1 -0
  22. data/jsgraphlib/Curry-1.0.1.js +29 -0
  23. data/jsgraphlib/dracula_algorithms.js +599 -0
  24. data/jsgraphlib/dracula_graffle.js +106 -0
  25. data/jsgraphlib/dracula_graph.js +534 -0
  26. data/jsgraphlib/graphtest.html +57 -0
  27. data/jsgraphlib/jquery-1.4.2.min.js +154 -0
  28. data/jsgraphlib/jsgraphsource.js +12 -0
  29. data/jsgraphlib/raphael-min.js +7 -0
  30. data/jsgraphlib/seedrandom.js +266 -0
  31. data/jsmetric.gemspec +26 -0
  32. data/lib/cc_report.rb +20 -0
  33. data/lib/complexity_analyser.rb +90 -0
  34. data/lib/fulljslint.js +6100 -0
  35. data/lib/graphing/graph_analyser.rb +19 -0
  36. data/lib/js_lint.rb +28 -0
  37. data/lib/json2.js +480 -0
  38. data/lib/options.js +24 -0
  39. data/lib/report.rb +9 -0
  40. data/lib/utils.rb +18 -0
  41. data/lib/version.rb +3 -0
  42. data/spec/spec_helper.rb +1 -0
  43. data/tasks/dev.rb +4 -0
  44. data/tasks/run.rb +55 -0
  45. metadata +175 -0
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .idea
6
+ .DS_Store
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm ruby-1.9.2@jsmetric
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
data/README ADDED
@@ -0,0 +1,36 @@
1
+ [WARNING: This project is not yet ready for proper use. Its very much an alpha at the moment]
2
+
3
+ *** Installation
4
+
5
+ $ gem install jsmetric
6
+
7
+
8
+ *** Usage
9
+
10
+ Cyclometric Complexity
11
+ $ ./bin/jsmetric path_to_js_file
12
+
13
+
14
+ *** Backlog/Future Work
15
+
16
+ - JSLint options are buried in the options.js file. Need to pull these out.
17
+ - Refactor the nasty code in the complexity analyser
18
+ - Add Debug messages for when a JS file fails JSLint validation
19
+
20
+
21
+ [Notes for developing JSMetric itself futher]
22
+
23
+ *** To get started you need:
24
+
25
+ Ruby 1.9.2
26
+ Bundler 1.x
27
+
28
+ This project contains a .rvmrc file for use with RVM.
29
+
30
+ *** Setting up dev environment
31
+
32
+ $ ./build
33
+
34
+ *** Dev smoke
35
+
36
+ $ ./bin/jsmetric features/sample_js_files_for_test/foobar.js
@@ -0,0 +1,37 @@
1
+ require 'bundler'
2
+ require "bundler/setup"
3
+ require "rubygems"
4
+
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ PROJECT_ROOT = File.expand_path("..", __FILE__)
8
+ $:.unshift "#{PROJECT_ROOT}/lib"
9
+
10
+ require 'rake'
11
+ require 'rake/testtask'
12
+ require 'rake/rdoctask'
13
+
14
+ # Cucumber configurations
15
+ require 'cucumber/rake/task'
16
+ Cucumber::Rake::Task.new do |t|
17
+ t.cucumber_opts = "--format pretty"
18
+ end
19
+
20
+ # RSpec
21
+
22
+ require 'rspec/core/rake_task'
23
+ RSpec::Core::RakeTask.new(:spec)
24
+
25
+
26
+ # other Project tasks
27
+ Dir[File.join(File.dirname(__FILE__),"tasks","*.rb")].each {|file| require file }
28
+
29
+ namespace :jsmetrics do
30
+ desc "master build"
31
+ task :build => [:spec, "cucumber"]
32
+ end
33
+
34
+ task :default => ["jsmetrics:build"]
35
+
36
+
37
+
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rubygems"
4
+ require "bundler/setup"
5
+
6
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
7
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
8
+
9
+
10
+ args = ARGV.dup
11
+ ARGV.clear
12
+ file_path = args.shift.strip rescue 'help'
13
+
14
+ require 'report'
15
+ puts Report.for file_path
16
+
data/boot.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+
4
+ Dir[File.join(File.dirname(__FILE__),"lib","*.rb")].each {|file| require file }
5
+ Dir[File.join(File.dirname(__FILE__),"lib","graphing","*.rb")].each {|file| require file }
data/build ADDED
@@ -0,0 +1 @@
1
+ bundle install && bundle exec rake
@@ -0,0 +1,46 @@
1
+ @booloperator
2
+ Feature: Calculate complexity for code that includes BOOLEAN decisions
3
+
4
+ Scenario: IF statement with BOOLEAN &&
5
+ Given javascript code as:
6
+ """
7
+ function foo() {
8
+ var bar,baz;
9
+ if(bar && baz) {}
10
+ };
11
+ """
12
+ When I run the complexity analysis on it
13
+ Then the complexity is reported as "3"
14
+
15
+ Scenario: IF statement with BOOLEAN ||
16
+ Given javascript code as:
17
+ """
18
+ function foo() {
19
+ var bar,baz;
20
+ if(bar || baz) {}
21
+ };
22
+ """
23
+ When I run the complexity analysis on it
24
+ Then the complexity is reported as "3"
25
+
26
+ Scenario: IF statement with multiple BOOLEAN &&
27
+ Given javascript code as:
28
+ """
29
+ function foo() {
30
+ var bar,baz;
31
+ if(bar && baz && bar) {}
32
+ };
33
+ """
34
+ When I run the complexity analysis on it
35
+ Then the complexity is reported as "4"
36
+
37
+ Scenario: IF statement with multiple BOOLEAN operators
38
+ Given javascript code as:
39
+ """
40
+ function foo() {
41
+ var bar,baz;
42
+ if(bar && baz || bar && baz) {}
43
+ };
44
+ """
45
+ When I run the complexity analysis on it
46
+ Then the complexity is reported as "5"
@@ -0,0 +1,117 @@
1
+ @switch
2
+ Feature: Calculate CASE/DEFAULT complexity for a stand alone Javascript function
3
+
4
+ Scenario: SWITCH with DEFAULT only
5
+ Given javascript code as:
6
+ """
7
+ function foo() {
8
+ var bar;
9
+ switch(bar) {
10
+ default:
11
+ //do something
12
+ }
13
+ }
14
+ """
15
+ When I run the complexity analysis on it
16
+ Then the complexity is reported as "2"
17
+
18
+ Scenario: SWITCH with single CASE statement
19
+ Given javascript code as:
20
+ """
21
+ function foo() {
22
+ var bar;
23
+ switch(bar) {
24
+ case true:
25
+ //do something
26
+ }
27
+ }
28
+ """
29
+ When I run the complexity analysis on it
30
+ Then the complexity is reported as "2"
31
+
32
+ Scenario: SWITCH with single CASE and it breaks out the SWITCH statements
33
+ Given javascript code as:
34
+ """
35
+ function foo() {
36
+ var bar;
37
+ switch(bar) {
38
+ case true:
39
+ //do something
40
+ break;
41
+ }
42
+ }
43
+ """
44
+ When I run the complexity analysis on it
45
+ Then the complexity is reported as "2"
46
+
47
+ Scenario: SWITCH with multiple CASE and each breaks out the SWITCH
48
+ Given javascript code as:
49
+ """
50
+ function foo() {
51
+ var bar;
52
+ switch(bar) {
53
+ case true:
54
+ //do something
55
+ break;
56
+
57
+ case false:
58
+ //do something
59
+ break;
60
+ }
61
+ }
62
+ """
63
+ When I run the complexity analysis on it
64
+ Then the complexity is reported as "3"
65
+
66
+ Scenario: SWITCH with multiple CASE and neither break out the SWITCH
67
+ Given javascript code as:
68
+ """
69
+ function foo() {
70
+ var bar, temp;
71
+
72
+ switch(bar) {
73
+ case true:
74
+ temp = "first"
75
+ //do something
76
+
77
+ case false:
78
+ temp = "second"
79
+ //do something
80
+ }
81
+ }
82
+ """
83
+ When I run the complexity analysis on it
84
+ Then the complexity is reported as "3"
85
+
86
+
87
+ Scenario: SWITCH with multiple CASE with no-ops are considered as a single Case
88
+ Given javascript code as:
89
+ """
90
+ function foo() {
91
+ var bar, temp;
92
+
93
+ switch(bar) {
94
+ case true:
95
+ case false:
96
+ case "blah":
97
+ }
98
+ }
99
+ """
100
+ When I run the complexity analysis on it
101
+ Then the complexity is reported as "2"
102
+
103
+ Scenario: SWITCH with multiple CASE with no-ops and Default
104
+ Given javascript code as:
105
+ """
106
+ function foo() {
107
+ var bar, temp;
108
+
109
+ switch(bar) {
110
+ case true:
111
+ case false:
112
+ default:
113
+ }
114
+ }
115
+ """
116
+ When I run the complexity analysis on it
117
+ Then the complexity is reported as "3"
@@ -0,0 +1,81 @@
1
+ @exceptions
2
+ Feature: Calculate TRY/CATCH complexity for a stand alone Javascript function
3
+
4
+ Scenario: Single TRY CATCH in a function
5
+ Given javascript code as:
6
+ """
7
+ function foo() {
8
+ try
9
+ {
10
+ //Run some code here
11
+ }
12
+ catch(err)
13
+ {
14
+ //Handle errors here
15
+ }
16
+ }
17
+ """
18
+ When I run the complexity analysis on it
19
+ Then the complexity is reported as "2"
20
+
21
+ Scenario: Single TRY FINALLY in a function
22
+ Given javascript code as:
23
+ """
24
+ function foo() {
25
+ try
26
+ {
27
+ //Run some code here
28
+ }
29
+ finally
30
+ {
31
+ //Handle errors here
32
+ }
33
+ }
34
+ """
35
+ When I run the complexity analysis on it
36
+ Then the complexity is reported as "2"
37
+
38
+ Scenario: Single TRY CATCH FINALLY in a function
39
+ Given javascript code as:
40
+ """
41
+ function foo() {
42
+ try
43
+ {
44
+ //Run some code here
45
+ }
46
+ catch(err)
47
+ {
48
+ //Handle errors here
49
+ }
50
+ finally
51
+ {
52
+ //Handle errors here
53
+ }
54
+ }
55
+ """
56
+ When I run the complexity analysis on it
57
+ Then the complexity is reported as "3"
58
+
59
+ Scenario: Nested TRY inside a CATCH in a function
60
+ Given javascript code as:
61
+ """
62
+ function foo() {
63
+ try
64
+ {
65
+ //Run some code here
66
+ }
67
+ catch(err)
68
+ {
69
+
70
+ try
71
+ {
72
+ //Run some code here
73
+ }
74
+ catch (anotherErr)
75
+ {
76
+ //Handle errors here
77
+ }
78
+ }
79
+ """
80
+ When I run the complexity analysis on it
81
+ Then the complexity is reported as "3"
@@ -0,0 +1,128 @@
1
+ @functions
2
+ Feature: Calculate number of functions and their names for a stand alone Javascript snippet
3
+
4
+ Scenario: Only statements and no functions
5
+ Given javascript code as:
6
+ """
7
+ var foo = {} || "";
8
+ var baz = 2;
9
+ """
10
+ When I run the complexity analysis on it
11
+ Then the number of functions is reported as "0"
12
+
13
+ Scenario: Single javascript function
14
+ Given javascript code as:
15
+ """
16
+ function foo() {};
17
+ """
18
+ When I run the complexity analysis on it
19
+ Then the number of functions is reported as "1"
20
+ And the function name is "foo"
21
+
22
+ Scenario: Multiple javascript functions
23
+ Given javascript code as:
24
+ """
25
+ function foo() {};
26
+ function bar() {};
27
+ """
28
+ When I run the complexity analysis on it
29
+ Then the number of functions is reported as "2"
30
+ And the function names are:
31
+ | Name |
32
+ | foo |
33
+ | bar |
34
+
35
+
36
+ Scenario: Multiple javascript functions nested
37
+ Given javascript code as:
38
+ """
39
+ function foo() {
40
+ function bar() {};
41
+ };
42
+ """
43
+ When I run the complexity analysis on it
44
+ Then the number of functions is reported as "2"
45
+
46
+ Scenario: Single outer function with inner private function assigned to a var
47
+ Given javascript code as:
48
+ """
49
+ function foo() {
50
+ var baz = function() {};
51
+ };
52
+ """
53
+ When I run the complexity analysis on it
54
+ Then the number of functions is reported as "2"
55
+ And the function names are:
56
+ | Name |
57
+ | foo |
58
+ | baz |
59
+
60
+ Scenario: Single outer function with inner private function that is unassigned
61
+ Given javascript code as:
62
+ """
63
+ function foo() {
64
+ function bar() {};
65
+ };
66
+ """
67
+ When I run the complexity analysis on it
68
+ Then the number of functions is reported as "2"
69
+ And the function names are:
70
+ | Name |
71
+ | foo |
72
+ | bar |
73
+
74
+ Scenario: Single outer function with inner public function
75
+ Given javascript code as:
76
+ """
77
+ function foo() {
78
+ this.baz.flaz = function() {};
79
+ };
80
+ """
81
+ When I run the complexity analysis on it
82
+ Then the number of functions is reported as "2"
83
+ And the function names are:
84
+ | Name |
85
+ | foo |
86
+ | this.baz.flaz |
87
+
88
+ Scenario: Single outer Object with inner public function
89
+ Given javascript code as:
90
+ """
91
+ var foo = {
92
+ flaz : function() {},
93
+ blah : "",
94
+ baz : function() {}
95
+ };
96
+ """
97
+ When I run the complexity analysis on it
98
+ Then the number of functions is reported as "2"
99
+ And the function names are:
100
+ | Name |
101
+ | flaz |
102
+ | baz |
103
+
104
+ Scenario: Single outer function with inner annonymous function
105
+ Given javascript code as:
106
+ """
107
+ function foo() {
108
+ return function() {};
109
+ };
110
+ """
111
+ When I run the complexity analysis on it
112
+ Then the number of functions is reported as "2"
113
+ And the function names are:
114
+ | Name |
115
+ | foo |
116
+ | Annonymous |
117
+
118
+
119
+ Scenario: Single javascript function containing the string "function"
120
+ Given javascript code as:
121
+ """
122
+ function foo() {
123
+ return "function";
124
+ };
125
+ """
126
+ When I run the complexity analysis on it
127
+ Then the number of functions is reported as "1"
128
+ And the function name is "foo"