code_metric_fu 4.14.0

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 (296) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +28 -0
  3. data/.metrics +3 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +15 -0
  6. data/.rubocop_todo.yml +69 -0
  7. data/.simplecov +74 -0
  8. data/.travis.yml +22 -0
  9. data/.yardopts +4 -0
  10. data/AUTHORS +12 -0
  11. data/CONTRIBUTING.md +47 -0
  12. data/CONTRIBUTORS +76 -0
  13. data/DEV.md +76 -0
  14. data/Gemfile +74 -0
  15. data/Guardfile +30 -0
  16. data/HISTORY.md +705 -0
  17. data/MIT-LICENSE +22 -0
  18. data/README.md +299 -0
  19. data/Rakefile +27 -0
  20. data/TODO.md +118 -0
  21. data/appveyor.yml +31 -0
  22. data/bin/metric_fu +9 -0
  23. data/bin/mf-cane +10 -0
  24. data/bin/mf-churn +10 -0
  25. data/bin/mf-flay +10 -0
  26. data/bin/mf-reek +10 -0
  27. data/bin/mf-roodi +10 -0
  28. data/bin/mf-saikuro +10 -0
  29. data/certs/bf4.pem +22 -0
  30. data/checksum/.gitkeep +0 -0
  31. data/checksum/metric_fu-4.10.0.gem.sha512 +1 -0
  32. data/checksum/metric_fu-4.11.0.gem.sha512 +1 -0
  33. data/checksum/metric_fu-4.11.1.gem.sha512 +1 -0
  34. data/checksum/metric_fu-4.11.2.gem.sha512 +1 -0
  35. data/checksum/metric_fu-4.11.3.gem.sha512 +1 -0
  36. data/checksum/metric_fu-4.11.4.gem.sha512 +1 -0
  37. data/checksum/metric_fu-4.12.0.gem.sha512 +1 -0
  38. data/checksum/metric_fu-4.2.0.gem.sha512 +1 -0
  39. data/checksum/metric_fu-4.2.1.gem.sha512 +1 -0
  40. data/checksum/metric_fu-4.3.0.gem.sha512 +1 -0
  41. data/checksum/metric_fu-4.3.1.gem.sha512 +1 -0
  42. data/checksum/metric_fu-4.4.0.gem.sha512 +1 -0
  43. data/checksum/metric_fu-4.4.1.gem.sha512 +1 -0
  44. data/checksum/metric_fu-4.4.2.gem.sha512 +1 -0
  45. data/checksum/metric_fu-4.4.3.gem.sha512 +1 -0
  46. data/checksum/metric_fu-4.4.4.gem.sha512 +1 -0
  47. data/checksum/metric_fu-4.5.0.gem.sha512 +1 -0
  48. data/checksum/metric_fu-4.5.1.gem.sha512 +1 -0
  49. data/checksum/metric_fu-4.5.2.gem.sha512 +1 -0
  50. data/checksum/metric_fu-4.6.0.gem.sha512 +1 -0
  51. data/checksum/metric_fu-4.7.0.gem.sha512 +1 -0
  52. data/checksum/metric_fu-4.7.1.gem.sha512 +1 -0
  53. data/checksum/metric_fu-4.7.2.gem.sha512 +1 -0
  54. data/checksum/metric_fu-4.7.3.gem.sha512 +1 -0
  55. data/checksum/metric_fu-4.7.4.gem.sha512 +1 -0
  56. data/checksum/metric_fu-4.8.0.gem.sha512 +1 -0
  57. data/checksum/metric_fu-4.9.0.gem.sha512 +1 -0
  58. data/config/roodi_config.yml +22 -0
  59. data/config/rubocop.yml +269 -0
  60. data/gem_tasks/build.rake +197 -0
  61. data/gem_tasks/rubocop.rake +10 -0
  62. data/gem_tasks/usage_test.rake +19 -0
  63. data/gem_tasks/yard.rake +24 -0
  64. data/lib/metric_fu/calculate.rb +10 -0
  65. data/lib/metric_fu/cli/client.rb +26 -0
  66. data/lib/metric_fu/cli/helper.rb +80 -0
  67. data/lib/metric_fu/cli/parser.rb +138 -0
  68. data/lib/metric_fu/configuration.rb +150 -0
  69. data/lib/metric_fu/constantize.rb +57 -0
  70. data/lib/metric_fu/data_structures/line_numbers.rb +112 -0
  71. data/lib/metric_fu/data_structures/location.rb +110 -0
  72. data/lib/metric_fu/data_structures/sexp_node.rb +107 -0
  73. data/lib/metric_fu/environment.rb +129 -0
  74. data/lib/metric_fu/errors/analysis_error.rb +4 -0
  75. data/lib/metric_fu/formatter/html.rb +96 -0
  76. data/lib/metric_fu/formatter/syntax.rb +45 -0
  77. data/lib/metric_fu/formatter/yaml.rb +18 -0
  78. data/lib/metric_fu/formatter.rb +40 -0
  79. data/lib/metric_fu/gem_run.rb +70 -0
  80. data/lib/metric_fu/gem_version.rb +92 -0
  81. data/lib/metric_fu/generator.rb +135 -0
  82. data/lib/metric_fu/io.rb +132 -0
  83. data/lib/metric_fu/loader.rb +105 -0
  84. data/lib/metric_fu/logger.rb +62 -0
  85. data/lib/metric_fu/logging/mf_debugger.rb +23 -0
  86. data/lib/metric_fu/metric.rb +143 -0
  87. data/lib/metric_fu/metrics/cane/generator.rb +95 -0
  88. data/lib/metric_fu/metrics/cane/grapher.rb +37 -0
  89. data/lib/metric_fu/metrics/cane/metric.rb +34 -0
  90. data/lib/metric_fu/metrics/cane/report.html.erb +87 -0
  91. data/lib/metric_fu/metrics/cane/violations.rb +46 -0
  92. data/lib/metric_fu/metrics/churn/generator.rb +37 -0
  93. data/lib/metric_fu/metrics/churn/hotspot.rb +43 -0
  94. data/lib/metric_fu/metrics/churn/metric.rb +29 -0
  95. data/lib/metric_fu/metrics/churn/report.html.erb +58 -0
  96. data/lib/metric_fu/metrics/flay/generator.rb +51 -0
  97. data/lib/metric_fu/metrics/flay/grapher.rb +37 -0
  98. data/lib/metric_fu/metrics/flay/hotspot.rb +52 -0
  99. data/lib/metric_fu/metrics/flay/metric.rb +28 -0
  100. data/lib/metric_fu/metrics/flay/report.html.erb +29 -0
  101. data/lib/metric_fu/metrics/flog/generator.rb +113 -0
  102. data/lib/metric_fu/metrics/flog/grapher.rb +77 -0
  103. data/lib/metric_fu/metrics/flog/hotspot.rb +46 -0
  104. data/lib/metric_fu/metrics/flog/metric.rb +29 -0
  105. data/lib/metric_fu/metrics/flog/report.html.erb +50 -0
  106. data/lib/metric_fu/metrics/hotspots/analysis/analyzed_problems.rb +34 -0
  107. data/lib/metric_fu/metrics/hotspots/analysis/analyzer_tables.rb +114 -0
  108. data/lib/metric_fu/metrics/hotspots/analysis/grouping.rb +23 -0
  109. data/lib/metric_fu/metrics/hotspots/analysis/groupings.rb +12 -0
  110. data/lib/metric_fu/metrics/hotspots/analysis/problems.rb +20 -0
  111. data/lib/metric_fu/metrics/hotspots/analysis/ranked_problem_location.rb +70 -0
  112. data/lib/metric_fu/metrics/hotspots/analysis/ranking.rb +29 -0
  113. data/lib/metric_fu/metrics/hotspots/analysis/rankings.rb +91 -0
  114. data/lib/metric_fu/metrics/hotspots/analysis/record.rb +32 -0
  115. data/lib/metric_fu/metrics/hotspots/analysis/scoring_strategies.rb +24 -0
  116. data/lib/metric_fu/metrics/hotspots/analysis/table.rb +67 -0
  117. data/lib/metric_fu/metrics/hotspots/generator.rb +40 -0
  118. data/lib/metric_fu/metrics/hotspots/hotspot.rb +87 -0
  119. data/lib/metric_fu/metrics/hotspots/hotspot_analyzer.rb +61 -0
  120. data/lib/metric_fu/metrics/hotspots/metric.rb +20 -0
  121. data/lib/metric_fu/metrics/hotspots/report.html.erb +60 -0
  122. data/lib/metric_fu/metrics/rails_best_practices/generator.rb +47 -0
  123. data/lib/metric_fu/metrics/rails_best_practices/grapher.rb +38 -0
  124. data/lib/metric_fu/metrics/rails_best_practices/metric.rb +31 -0
  125. data/lib/metric_fu/metrics/rails_best_practices/report.html.erb +22 -0
  126. data/lib/metric_fu/metrics/rcov/external_client.rb +22 -0
  127. data/lib/metric_fu/metrics/rcov/generator.rb +75 -0
  128. data/lib/metric_fu/metrics/rcov/grapher.rb +37 -0
  129. data/lib/metric_fu/metrics/rcov/hotspot.rb +46 -0
  130. data/lib/metric_fu/metrics/rcov/metric.rb +61 -0
  131. data/lib/metric_fu/metrics/rcov/rcov_format_coverage.rb +149 -0
  132. data/lib/metric_fu/metrics/rcov/rcov_line.rb +48 -0
  133. data/lib/metric_fu/metrics/rcov/report.html.erb +40 -0
  134. data/lib/metric_fu/metrics/rcov/simplecov_formatter.rb +74 -0
  135. data/lib/metric_fu/metrics/reek/generator.rb +97 -0
  136. data/lib/metric_fu/metrics/reek/grapher.rb +55 -0
  137. data/lib/metric_fu/metrics/reek/hotspot.rb +95 -0
  138. data/lib/metric_fu/metrics/reek/metric.rb +26 -0
  139. data/lib/metric_fu/metrics/reek/report.html.erb +35 -0
  140. data/lib/metric_fu/metrics/roodi/generator.rb +41 -0
  141. data/lib/metric_fu/metrics/roodi/grapher.rb +37 -0
  142. data/lib/metric_fu/metrics/roodi/hotspot.rb +39 -0
  143. data/lib/metric_fu/metrics/roodi/metric.rb +24 -0
  144. data/lib/metric_fu/metrics/roodi/report.html.erb +22 -0
  145. data/lib/metric_fu/metrics/saikuro/generator.rb +145 -0
  146. data/lib/metric_fu/metrics/saikuro/hotspot.rb +51 -0
  147. data/lib/metric_fu/metrics/saikuro/metric.rb +31 -0
  148. data/lib/metric_fu/metrics/saikuro/parsing_element.rb +37 -0
  149. data/lib/metric_fu/metrics/saikuro/report.html.erb +71 -0
  150. data/lib/metric_fu/metrics/saikuro/scratch_file.rb +108 -0
  151. data/lib/metric_fu/metrics/stats/generator.rb +82 -0
  152. data/lib/metric_fu/metrics/stats/grapher.rb +40 -0
  153. data/lib/metric_fu/metrics/stats/hotspot.rb +35 -0
  154. data/lib/metric_fu/metrics/stats/metric.rb +28 -0
  155. data/lib/metric_fu/metrics/stats/report.html.erb +44 -0
  156. data/lib/metric_fu/reporter.rb +37 -0
  157. data/lib/metric_fu/reporting/graphs/graph.rb +69 -0
  158. data/lib/metric_fu/reporting/graphs/grapher.rb +66 -0
  159. data/lib/metric_fu/reporting/result.rb +59 -0
  160. data/lib/metric_fu/run.rb +82 -0
  161. data/lib/metric_fu/tasks/metric_fu.rake +54 -0
  162. data/lib/metric_fu/templates/_gem_info.html.erb +8 -0
  163. data/lib/metric_fu/templates/_graph.html.erb +2 -0
  164. data/lib/metric_fu/templates/_report_footer.html.erb +1 -0
  165. data/lib/metric_fu/templates/configuration.rb +25 -0
  166. data/lib/metric_fu/templates/css/bluff.css +15 -0
  167. data/lib/metric_fu/templates/css/buttons.css +82 -0
  168. data/lib/metric_fu/templates/css/default.css +43 -0
  169. data/lib/metric_fu/templates/css/integrity.css +337 -0
  170. data/lib/metric_fu/templates/css/rcov.css +32 -0
  171. data/lib/metric_fu/templates/css/reset.css +7 -0
  172. data/lib/metric_fu/templates/css/syntax.css +19 -0
  173. data/lib/metric_fu/templates/index.html.erb +13 -0
  174. data/lib/metric_fu/templates/javascripts/bluff-min.js +1 -0
  175. data/lib/metric_fu/templates/javascripts/bluff_graph.js +15 -0
  176. data/lib/metric_fu/templates/javascripts/excanvas.js +35 -0
  177. data/lib/metric_fu/templates/javascripts/highcharts.js +294 -0
  178. data/lib/metric_fu/templates/javascripts/highcharts_graph.js +38 -0
  179. data/lib/metric_fu/templates/javascripts/js-class.js +1 -0
  180. data/lib/metric_fu/templates/javascripts/standalone-framework.js +17 -0
  181. data/lib/metric_fu/templates/javascripts/utils.js +9 -0
  182. data/lib/metric_fu/templates/layout.html.erb +41 -0
  183. data/lib/metric_fu/templates/metrics_template.rb +86 -0
  184. data/lib/metric_fu/templates/report.html.erb +31 -0
  185. data/lib/metric_fu/templates/report.rb +41 -0
  186. data/lib/metric_fu/templates/template.rb +247 -0
  187. data/lib/metric_fu/utility.rb +79 -0
  188. data/lib/metric_fu/version.rb +9 -0
  189. data/lib/metric_fu.rb +143 -0
  190. data/metric_fu.gemspec +72 -0
  191. data/spec/capture_warnings.rb +55 -0
  192. data/spec/cli/helper_spec.rb +165 -0
  193. data/spec/dummy/.gitignore +1 -0
  194. data/spec/dummy/.gitkeep +0 -0
  195. data/spec/dummy/.metrics +4 -0
  196. data/spec/dummy/lib/.gitkeep +0 -0
  197. data/spec/dummy/lib/bad_encoding.rb +6 -0
  198. data/spec/dummy/spec/.gitkeep +0 -0
  199. data/spec/fixtures/20090630.yml +7922 -0
  200. data/spec/fixtures/coverage-153.rb +11 -0
  201. data/spec/fixtures/coverage.rb +13 -0
  202. data/spec/fixtures/exit0.sh +3 -0
  203. data/spec/fixtures/exit1.sh +3 -0
  204. data/spec/fixtures/hotspots/flog.yml +86 -0
  205. data/spec/fixtures/hotspots/generator.yml +47 -0
  206. data/spec/fixtures/hotspots/generator_analysis.yml +53 -0
  207. data/spec/fixtures/hotspots/reek.yml +14 -0
  208. data/spec/fixtures/hotspots/roodi.yml +13 -0
  209. data/spec/fixtures/hotspots/saikuro.yml +27 -0
  210. data/spec/fixtures/hotspots/several_metrics.yml +47 -0
  211. data/spec/fixtures/hotspots/stats.yml +4 -0
  212. data/spec/fixtures/hotspots/three_metrics_on_same_file.yml +36 -0
  213. data/spec/fixtures/line_numbers/foo.rb +33 -0
  214. data/spec/fixtures/line_numbers/module.rb +11 -0
  215. data/spec/fixtures/line_numbers/module_surrounds_class.rb +15 -0
  216. data/spec/fixtures/line_numbers/two_classes.rb +11 -0
  217. data/spec/fixtures/metric_missing.yml +1 -0
  218. data/spec/fixtures/rcov_output.txt +135 -0
  219. data/spec/fixtures/saikuro/app/controllers/sessions_controller.rb_cyclo.html +10 -0
  220. data/spec/fixtures/saikuro/app/controllers/users_controller.rb_cyclo.html +16 -0
  221. data/spec/fixtures/saikuro/index_cyclo.html +155 -0
  222. data/spec/fixtures/saikuro_sfiles/thing.rb_cyclo.html +11 -0
  223. data/spec/metric_fu/calculate_spec.rb +21 -0
  224. data/spec/metric_fu/configuration_spec.rb +90 -0
  225. data/spec/metric_fu/data_structures/line_numbers_spec.rb +63 -0
  226. data/spec/metric_fu/data_structures/location_spec.rb +110 -0
  227. data/spec/metric_fu/formatter/configuration_spec.rb +44 -0
  228. data/spec/metric_fu/formatter/html_spec.rb +138 -0
  229. data/spec/metric_fu/formatter/yaml_spec.rb +61 -0
  230. data/spec/metric_fu/formatter_spec.rb +49 -0
  231. data/spec/metric_fu/gem_version_spec.rb +12 -0
  232. data/spec/metric_fu/generator_spec.rb +130 -0
  233. data/spec/metric_fu/loader_spec.rb +10 -0
  234. data/spec/metric_fu/metric_spec.rb +46 -0
  235. data/spec/metric_fu/metrics/cane/configuration_spec.rb +22 -0
  236. data/spec/metric_fu/metrics/cane/generator_spec.rb +184 -0
  237. data/spec/metric_fu/metrics/churn/configuration_spec.rb +13 -0
  238. data/spec/metric_fu/metrics/churn/generator_spec.rb +64 -0
  239. data/spec/metric_fu/metrics/flay/configuration_spec.rb +13 -0
  240. data/spec/metric_fu/metrics/flay/generator_spec.rb +105 -0
  241. data/spec/metric_fu/metrics/flay/grapher_spec.rb +57 -0
  242. data/spec/metric_fu/metrics/flog/configuration_spec.rb +18 -0
  243. data/spec/metric_fu/metrics/flog/generator_spec.rb +77 -0
  244. data/spec/metric_fu/metrics/flog/grapher_spec.rb +107 -0
  245. data/spec/metric_fu/metrics/hotspots/analysis/analyzed_problems_spec.rb +104 -0
  246. data/spec/metric_fu/metrics/hotspots/analysis/analyzer_tables_spec.rb +71 -0
  247. data/spec/metric_fu/metrics/hotspots/analysis/ranking_spec.rb +30 -0
  248. data/spec/metric_fu/metrics/hotspots/analysis/rankings_spec.rb +97 -0
  249. data/spec/metric_fu/metrics/hotspots/analysis/table_spec.rb +6 -0
  250. data/spec/metric_fu/metrics/hotspots/generator_spec.rb +46 -0
  251. data/spec/metric_fu/metrics/hotspots/hotspot_analyzer_spec.rb +10 -0
  252. data/spec/metric_fu/metrics/hotspots/hotspot_spec.rb +16 -0
  253. data/spec/metric_fu/metrics/rails_best_practices/configuration_spec.rb +55 -0
  254. data/spec/metric_fu/metrics/rails_best_practices/generator_spec.rb +33 -0
  255. data/spec/metric_fu/metrics/rails_best_practices/grapher_spec.rb +62 -0
  256. data/spec/metric_fu/metrics/rcov/configuration_spec.rb +28 -0
  257. data/spec/metric_fu/metrics/rcov/generator_spec.rb +22 -0
  258. data/spec/metric_fu/metrics/rcov/grapher_spec.rb +57 -0
  259. data/spec/metric_fu/metrics/rcov/hotspot_spec.rb +20 -0
  260. data/spec/metric_fu/metrics/rcov/rcov_line_spec.rb +89 -0
  261. data/spec/metric_fu/metrics/rcov/simplecov_formatter_spec.rb +67 -0
  262. data/spec/metric_fu/metrics/reek/configuration_spec.rb +13 -0
  263. data/spec/metric_fu/metrics/reek/generator_spec.rb +169 -0
  264. data/spec/metric_fu/metrics/reek/grapher_spec.rb +66 -0
  265. data/spec/metric_fu/metrics/roodi/configuration_spec.rb +14 -0
  266. data/spec/metric_fu/metrics/roodi/generator_spec.rb +82 -0
  267. data/spec/metric_fu/metrics/roodi/grapher_spec.rb +57 -0
  268. data/spec/metric_fu/metrics/saikuro/configuration_spec.rb +25 -0
  269. data/spec/metric_fu/metrics/saikuro/generator_spec.rb +71 -0
  270. data/spec/metric_fu/metrics/stats/generator_spec.rb +96 -0
  271. data/spec/metric_fu/metrics/stats/grapher_spec.rb +69 -0
  272. data/spec/metric_fu/reporter_spec.rb +41 -0
  273. data/spec/metric_fu/reporting/graphs/graph_spec.rb +44 -0
  274. data/spec/metric_fu/reporting/graphs/grapher_spec.rb +24 -0
  275. data/spec/metric_fu/reporting/result_spec.rb +50 -0
  276. data/spec/metric_fu/run_spec.rb +197 -0
  277. data/spec/metric_fu/templates/configuration_spec.rb +51 -0
  278. data/spec/metric_fu/templates/metrics_template_spec.rb +11 -0
  279. data/spec/metric_fu/templates/report_spec.rb +15 -0
  280. data/spec/metric_fu/templates/template_spec.rb +233 -0
  281. data/spec/metric_fu/utility_spec.rb +12 -0
  282. data/spec/metric_fu_spec.rb +33 -0
  283. data/spec/quality_spec.rb +114 -0
  284. data/spec/shared/configured.rb +45 -0
  285. data/spec/shared/test_coverage.rb +95 -0
  286. data/spec/spec_helper.rb +54 -0
  287. data/spec/support/deferred_garbaged_collection.rb +33 -0
  288. data/spec/support/helper_methods.rb +32 -0
  289. data/spec/support/matcher_create_file.rb +37 -0
  290. data/spec/support/matcher_create_files.rb +43 -0
  291. data/spec/support/suite.rb +26 -0
  292. data/spec/support/test_fixtures.rb +37 -0
  293. data/spec/support/timeout.rb +7 -0
  294. data/spec/support/usage_test.rb +150 -0
  295. data/spec/usage_test_spec.rb +93 -0
  296. metadata +757 -0
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe MetricFu do
5
+ specify "the default report_name is the run directory base name" do
6
+ expect(MetricFu.report_name).to eq("dummy")
7
+ end
8
+
9
+ specify "the user can set the report_name" do
10
+ original_report_name = MetricFu.report_name
11
+
12
+ MetricFu.report_name = "override"
13
+ expect(MetricFu.report_name).to eq("override")
14
+
15
+ MetricFu.report_name = original_report_name
16
+ end
17
+
18
+ it "has a global report time (corresponding to the time of the VCS code state)" do
19
+ expect(MetricFu.report_time - Time.now).to be_within(0.1).of(0)
20
+ end
21
+
22
+ it "has a global current time (corresponding to report generation time)" do
23
+ expect(MetricFu.current_time - Time.now).to be_within(0.1).of(0)
24
+ end
25
+
26
+ it "has a global report id" do
27
+ expect(MetricFu.report_id).to eq(Time.now.strftime("%Y%m%d"))
28
+ end
29
+
30
+ it "has a global report fingerprint (corresponding to VCS code state)" do
31
+ expect(MetricFu.report_fingerprint.to_i - Time.now.to_i).to be_within(0.1).of(0)
32
+ end
33
+ end
@@ -0,0 +1,114 @@
1
+ # coding: utf-8
2
+ # from https://github.com/vcr/vcr/blob/master/spec/quality_spec.rb
3
+ # from https://raw.githubusercontent.com/bundler/bundler/master/spec/quality_spec.rb
4
+ require "spec_helper"
5
+
6
+ if defined?(Encoding) && Encoding.default_external != "UTF-8"
7
+ Encoding.default_external = "UTF-8"
8
+ end
9
+
10
+ RSpec.describe "The library itself" do
11
+ # For some reason RSpec may expect this to be defined
12
+ # and crash really bad without it
13
+ def self.uses_transaction?(*)
14
+ false
15
+ end
16
+
17
+ def encode_utf8!(string)
18
+ string.encode!(Encoding::UTF_8,
19
+ invalid: :replace,
20
+ undef: :replace,
21
+ replace: "<?>".freeze
22
+ )
23
+ end
24
+
25
+ def ignore_whitespace?(filename)
26
+ @whitespace_regex ||=
27
+ /\.gitmodules|fixtures|vendor|LICENSE|etc|db|public|reports/
28
+ !!(filename =~ @whitespace_regex)
29
+ end
30
+
31
+ def check_for_spec_defs_with_single_quotes(filename)
32
+ failing_lines = []
33
+
34
+ File.readlines(filename).each_with_index do |line, number|
35
+ encode_utf8!(line)
36
+ failing_lines << number + 1 if line =~ /^ *(describe|it|context) {1}'{1}/
37
+ end
38
+
39
+ if failing_lines.any?
40
+ # Prevent rubocop from looping infinitely
41
+ # rubocop:disable Style/StringLiterals
42
+ "#{filename} uses inconsistent single quotes "\
43
+ "on lines #{failing_lines.join(', ')}"
44
+ # rubocop:enable Style/StringLiterals
45
+ end
46
+ end
47
+
48
+ def check_for_tab_characters(filename)
49
+ failing_lines = []
50
+ File.readlines(filename).each_with_index do |line, number|
51
+ encode_utf8!(line)
52
+ failing_lines << number + 1 if line =~ /\t/
53
+ end
54
+
55
+ unless failing_lines.empty?
56
+ # Prevent rubocop from looping infinitely
57
+ # rubocop:disable Style/StringLiterals
58
+ "#{filename} has tab characters on lines #{failing_lines.join(', ')}"
59
+ # rubocop:enable Style/StringLiterals
60
+ end
61
+ end
62
+
63
+ def check_for_extra_spaces(filename)
64
+ failing_lines = []
65
+ File.readlines(filename).each_with_index do |line, number|
66
+ encode_utf8!(line)
67
+ next if line =~ /^\s+#.*\s+\n$/
68
+ failing_lines << number + 1 if line =~ /\s+\n$/
69
+ end
70
+
71
+ unless failing_lines.empty?
72
+ # Prevent rubocop from looping infinitely
73
+ # rubocop:disable Style/StringLiterals
74
+ "#{filename} has spaces on the EOL on lines #{failing_lines.join(', ')}"
75
+ # rubocop:enable Style/StringLiterals
76
+ end
77
+ end
78
+
79
+ RSpec::Matchers.define :be_well_formed do
80
+ failure_message do |actual|
81
+ actual.join("\n")
82
+ end
83
+
84
+ match(&:empty?)
85
+ end
86
+
87
+ it "has no malformed whitespace" do
88
+ error_messages = []
89
+ Dir.chdir(File.expand_path("../..", __FILE__)) do
90
+ `git ls-files -z`.split("\x0").each do |filename|
91
+ next if !File.exist?(filename)
92
+ next if ignore_whitespace?(filename)
93
+ error_messages << check_for_tab_characters(filename)
94
+ error_messages << check_for_extra_spaces(filename)
95
+ end
96
+ end
97
+ expect(error_messages.compact).to be_well_formed
98
+ end
99
+
100
+ it "uses double-quotes consistently in specs" do
101
+ included = /spec/
102
+ error_messages = []
103
+ Dir.chdir(File.expand_path("../", __FILE__)) do
104
+ `git ls-files -z spec`.split("\x0").each do |filename|
105
+ next unless filename =~ included
106
+ error_messages << check_for_spec_defs_with_single_quotes(filename)
107
+ end
108
+ end
109
+ error_messages.compact.each do |error_message|
110
+ warn error_message
111
+ end
112
+ expect(error_messages.compact).to be_well_formed
113
+ end
114
+ end
@@ -0,0 +1,45 @@
1
+ shared_examples "configured" do
2
+ def get_new_config
3
+ ENV["CC_BUILD_ARTIFACTS"] = nil
4
+ @config = MetricFu.configuration
5
+ @config.reset
6
+ MetricFu.configuration.configure_metric(:rcov) do |rcov|
7
+ rcov.enabled = true
8
+ end
9
+ MetricFu.configure
10
+ allow(MetricFu::Io::FileSystem).to receive(:create_directories) # no need to create directories for the tests
11
+ @config
12
+ end
13
+
14
+ def directory(name)
15
+ MetricFu::Io::FileSystem.directory(name)
16
+ end
17
+
18
+ def base_directory
19
+ directory("base_directory")
20
+ end
21
+
22
+ def output_directory
23
+ directory("output_directory")
24
+ end
25
+
26
+ def scratch_directory
27
+ directory("scratch_directory")
28
+ end
29
+
30
+ def template_directory
31
+ directory("template_directory")
32
+ end
33
+
34
+ def template_class
35
+ MetricFu::Formatter::Templates.option("template_class")
36
+ end
37
+
38
+ def metric_fu_root
39
+ directory("root_directory")
40
+ end
41
+
42
+ def load_metric(metric)
43
+ load File.join(MetricFu.metrics_dir, metric, "metric.rb")
44
+ end
45
+ end
@@ -0,0 +1,95 @@
1
+ shared_examples "rcov test coverage generator" do |metric_name|
2
+ before do
3
+ setup_fs
4
+ MetricFu::Configuration.run do |config|
5
+ config.configure_metric(metric_name) do |rcov|
6
+ rcov.enabled = true
7
+ end
8
+ end
9
+ end
10
+
11
+ before :each do
12
+ @default_options = MetricFu::Metric.get_metric(metric_name).run_options
13
+ end
14
+
15
+ describe "emit" do
16
+ before :each do
17
+ options = { external: nil }
18
+ @rcov = MetricFu::RcovGenerator.new(@default_options.merge(options))
19
+ end
20
+
21
+ # TODO: should this be true of this metric?
22
+ it "should clear out previous output and make output folder" do
23
+ expect(MetricFu::Utility).to receive(:rm_rf).with(MetricFu::RcovGenerator.metric_directory, verbose: false)
24
+ expect(MetricFu::Utility).to receive(:mkdir_p).with(MetricFu::RcovGenerator.metric_directory)
25
+ @rcov.reset_output_location
26
+ end
27
+ end
28
+
29
+ def rcov_output
30
+ FIXTURE.load_file("rcov_output.txt")
31
+ end
32
+
33
+ describe "with rcov_output fed into" do
34
+ before :each do
35
+ options = { external: nil }
36
+ @rcov = MetricFu::RcovGenerator.new(@default_options.merge(options))
37
+ expect(@rcov).to receive(:load_output).and_return(rcov_output)
38
+ @files = @rcov.analyze
39
+ end
40
+
41
+ describe "analyze" do
42
+ it "should compute percent of lines run" do
43
+ expect(@files["./lib/metric_fu/metrics/hotspots/analysis/record.rb"][:percent_run]).to eq(94)
44
+ expect(@files["./lib/metric_fu/metrics/hotspots/analysis/table.rb"][:percent_run]).to eq(93)
45
+ end
46
+
47
+ it "should know which lines were run" do
48
+ expect(@files["./lib/metric_fu/metrics/hotspots/analysis/record.rb"][:lines].any? {|line|
49
+ line[:content].strip == "@data[key]" &&
50
+ line[:was_run] == 1
51
+ }).to be_truthy
52
+ end
53
+
54
+ it "should know which lines NOT were run" do
55
+ expect(@files["./lib/metric_fu/metrics/hotspots/analysis/record.rb"][:lines].any? {|line|
56
+ line[:content].strip == "super(name, *args, &block)" &&
57
+ line[:was_run] == 0
58
+ }).to be_truthy
59
+ end
60
+
61
+ it "should know which lines were ignored" do
62
+ expect(@files["./lib/metric_fu/metrics/hotspots/analysis/record.rb"][:lines].any? {|line|
63
+ line[:content].strip == "end" &&
64
+ line[:was_run] == nil
65
+ }).to be_truthy
66
+ end
67
+ end
68
+
69
+ describe "to_h" do
70
+ it "should calculate total percentage for all files" do
71
+ expect(@rcov.to_h[:rcov][:global_percent_run]).to eq(93.3)
72
+ end
73
+ end
74
+ end
75
+ describe "with external configuration option set" do
76
+ before :each do
77
+ options = { external: "coverage/rcov.txt" }
78
+ @rcov = MetricFu::RcovGenerator.new(@default_options.merge(options))
79
+ end
80
+
81
+ it "should emit nothing if external configuration option is set" do
82
+ expect(MetricFu::Utility).not_to receive(:rm_rf)
83
+ @rcov.emit
84
+ end
85
+
86
+ it "should open the external rcov analysis file" do
87
+ expect(@rcov).to receive(:load_output).and_return(rcov_output)
88
+ @files = @rcov.analyze
89
+ end
90
+ end
91
+
92
+ after do
93
+ cleanup_fs
94
+ end
95
+ end
@@ -0,0 +1,54 @@
1
+ # add lib to the load path just like rubygems does
2
+ $:.unshift File.expand_path("../../lib", __FILE__)
3
+ require "simplecov"
4
+
5
+ require "date"
6
+ require "test_construct"
7
+ require "json"
8
+ require "pry-nav"
9
+
10
+ require "metric_fu"
11
+ include MetricFu
12
+ def mf_log(msg); mf_debug(msg); end
13
+
14
+ # Requires supporting ruby files with custom matchers and macros, etc,
15
+ # in spec/support/ and its subdirectories.
16
+ Dir[MetricFu.root_dir + "/spec/support/**/*.rb"].each { |f| require f }
17
+
18
+ RSpec.configure do |config|
19
+ config.filter_run focus: true
20
+ config.run_all_when_everything_filtered = true
21
+ # Skip specs tagged `:slow` unless SLOW_SPECS is set
22
+ config.filter_run_excluding :slow unless ENV["SLOW_SPECS"]
23
+ # End specs on first failure if FAIL_FAST is set
24
+ config.fail_fast = ENV.include?("FAIL_FAST")
25
+ config.order = :rand
26
+ config.color = true
27
+ config.expect_with :rspec do |expectations|
28
+ expectations.syntax = :expect
29
+ end
30
+ config.mock_with :rspec do |mocks|
31
+ mocks.syntax = :expect
32
+ mocks.verify_partial_doubles = true
33
+ end
34
+
35
+ # :suite after/before all specs
36
+ # :each every describe block
37
+ # :all every it block
38
+
39
+ def run_dir
40
+ File.expand_path("dummy", File.dirname(__FILE__))
41
+ end
42
+
43
+ config.before(:suite) do
44
+ MetricFu.run_dir = run_dir
45
+ end
46
+
47
+ config.after(:suite) do
48
+ cleanup_fs
49
+ end
50
+
51
+ config.after(:each) do
52
+ MetricFu.reset
53
+ end
54
+ end
@@ -0,0 +1,33 @@
1
+ class DeferredGarbageCollection
2
+ DEFERRED_GC_THRESHOLD = (ENV["DEFER_GC"] || 15.0).to_f
3
+
4
+ @@last_gc_run = Time.now
5
+
6
+ def self.start
7
+ GC.disable if DEFERRED_GC_THRESHOLD > 0
8
+ end
9
+
10
+ def self.reconsider
11
+ if DEFERRED_GC_THRESHOLD > 0 && Time.now - @@last_gc_run >= DEFERRED_GC_THRESHOLD
12
+ GC.enable
13
+ GC.start
14
+ GC.disable
15
+ @@last_gc_run = Time.now
16
+ end
17
+ end
18
+
19
+ def self.configure(config)
20
+ return if defined?(JRUBY_VERSION)
21
+ config.before(:all) do
22
+ DeferredGarbageCollection.start
23
+ end
24
+
25
+ config.after(:all) do
26
+ DeferredGarbageCollection.reconsider
27
+ end
28
+ end
29
+ end
30
+
31
+ RSpec.configure do |config|
32
+ DeferredGarbageCollection.configure(config)
33
+ end
@@ -0,0 +1,32 @@
1
+ def enable_hotspots
2
+ MetricFu.configure
3
+ hotspot_metrics = MetricFu::Metric.metrics.map(&:name)
4
+ hotspot_metrics.each do |metric_name|
5
+ path = "#{metric_name}/hotspot"
6
+ begin
7
+ MetricFu.metrics_require { path }
8
+ rescue LoadError
9
+ # No hotspot, but that's ok
10
+ end
11
+ end
12
+ end
13
+
14
+ def metric_not_activated?(metric_name)
15
+ MetricFu.configuration.configure_metrics
16
+ metric = MetricFu::Metric.get_metric(metric_name.intern)
17
+ if (metric.activate rescue false) # may fail if ripper not supported
18
+ false
19
+ else
20
+ p "Skipping #{metric_name} tests, not activated"
21
+ true
22
+ end
23
+ end
24
+
25
+ def breaks_when?(bool)
26
+ p "Skipping tests in #{caller[0]}. They unnecessarily break the build." if bool
27
+ bool
28
+ end
29
+
30
+ def compare_paths(path1, path2)
31
+ expect(File.join(MetricFu.root_dir, path1)).to eq(File.join(MetricFu.root_dir, path2))
32
+ end
@@ -0,0 +1,37 @@
1
+ RSpec::Matchers.define :create_file do |expected|
2
+ match do |block|
3
+ @before = exists?(expected)
4
+ block.call
5
+ @after = exists?(expected)
6
+ !@before && @after
7
+ end
8
+
9
+ failure_message do |_block|
10
+ existed_before_message expected do
11
+ "The file #{expected.inspect} was not created"
12
+ end
13
+ end
14
+
15
+ failure_message_when_negated do |_block|
16
+ existed_before_message expected do
17
+ "The file #{expected.inspect} was created"
18
+ end
19
+ end
20
+
21
+ def supports_block_expectations?
22
+ true
23
+ end
24
+
25
+ def exists?(expected)
26
+ # Allows us to use wildcard checks for existence.
27
+ !Dir.glob(expected).empty?
28
+ end
29
+
30
+ def existed_before_message(expected)
31
+ if @before
32
+ "The file #{expected.inspect} existed before, so this test doesn't work"
33
+ else
34
+ yield
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,43 @@
1
+ RSpec::Matchers.define :create_files do |expected|
2
+ match do |block|
3
+ @before = false
4
+ @after = true
5
+ expected.each do |file|
6
+ @before |= exists?(file)
7
+ end
8
+ block.call
9
+ expected.each do |file|
10
+ @after &= exists?(file)
11
+ end
12
+ !@before && @after
13
+ end
14
+
15
+ failure_message do |_block|
16
+ existed_before_message expected do
17
+ "One or more files in [#{expected.inspect}] was not created."
18
+ end
19
+ end
20
+
21
+ failure_message_when_negated do |_block|
22
+ existed_before_message expected do
23
+ "The files in [#{expected.inspect}] were created."
24
+ end
25
+ end
26
+
27
+ def supports_block_expectations?
28
+ true
29
+ end
30
+
31
+ def exists?(expected)
32
+ # Allows us to use wildcard checks for existence.
33
+ !Dir.glob(expected).empty?
34
+ end
35
+
36
+ def existed_before_message(expected)
37
+ if @before
38
+ "One or more files in [#{expected.inspect}] existed before, so this test doesn't work"
39
+ else
40
+ yield
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,26 @@
1
+ require "fileutils"
2
+ def directory(name)
3
+ MetricFu::Io::FileSystem.directory(name)
4
+ end
5
+
6
+ def scratch_directory(name)
7
+ File.join(MetricFu::Io::FileSystem.artifact_dir, "scratch", name)
8
+ end
9
+
10
+ def artifact_test_dir
11
+ File.join(MetricFu::APP_ROOT, "tmp", "metric_fu", "test")
12
+ end
13
+
14
+ # Let's shift the output directories so that we don't interfere with
15
+ # existing historical metric data.
16
+ MetricFu::Io::FileSystem.artifact_dir = artifact_test_dir
17
+ MetricFu::Io::FileSystem.set_directories
18
+
19
+ def setup_fs
20
+ cleanup_fs
21
+ MetricFu::Io::FileSystem.set_directories
22
+ end
23
+
24
+ def cleanup_fs
25
+ FileUtils.rm_rf(artifact_test_dir)
26
+ end
@@ -0,0 +1,37 @@
1
+ require "pathname"
2
+ class TestFixtures
3
+ attr_reader :fixtures_path
4
+
5
+ def initialize
6
+ @loaded_data = {}
7
+ @fixtures_path = Pathname(MetricFu.root_dir).join("spec", "fixtures")
8
+ end
9
+
10
+ def load_metric(path)
11
+ retrieve_data(path) do |path|
12
+ YAML.load_file(fixture_path(path))
13
+ end
14
+ end
15
+
16
+ def load_file(path)
17
+ retrieve_data(path) do |path|
18
+ File.read(fixture_path(path))
19
+ end
20
+ end
21
+
22
+ def fixture_path(path)
23
+ fixtures_path.join(*Array(path))
24
+ end
25
+
26
+ private
27
+
28
+ def retrieve_data(path)
29
+ @loaded_data.fetch(path) do
30
+ @loaded_data[path] = yield(path)
31
+ end
32
+ end
33
+ end
34
+ FIXTURE = TestFixtures.new
35
+ HOTSPOT_DATA = ->(paths) {
36
+ FIXTURE.load_metric(["hotspots"].concat(Array(paths)))
37
+ }
@@ -0,0 +1,7 @@
1
+ require "timeout"
2
+ # No spec should run longer than this
3
+ # (define here to support the closure)
4
+ p "setting timeout #{timeout = 15.0} seconds"
5
+ RSpec.configuration.around(:each) do |example|
6
+ Timeout.timeout(timeout, &example)
7
+ end