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.
- checksums.yaml +7 -0
- data/.gitignore +28 -0
- data/.metrics +3 -0
- data/.rspec +2 -0
- data/.rubocop.yml +15 -0
- data/.rubocop_todo.yml +69 -0
- data/.simplecov +74 -0
- data/.travis.yml +22 -0
- data/.yardopts +4 -0
- data/AUTHORS +12 -0
- data/CONTRIBUTING.md +47 -0
- data/CONTRIBUTORS +76 -0
- data/DEV.md +76 -0
- data/Gemfile +74 -0
- data/Guardfile +30 -0
- data/HISTORY.md +705 -0
- data/MIT-LICENSE +22 -0
- data/README.md +299 -0
- data/Rakefile +27 -0
- data/TODO.md +118 -0
- data/appveyor.yml +31 -0
- data/bin/metric_fu +9 -0
- data/bin/mf-cane +10 -0
- data/bin/mf-churn +10 -0
- data/bin/mf-flay +10 -0
- data/bin/mf-reek +10 -0
- data/bin/mf-roodi +10 -0
- data/bin/mf-saikuro +10 -0
- data/certs/bf4.pem +22 -0
- data/checksum/.gitkeep +0 -0
- data/checksum/metric_fu-4.10.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.11.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.11.1.gem.sha512 +1 -0
- data/checksum/metric_fu-4.11.2.gem.sha512 +1 -0
- data/checksum/metric_fu-4.11.3.gem.sha512 +1 -0
- data/checksum/metric_fu-4.11.4.gem.sha512 +1 -0
- data/checksum/metric_fu-4.12.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.2.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.2.1.gem.sha512 +1 -0
- data/checksum/metric_fu-4.3.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.3.1.gem.sha512 +1 -0
- data/checksum/metric_fu-4.4.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.4.1.gem.sha512 +1 -0
- data/checksum/metric_fu-4.4.2.gem.sha512 +1 -0
- data/checksum/metric_fu-4.4.3.gem.sha512 +1 -0
- data/checksum/metric_fu-4.4.4.gem.sha512 +1 -0
- data/checksum/metric_fu-4.5.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.5.1.gem.sha512 +1 -0
- data/checksum/metric_fu-4.5.2.gem.sha512 +1 -0
- data/checksum/metric_fu-4.6.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.7.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.7.1.gem.sha512 +1 -0
- data/checksum/metric_fu-4.7.2.gem.sha512 +1 -0
- data/checksum/metric_fu-4.7.3.gem.sha512 +1 -0
- data/checksum/metric_fu-4.7.4.gem.sha512 +1 -0
- data/checksum/metric_fu-4.8.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.9.0.gem.sha512 +1 -0
- data/config/roodi_config.yml +22 -0
- data/config/rubocop.yml +269 -0
- data/gem_tasks/build.rake +197 -0
- data/gem_tasks/rubocop.rake +10 -0
- data/gem_tasks/usage_test.rake +19 -0
- data/gem_tasks/yard.rake +24 -0
- data/lib/metric_fu/calculate.rb +10 -0
- data/lib/metric_fu/cli/client.rb +26 -0
- data/lib/metric_fu/cli/helper.rb +80 -0
- data/lib/metric_fu/cli/parser.rb +138 -0
- data/lib/metric_fu/configuration.rb +150 -0
- data/lib/metric_fu/constantize.rb +57 -0
- data/lib/metric_fu/data_structures/line_numbers.rb +112 -0
- data/lib/metric_fu/data_structures/location.rb +110 -0
- data/lib/metric_fu/data_structures/sexp_node.rb +107 -0
- data/lib/metric_fu/environment.rb +129 -0
- data/lib/metric_fu/errors/analysis_error.rb +4 -0
- data/lib/metric_fu/formatter/html.rb +96 -0
- data/lib/metric_fu/formatter/syntax.rb +45 -0
- data/lib/metric_fu/formatter/yaml.rb +18 -0
- data/lib/metric_fu/formatter.rb +40 -0
- data/lib/metric_fu/gem_run.rb +70 -0
- data/lib/metric_fu/gem_version.rb +92 -0
- data/lib/metric_fu/generator.rb +135 -0
- data/lib/metric_fu/io.rb +132 -0
- data/lib/metric_fu/loader.rb +105 -0
- data/lib/metric_fu/logger.rb +62 -0
- data/lib/metric_fu/logging/mf_debugger.rb +23 -0
- data/lib/metric_fu/metric.rb +143 -0
- data/lib/metric_fu/metrics/cane/generator.rb +95 -0
- data/lib/metric_fu/metrics/cane/grapher.rb +37 -0
- data/lib/metric_fu/metrics/cane/metric.rb +34 -0
- data/lib/metric_fu/metrics/cane/report.html.erb +87 -0
- data/lib/metric_fu/metrics/cane/violations.rb +46 -0
- data/lib/metric_fu/metrics/churn/generator.rb +37 -0
- data/lib/metric_fu/metrics/churn/hotspot.rb +43 -0
- data/lib/metric_fu/metrics/churn/metric.rb +29 -0
- data/lib/metric_fu/metrics/churn/report.html.erb +58 -0
- data/lib/metric_fu/metrics/flay/generator.rb +51 -0
- data/lib/metric_fu/metrics/flay/grapher.rb +37 -0
- data/lib/metric_fu/metrics/flay/hotspot.rb +52 -0
- data/lib/metric_fu/metrics/flay/metric.rb +28 -0
- data/lib/metric_fu/metrics/flay/report.html.erb +29 -0
- data/lib/metric_fu/metrics/flog/generator.rb +113 -0
- data/lib/metric_fu/metrics/flog/grapher.rb +77 -0
- data/lib/metric_fu/metrics/flog/hotspot.rb +46 -0
- data/lib/metric_fu/metrics/flog/metric.rb +29 -0
- data/lib/metric_fu/metrics/flog/report.html.erb +50 -0
- data/lib/metric_fu/metrics/hotspots/analysis/analyzed_problems.rb +34 -0
- data/lib/metric_fu/metrics/hotspots/analysis/analyzer_tables.rb +114 -0
- data/lib/metric_fu/metrics/hotspots/analysis/grouping.rb +23 -0
- data/lib/metric_fu/metrics/hotspots/analysis/groupings.rb +12 -0
- data/lib/metric_fu/metrics/hotspots/analysis/problems.rb +20 -0
- data/lib/metric_fu/metrics/hotspots/analysis/ranked_problem_location.rb +70 -0
- data/lib/metric_fu/metrics/hotspots/analysis/ranking.rb +29 -0
- data/lib/metric_fu/metrics/hotspots/analysis/rankings.rb +91 -0
- data/lib/metric_fu/metrics/hotspots/analysis/record.rb +32 -0
- data/lib/metric_fu/metrics/hotspots/analysis/scoring_strategies.rb +24 -0
- data/lib/metric_fu/metrics/hotspots/analysis/table.rb +67 -0
- data/lib/metric_fu/metrics/hotspots/generator.rb +40 -0
- data/lib/metric_fu/metrics/hotspots/hotspot.rb +87 -0
- data/lib/metric_fu/metrics/hotspots/hotspot_analyzer.rb +61 -0
- data/lib/metric_fu/metrics/hotspots/metric.rb +20 -0
- data/lib/metric_fu/metrics/hotspots/report.html.erb +60 -0
- data/lib/metric_fu/metrics/rails_best_practices/generator.rb +47 -0
- data/lib/metric_fu/metrics/rails_best_practices/grapher.rb +38 -0
- data/lib/metric_fu/metrics/rails_best_practices/metric.rb +31 -0
- data/lib/metric_fu/metrics/rails_best_practices/report.html.erb +22 -0
- data/lib/metric_fu/metrics/rcov/external_client.rb +22 -0
- data/lib/metric_fu/metrics/rcov/generator.rb +75 -0
- data/lib/metric_fu/metrics/rcov/grapher.rb +37 -0
- data/lib/metric_fu/metrics/rcov/hotspot.rb +46 -0
- data/lib/metric_fu/metrics/rcov/metric.rb +61 -0
- data/lib/metric_fu/metrics/rcov/rcov_format_coverage.rb +149 -0
- data/lib/metric_fu/metrics/rcov/rcov_line.rb +48 -0
- data/lib/metric_fu/metrics/rcov/report.html.erb +40 -0
- data/lib/metric_fu/metrics/rcov/simplecov_formatter.rb +74 -0
- data/lib/metric_fu/metrics/reek/generator.rb +97 -0
- data/lib/metric_fu/metrics/reek/grapher.rb +55 -0
- data/lib/metric_fu/metrics/reek/hotspot.rb +95 -0
- data/lib/metric_fu/metrics/reek/metric.rb +26 -0
- data/lib/metric_fu/metrics/reek/report.html.erb +35 -0
- data/lib/metric_fu/metrics/roodi/generator.rb +41 -0
- data/lib/metric_fu/metrics/roodi/grapher.rb +37 -0
- data/lib/metric_fu/metrics/roodi/hotspot.rb +39 -0
- data/lib/metric_fu/metrics/roodi/metric.rb +24 -0
- data/lib/metric_fu/metrics/roodi/report.html.erb +22 -0
- data/lib/metric_fu/metrics/saikuro/generator.rb +145 -0
- data/lib/metric_fu/metrics/saikuro/hotspot.rb +51 -0
- data/lib/metric_fu/metrics/saikuro/metric.rb +31 -0
- data/lib/metric_fu/metrics/saikuro/parsing_element.rb +37 -0
- data/lib/metric_fu/metrics/saikuro/report.html.erb +71 -0
- data/lib/metric_fu/metrics/saikuro/scratch_file.rb +108 -0
- data/lib/metric_fu/metrics/stats/generator.rb +82 -0
- data/lib/metric_fu/metrics/stats/grapher.rb +40 -0
- data/lib/metric_fu/metrics/stats/hotspot.rb +35 -0
- data/lib/metric_fu/metrics/stats/metric.rb +28 -0
- data/lib/metric_fu/metrics/stats/report.html.erb +44 -0
- data/lib/metric_fu/reporter.rb +37 -0
- data/lib/metric_fu/reporting/graphs/graph.rb +69 -0
- data/lib/metric_fu/reporting/graphs/grapher.rb +66 -0
- data/lib/metric_fu/reporting/result.rb +59 -0
- data/lib/metric_fu/run.rb +82 -0
- data/lib/metric_fu/tasks/metric_fu.rake +54 -0
- data/lib/metric_fu/templates/_gem_info.html.erb +8 -0
- data/lib/metric_fu/templates/_graph.html.erb +2 -0
- data/lib/metric_fu/templates/_report_footer.html.erb +1 -0
- data/lib/metric_fu/templates/configuration.rb +25 -0
- data/lib/metric_fu/templates/css/bluff.css +15 -0
- data/lib/metric_fu/templates/css/buttons.css +82 -0
- data/lib/metric_fu/templates/css/default.css +43 -0
- data/lib/metric_fu/templates/css/integrity.css +337 -0
- data/lib/metric_fu/templates/css/rcov.css +32 -0
- data/lib/metric_fu/templates/css/reset.css +7 -0
- data/lib/metric_fu/templates/css/syntax.css +19 -0
- data/lib/metric_fu/templates/index.html.erb +13 -0
- data/lib/metric_fu/templates/javascripts/bluff-min.js +1 -0
- data/lib/metric_fu/templates/javascripts/bluff_graph.js +15 -0
- data/lib/metric_fu/templates/javascripts/excanvas.js +35 -0
- data/lib/metric_fu/templates/javascripts/highcharts.js +294 -0
- data/lib/metric_fu/templates/javascripts/highcharts_graph.js +38 -0
- data/lib/metric_fu/templates/javascripts/js-class.js +1 -0
- data/lib/metric_fu/templates/javascripts/standalone-framework.js +17 -0
- data/lib/metric_fu/templates/javascripts/utils.js +9 -0
- data/lib/metric_fu/templates/layout.html.erb +41 -0
- data/lib/metric_fu/templates/metrics_template.rb +86 -0
- data/lib/metric_fu/templates/report.html.erb +31 -0
- data/lib/metric_fu/templates/report.rb +41 -0
- data/lib/metric_fu/templates/template.rb +247 -0
- data/lib/metric_fu/utility.rb +79 -0
- data/lib/metric_fu/version.rb +9 -0
- data/lib/metric_fu.rb +143 -0
- data/metric_fu.gemspec +72 -0
- data/spec/capture_warnings.rb +55 -0
- data/spec/cli/helper_spec.rb +165 -0
- data/spec/dummy/.gitignore +1 -0
- data/spec/dummy/.gitkeep +0 -0
- data/spec/dummy/.metrics +4 -0
- data/spec/dummy/lib/.gitkeep +0 -0
- data/spec/dummy/lib/bad_encoding.rb +6 -0
- data/spec/dummy/spec/.gitkeep +0 -0
- data/spec/fixtures/20090630.yml +7922 -0
- data/spec/fixtures/coverage-153.rb +11 -0
- data/spec/fixtures/coverage.rb +13 -0
- data/spec/fixtures/exit0.sh +3 -0
- data/spec/fixtures/exit1.sh +3 -0
- data/spec/fixtures/hotspots/flog.yml +86 -0
- data/spec/fixtures/hotspots/generator.yml +47 -0
- data/spec/fixtures/hotspots/generator_analysis.yml +53 -0
- data/spec/fixtures/hotspots/reek.yml +14 -0
- data/spec/fixtures/hotspots/roodi.yml +13 -0
- data/spec/fixtures/hotspots/saikuro.yml +27 -0
- data/spec/fixtures/hotspots/several_metrics.yml +47 -0
- data/spec/fixtures/hotspots/stats.yml +4 -0
- data/spec/fixtures/hotspots/three_metrics_on_same_file.yml +36 -0
- data/spec/fixtures/line_numbers/foo.rb +33 -0
- data/spec/fixtures/line_numbers/module.rb +11 -0
- data/spec/fixtures/line_numbers/module_surrounds_class.rb +15 -0
- data/spec/fixtures/line_numbers/two_classes.rb +11 -0
- data/spec/fixtures/metric_missing.yml +1 -0
- data/spec/fixtures/rcov_output.txt +135 -0
- data/spec/fixtures/saikuro/app/controllers/sessions_controller.rb_cyclo.html +10 -0
- data/spec/fixtures/saikuro/app/controllers/users_controller.rb_cyclo.html +16 -0
- data/spec/fixtures/saikuro/index_cyclo.html +155 -0
- data/spec/fixtures/saikuro_sfiles/thing.rb_cyclo.html +11 -0
- data/spec/metric_fu/calculate_spec.rb +21 -0
- data/spec/metric_fu/configuration_spec.rb +90 -0
- data/spec/metric_fu/data_structures/line_numbers_spec.rb +63 -0
- data/spec/metric_fu/data_structures/location_spec.rb +110 -0
- data/spec/metric_fu/formatter/configuration_spec.rb +44 -0
- data/spec/metric_fu/formatter/html_spec.rb +138 -0
- data/spec/metric_fu/formatter/yaml_spec.rb +61 -0
- data/spec/metric_fu/formatter_spec.rb +49 -0
- data/spec/metric_fu/gem_version_spec.rb +12 -0
- data/spec/metric_fu/generator_spec.rb +130 -0
- data/spec/metric_fu/loader_spec.rb +10 -0
- data/spec/metric_fu/metric_spec.rb +46 -0
- data/spec/metric_fu/metrics/cane/configuration_spec.rb +22 -0
- data/spec/metric_fu/metrics/cane/generator_spec.rb +184 -0
- data/spec/metric_fu/metrics/churn/configuration_spec.rb +13 -0
- data/spec/metric_fu/metrics/churn/generator_spec.rb +64 -0
- data/spec/metric_fu/metrics/flay/configuration_spec.rb +13 -0
- data/spec/metric_fu/metrics/flay/generator_spec.rb +105 -0
- data/spec/metric_fu/metrics/flay/grapher_spec.rb +57 -0
- data/spec/metric_fu/metrics/flog/configuration_spec.rb +18 -0
- data/spec/metric_fu/metrics/flog/generator_spec.rb +77 -0
- data/spec/metric_fu/metrics/flog/grapher_spec.rb +107 -0
- data/spec/metric_fu/metrics/hotspots/analysis/analyzed_problems_spec.rb +104 -0
- data/spec/metric_fu/metrics/hotspots/analysis/analyzer_tables_spec.rb +71 -0
- data/spec/metric_fu/metrics/hotspots/analysis/ranking_spec.rb +30 -0
- data/spec/metric_fu/metrics/hotspots/analysis/rankings_spec.rb +97 -0
- data/spec/metric_fu/metrics/hotspots/analysis/table_spec.rb +6 -0
- data/spec/metric_fu/metrics/hotspots/generator_spec.rb +46 -0
- data/spec/metric_fu/metrics/hotspots/hotspot_analyzer_spec.rb +10 -0
- data/spec/metric_fu/metrics/hotspots/hotspot_spec.rb +16 -0
- data/spec/metric_fu/metrics/rails_best_practices/configuration_spec.rb +55 -0
- data/spec/metric_fu/metrics/rails_best_practices/generator_spec.rb +33 -0
- data/spec/metric_fu/metrics/rails_best_practices/grapher_spec.rb +62 -0
- data/spec/metric_fu/metrics/rcov/configuration_spec.rb +28 -0
- data/spec/metric_fu/metrics/rcov/generator_spec.rb +22 -0
- data/spec/metric_fu/metrics/rcov/grapher_spec.rb +57 -0
- data/spec/metric_fu/metrics/rcov/hotspot_spec.rb +20 -0
- data/spec/metric_fu/metrics/rcov/rcov_line_spec.rb +89 -0
- data/spec/metric_fu/metrics/rcov/simplecov_formatter_spec.rb +67 -0
- data/spec/metric_fu/metrics/reek/configuration_spec.rb +13 -0
- data/spec/metric_fu/metrics/reek/generator_spec.rb +169 -0
- data/spec/metric_fu/metrics/reek/grapher_spec.rb +66 -0
- data/spec/metric_fu/metrics/roodi/configuration_spec.rb +14 -0
- data/spec/metric_fu/metrics/roodi/generator_spec.rb +82 -0
- data/spec/metric_fu/metrics/roodi/grapher_spec.rb +57 -0
- data/spec/metric_fu/metrics/saikuro/configuration_spec.rb +25 -0
- data/spec/metric_fu/metrics/saikuro/generator_spec.rb +71 -0
- data/spec/metric_fu/metrics/stats/generator_spec.rb +96 -0
- data/spec/metric_fu/metrics/stats/grapher_spec.rb +69 -0
- data/spec/metric_fu/reporter_spec.rb +41 -0
- data/spec/metric_fu/reporting/graphs/graph_spec.rb +44 -0
- data/spec/metric_fu/reporting/graphs/grapher_spec.rb +24 -0
- data/spec/metric_fu/reporting/result_spec.rb +50 -0
- data/spec/metric_fu/run_spec.rb +197 -0
- data/spec/metric_fu/templates/configuration_spec.rb +51 -0
- data/spec/metric_fu/templates/metrics_template_spec.rb +11 -0
- data/spec/metric_fu/templates/report_spec.rb +15 -0
- data/spec/metric_fu/templates/template_spec.rb +233 -0
- data/spec/metric_fu/utility_spec.rb +12 -0
- data/spec/metric_fu_spec.rb +33 -0
- data/spec/quality_spec.rb +114 -0
- data/spec/shared/configured.rb +45 -0
- data/spec/shared/test_coverage.rb +95 -0
- data/spec/spec_helper.rb +54 -0
- data/spec/support/deferred_garbaged_collection.rb +33 -0
- data/spec/support/helper_methods.rb +32 -0
- data/spec/support/matcher_create_file.rb +37 -0
- data/spec/support/matcher_create_files.rb +43 -0
- data/spec/support/suite.rb +26 -0
- data/spec/support/test_fixtures.rb +37 -0
- data/spec/support/timeout.rb +7 -0
- data/spec/support/usage_test.rb +150 -0
- data/spec/usage_test_spec.rb +93 -0
- metadata +757 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module MetricFu
|
|
2
|
+
class MetricStats < Metric
|
|
3
|
+
def name
|
|
4
|
+
:stats
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def default_run_options
|
|
8
|
+
{
|
|
9
|
+
# returns a list of directories that contains the glob of files that have the file_pattern in the file names
|
|
10
|
+
additional_test_directories: [{ glob_pattern: File.join(".", "spec", "**", "*_spec.rb"), file_pattern: "spec" }],
|
|
11
|
+
additional_app_directories: [{ glob_pattern: File.join(".", "engines", "**", "*.rb"), file_pattern: "" }],
|
|
12
|
+
}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def has_graph?
|
|
16
|
+
true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def enable
|
|
20
|
+
super
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def activate
|
|
24
|
+
activate_library "code_metrics"
|
|
25
|
+
super
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<h3>Lines of Code/Tests Metric Results</h3>
|
|
2
|
+
|
|
3
|
+
<%= render_partial 'graph', {:graph_name => 'stats'} %>
|
|
4
|
+
|
|
5
|
+
<p>Lines of Code/Tests Metrics Results</p>
|
|
6
|
+
<table>
|
|
7
|
+
<tr>
|
|
8
|
+
<th>Lines of Code</th>
|
|
9
|
+
<th>Lines of Test</th>
|
|
10
|
+
<th>Code to test ratio</th>
|
|
11
|
+
</tr>
|
|
12
|
+
<tr>
|
|
13
|
+
<td><%= @stats[:codeLOC] %></td>
|
|
14
|
+
<td><%= @stats[:testLOC] %></td>
|
|
15
|
+
<td>1:<%= @stats[:code_to_test_ratio] %></td>
|
|
16
|
+
</tr>
|
|
17
|
+
</table>
|
|
18
|
+
|
|
19
|
+
<table>
|
|
20
|
+
<tr>
|
|
21
|
+
<th>Name</th>
|
|
22
|
+
<th>Lines</th>
|
|
23
|
+
<th>LOC</th>
|
|
24
|
+
<th>Classes</th>
|
|
25
|
+
<th>Methods</th>
|
|
26
|
+
<th>Methods per class</th>
|
|
27
|
+
<th>LOC per method</th>
|
|
28
|
+
</tr>
|
|
29
|
+
<% count = 0 %>
|
|
30
|
+
<% @stats[:lines].each do |line| %>
|
|
31
|
+
<tr>
|
|
32
|
+
<td><%= line[:name] %></td>
|
|
33
|
+
<td><%= line[:lines] %></td>
|
|
34
|
+
<td><%= line[:loc] %></td>
|
|
35
|
+
<td><%= line[:classes] %></td>
|
|
36
|
+
<td><%= line[:methods] %></td>
|
|
37
|
+
<td><%= line[:methods_per_class] %></td>
|
|
38
|
+
<td><%= line[:loc_per_method] %></td>
|
|
39
|
+
</tr>
|
|
40
|
+
<% count += 1 %>
|
|
41
|
+
<% end %>
|
|
42
|
+
</table>
|
|
43
|
+
|
|
44
|
+
<%= render_partial 'report_footer' %>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module MetricFu
|
|
2
|
+
class Reporter
|
|
3
|
+
def initialize(formatters = nil)
|
|
4
|
+
@formatters = Array(formatters)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def start
|
|
8
|
+
notify :start
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def finish
|
|
12
|
+
notify :finish
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def start_metric(metric)
|
|
16
|
+
mf_log "** STARTING METRIC #{metric}"
|
|
17
|
+
notify :start_metric, metric
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def finish_metric(metric)
|
|
21
|
+
mf_log "** ENDING METRIC #{metric}"
|
|
22
|
+
notify :finish_metric, metric
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def display_results
|
|
26
|
+
notify :display_results
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
protected
|
|
30
|
+
|
|
31
|
+
def notify(event, *args)
|
|
32
|
+
@formatters.each do |formatter|
|
|
33
|
+
formatter.send(event, *args) if formatter.respond_to?(event)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module MetricFu
|
|
2
|
+
def self.graph
|
|
3
|
+
@graph ||= Graph.new
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
class Graph
|
|
7
|
+
attr_accessor :graphers
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
self.graphers = []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def add(metric_name, _graph_engine, output_directory = MetricFu::Io::FileSystem.directory("output_directory"))
|
|
14
|
+
grapher = MetricFu::Grapher.get_grapher(metric_name).
|
|
15
|
+
new.tap { |g| g.output_directory = output_directory }
|
|
16
|
+
graphers.push grapher
|
|
17
|
+
rescue NameError => e
|
|
18
|
+
mf_log "#{e.message} called in MetricFu::Graph.add with #{graph_type}"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def generate
|
|
22
|
+
return if graphers.empty?
|
|
23
|
+
mf_log "Generating graphs"
|
|
24
|
+
generate_graphs_for_files
|
|
25
|
+
graph!
|
|
26
|
+
rescue NameError => e
|
|
27
|
+
mf_log "#{e.message} called in MetricFu::Graph generate"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def metric_files
|
|
33
|
+
MetricFu::Utility.glob(
|
|
34
|
+
File.join(MetricFu::Io::FileSystem.directory("data_directory"), "*.yml")
|
|
35
|
+
).sort
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def generate_graphs_for_files
|
|
39
|
+
metric_files.each do |metric_file|
|
|
40
|
+
generate_graphs_for_file(metric_file)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def generate_graphs_for_file(metric_file)
|
|
45
|
+
mf_log "Generating graphs for #{metric_file}"
|
|
46
|
+
date_parts = year_month_day_from_filename(metric_file)
|
|
47
|
+
metrics = MetricFu::Utility.load_yaml(metric_file)
|
|
48
|
+
|
|
49
|
+
build_graph(metrics, "#{date_parts[:m]}/#{date_parts[:d]}")
|
|
50
|
+
rescue NameError => e
|
|
51
|
+
mf_log "#{e.message} called in MetricFu::Graph.generate with #{metric_file}"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def build_graph(metrics, sortable_prefix)
|
|
55
|
+
graphers.each do |grapher|
|
|
56
|
+
grapher.get_metrics(metrics, sortable_prefix)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def graph!
|
|
61
|
+
graphers.each(&:graph!)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def year_month_day_from_filename(path_to_file_with_date)
|
|
65
|
+
date = path_to_file_with_date.match(/\/(\d+).yml$/)[1]
|
|
66
|
+
{ y: date[0..3].to_i, m: date[4..5].to_i, d: date[6..7].to_i }
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require "multi_json"
|
|
2
|
+
module MetricFu
|
|
3
|
+
class Grapher
|
|
4
|
+
@graphers = []
|
|
5
|
+
# @return all subclassed graphers [Array<MetricFu::Grapher>]
|
|
6
|
+
def self.graphers
|
|
7
|
+
@graphers
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.inherited(subclass)
|
|
11
|
+
@graphers << subclass
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.get_grapher(metric)
|
|
15
|
+
graphers.find { |grapher|grapher.metric.to_s == metric.to_s }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
attr_accessor :output_directory
|
|
19
|
+
|
|
20
|
+
def initialize(opts = {})
|
|
21
|
+
self.output_directory = opts[:output_directory]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def output_directory
|
|
25
|
+
@output_directory || MetricFu::Io::FileSystem.directory("output_directory")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def get_metrics(_metrics, _sortable_prefix)
|
|
29
|
+
not_implemented
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def graph!
|
|
33
|
+
labels = MultiJson.dump(@labels)
|
|
34
|
+
content = <<-EOS
|
|
35
|
+
var graph_title = '#{title}';
|
|
36
|
+
#{build_data(data)}
|
|
37
|
+
var graph_labels = #{labels};
|
|
38
|
+
EOS
|
|
39
|
+
File.open(File.join(output_directory, "results", output_filename), "w") { |f| f << content }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def title
|
|
43
|
+
not_implemented
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def date
|
|
47
|
+
not_implemented
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def output_filename
|
|
51
|
+
not_implemented
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def build_data(data)
|
|
57
|
+
"var graph_series = [" << Array(data).map do |label, datum|
|
|
58
|
+
"{name: '#{label}', data: [#{datum}]}"
|
|
59
|
+
end.join(",") << "];"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def not_implemented
|
|
63
|
+
raise "#{__LINE__} in #{__FILE__} from #{caller[0]}"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module MetricFu
|
|
2
|
+
# MetricFu.result memoizes access to a Result object, that will be
|
|
3
|
+
# used throughout the lifecycle of the MetricFu app.
|
|
4
|
+
def self.result
|
|
5
|
+
@result ||= Result.new
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# = Result
|
|
9
|
+
#
|
|
10
|
+
# The Result class is responsible for one thing:
|
|
11
|
+
#
|
|
12
|
+
# It tracks the results generated by each metric used in this test run.
|
|
13
|
+
class Result
|
|
14
|
+
# Renders the result of the result_hash into a yaml serialization
|
|
15
|
+
# ready for writing out to a file.
|
|
16
|
+
#
|
|
17
|
+
# @return YAML
|
|
18
|
+
# A YAML object containing the results of the result generation
|
|
19
|
+
# process
|
|
20
|
+
def as_yaml
|
|
21
|
+
result_hash.to_yaml
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def per_file_data
|
|
25
|
+
@per_file_data ||= Hash.new do |hash, filename|
|
|
26
|
+
hash[filename] = Hash.new do |h, line|
|
|
27
|
+
h[line] = Array.new
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def result_hash #:nodoc:
|
|
33
|
+
@result_hash ||= {}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Adds a hash from a passed result, produced by one of the Generator
|
|
37
|
+
# classes to the aggregate result_hash managed by this hash.
|
|
38
|
+
#
|
|
39
|
+
# @param result_type Hash
|
|
40
|
+
# The hash to add to the aggregate result_hash
|
|
41
|
+
def add(result_type)
|
|
42
|
+
mf_debug "result requested #{result_type}"
|
|
43
|
+
metric_options = metric_options_for_result_type(result_type)
|
|
44
|
+
generator_class = MetricFu::Generator.get_generator(result_type)
|
|
45
|
+
mf_debug "result class found #{generator_class}"
|
|
46
|
+
generator = generator_class.new(metric_options)
|
|
47
|
+
|
|
48
|
+
result_hash.merge!(generator.generate_result)
|
|
49
|
+
|
|
50
|
+
generator.per_file_info(per_file_data) if generator.respond_to?(:per_file_info)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def metric_options_for_result_type(result_type)
|
|
56
|
+
MetricFu::Metric.get_metric(result_type).run_options
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
module MetricFu
|
|
2
|
+
class Run
|
|
3
|
+
def initialize
|
|
4
|
+
STDOUT.sync = true
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def run(options = {})
|
|
8
|
+
configure_run(options)
|
|
9
|
+
measure
|
|
10
|
+
display_results if options[:open]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def report_metrics(metrics = MetricFu::Metric.enabled_metrics)
|
|
14
|
+
metrics.map(&:name)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def measure
|
|
18
|
+
reporter.start
|
|
19
|
+
report_metrics.each {|metric|
|
|
20
|
+
reporter.start_metric(metric)
|
|
21
|
+
MetricFu.result.add(metric)
|
|
22
|
+
reporter.finish_metric(metric)
|
|
23
|
+
}
|
|
24
|
+
reporter.finish
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def display_results
|
|
28
|
+
reporter.display_results
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def configure_run(options)
|
|
34
|
+
disable_metrics(options)
|
|
35
|
+
configure_formatters(options)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def disable_metrics(options)
|
|
39
|
+
return if options.size == 0
|
|
40
|
+
report_metrics.each do |metric|
|
|
41
|
+
metric = metric.to_sym
|
|
42
|
+
if (metric_options = options[metric])
|
|
43
|
+
mf_debug "using metric #{metric}"
|
|
44
|
+
configure_metric(metric, metric_options) if metric_options.is_a?(Hash)
|
|
45
|
+
else
|
|
46
|
+
mf_debug "disabling metric #{metric}"
|
|
47
|
+
MetricFu::Metric.get_metric(metric).enabled = false
|
|
48
|
+
mf_debug "active metrics are #{MetricFu::Metric.enabled_metrics.inspect}"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def configure_metric(metric, metric_options)
|
|
54
|
+
MetricFu::Configuration.configure_metric(metric) do |metric|
|
|
55
|
+
metric_options.each do |option, value|
|
|
56
|
+
mf_log "Setting #{metric} option #{option} to #{value}"
|
|
57
|
+
metric.public_send("#{option}=", value)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def configure_formatters(options)
|
|
63
|
+
# Configure from command line if any.
|
|
64
|
+
if options[:format]
|
|
65
|
+
MetricFu.configuration.formatters.clear # Command-line format takes precedence.
|
|
66
|
+
Array(options[:format]).each do |format, o|
|
|
67
|
+
MetricFu.configuration.configure_formatter(format, o)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
# If no formatters specified, use defaults.
|
|
71
|
+
if MetricFu.configuration.formatters.empty?
|
|
72
|
+
Array(MetricFu::Formatter::DEFAULT).each do |format, o|
|
|
73
|
+
MetricFu.configuration.configure_formatter(format, o)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def reporter
|
|
79
|
+
MetricFu::Reporter.new(MetricFu.configuration.formatters)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require "rake"
|
|
2
|
+
require "metric_fu/run"
|
|
3
|
+
namespace :metrics do
|
|
4
|
+
def options_tip(task_name)
|
|
5
|
+
"with options, for example: rake metrics:#{task_name}['cane: {abc_max: 81}']"
|
|
6
|
+
end
|
|
7
|
+
desc "Generate all metrics reports, or #{options_tip('all')}"
|
|
8
|
+
task :all, [:options] do |_t, args|
|
|
9
|
+
MetricFu.run(process_options(args.options))
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
desc "Run only specified ;-separated metrics, for example, metrics:only[cane;flog] or #{options_tip('only')}"
|
|
13
|
+
task :only, [:metrics, :options] do |_t, args|
|
|
14
|
+
requested_metrics = args.metrics.to_s.split(";").map(&:strip)
|
|
15
|
+
enabled_metrics = MetricFu::Metric.enabled_metrics.map(&:name)
|
|
16
|
+
metrics_to_run = enabled_metrics.select { |metric| requested_metrics.include?(metric.to_s) }
|
|
17
|
+
MetricFu.run_only(metrics_to_run, process_options(args.options))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
MetricFu::Metric.enabled_metrics.each do |metric|
|
|
21
|
+
name = metric.name
|
|
22
|
+
desc "Generate report for #{name}, or #{options_tip('cane')}"
|
|
23
|
+
task name, [:options] do |_t, args|
|
|
24
|
+
MetricFu.run_only(name, process_options(args.options))
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
# from https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/hash/keys.rb
|
|
31
|
+
class Hash
|
|
32
|
+
# Destructively, recursively convert all keys to symbols, as long as they respond
|
|
33
|
+
# to +to_sym+.
|
|
34
|
+
def recursively_symbolize_keys!
|
|
35
|
+
keys.each do |key|
|
|
36
|
+
value = delete(key)
|
|
37
|
+
new_key = key.intern # rescue
|
|
38
|
+
self[new_key] = (value.is_a?(Hash) ? value.dup.recursively_symbolize_keys! : value)
|
|
39
|
+
end
|
|
40
|
+
self
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def process_options(options)
|
|
45
|
+
return {} if options.nil? or options.empty?
|
|
46
|
+
options = YAML.load(options)
|
|
47
|
+
if options.is_a?(Hash)
|
|
48
|
+
p "Got options #{options.recursively_symbolize_keys!.inspect}"
|
|
49
|
+
options
|
|
50
|
+
else
|
|
51
|
+
raise "Invalid options #{options.inspect}, is a #{options.class}, should be a Hash"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<%
|
|
2
|
+
gem_spec = MetricFu::GemVersion.activated_gems.find { |g| g.name =~ /metric_fu/ }
|
|
3
|
+
gem_name = gem_spec.name
|
|
4
|
+
gem_version = gem_spec.version.to_s
|
|
5
|
+
gem_description = gem_spec.description
|
|
6
|
+
gem_homepage = gem_spec.homepage
|
|
7
|
+
%>
|
|
8
|
+
<p>Generated by <a href="<%= gem_homepage %>" title="<%= gem_description %>"><%= gem_name %></a> (v<%= gem_version %>)</p>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<p>Generated on <%= MetricFu.current_time %></p>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
MetricFu.lib_require { "templates/metrics_template" }
|
|
2
|
+
module MetricFu::Templates
|
|
3
|
+
class Configuration
|
|
4
|
+
FILE_PREFIX = "file:/"
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
@options = {}
|
|
8
|
+
@options[:template_class] = MetricFu::Templates::MetricsTemplate
|
|
9
|
+
@options[:darwin_txmt_protocol_no_thanks] = true
|
|
10
|
+
# turning off syntax_highlighting may avoid some UTF-8 issues
|
|
11
|
+
@options[:syntax_highlighting] = true
|
|
12
|
+
@options[:link_prefix] = FILE_PREFIX
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
[:template_class, :link_prefix, :syntax_highlighting, :darwin_txmt_protocol_no_thanks].each do |option|
|
|
16
|
+
define_method("#{option}=") do |arg|
|
|
17
|
+
@options[option] = arg
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def option(name)
|
|
22
|
+
@options.fetch(name.to_sym) { raise "No such template option: #{name}" }
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
.bluff-tooltip {
|
|
2
|
+
background: #fff;
|
|
3
|
+
border: 1px solid #d1edf5;
|
|
4
|
+
padding: 8px 8px 6px;
|
|
5
|
+
}
|
|
6
|
+
.bluff-tooltip .color {
|
|
7
|
+
display: block;
|
|
8
|
+
height: 4px;
|
|
9
|
+
width: 30px;
|
|
10
|
+
margin: 0 0 4px;
|
|
11
|
+
overflow: hidden;
|
|
12
|
+
}
|
|
13
|
+
.bluff-tooltip .data {
|
|
14
|
+
font-weight: bold;
|
|
15
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/* --------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
buttons.css
|
|
4
|
+
* Gives you some great CSS-only buttons.
|
|
5
|
+
|
|
6
|
+
Created by Kevin Hale [particletree.com]
|
|
7
|
+
* particletree.com/features/rediscovering-the-button-element
|
|
8
|
+
|
|
9
|
+
See Readme.txt in this folder for instructions.
|
|
10
|
+
|
|
11
|
+
-------------------------------------------------------------- */
|
|
12
|
+
|
|
13
|
+
button {
|
|
14
|
+
display:block;
|
|
15
|
+
float:left;
|
|
16
|
+
margin:0 0.583em 0.667em 0;
|
|
17
|
+
padding:5px 10px 5px 7px; /* Links */
|
|
18
|
+
|
|
19
|
+
border:1px solid #dedede;
|
|
20
|
+
border-top:1px solid #eee;
|
|
21
|
+
border-left:1px solid #eee;
|
|
22
|
+
|
|
23
|
+
background-color:#f5f5f5;
|
|
24
|
+
font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif;
|
|
25
|
+
font-size:100%;
|
|
26
|
+
line-height:130%;
|
|
27
|
+
text-decoration:none;
|
|
28
|
+
font-weight:bold;
|
|
29
|
+
color:#565656;
|
|
30
|
+
cursor:pointer;
|
|
31
|
+
}
|
|
32
|
+
button {
|
|
33
|
+
width:auto;
|
|
34
|
+
overflow:visible;
|
|
35
|
+
padding:4px 10px 3px 7px; /* IE6 */
|
|
36
|
+
}
|
|
37
|
+
button[type] {
|
|
38
|
+
padding:4px 10px 4px 7px; /* Firefox */
|
|
39
|
+
line-height:17px; /* Safari */
|
|
40
|
+
}
|
|
41
|
+
*:first-child+html button[type] {
|
|
42
|
+
padding:4px 10px 3px 7px; /* IE7 */
|
|
43
|
+
}
|
|
44
|
+
button img {
|
|
45
|
+
margin:0 3px -3px 0 !important;
|
|
46
|
+
padding:0;
|
|
47
|
+
border:none;
|
|
48
|
+
width:16px;
|
|
49
|
+
height:16px;
|
|
50
|
+
float:none;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
/* Button colors
|
|
55
|
+
-------------------------------------------------------------- */
|
|
56
|
+
|
|
57
|
+
/* Standard */
|
|
58
|
+
button:hover {
|
|
59
|
+
background-color:#dff4ff;
|
|
60
|
+
border:1px solid #c2e1ef;
|
|
61
|
+
color:#336699;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* Positive */
|
|
65
|
+
body .positive {
|
|
66
|
+
color:#529214;
|
|
67
|
+
}
|
|
68
|
+
button.positive:hover {
|
|
69
|
+
background-color:#E6EFC2;
|
|
70
|
+
border:1px solid #C6D880;
|
|
71
|
+
color:#529214;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* Negative */
|
|
75
|
+
body .negative {
|
|
76
|
+
color:#d12f19;
|
|
77
|
+
}
|
|
78
|
+
button.negative:hover {
|
|
79
|
+
background:#fbe3e4;
|
|
80
|
+
border:1px solid #fbc2c4;
|
|
81
|
+
color:#d12f19;
|
|
82
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
table {
|
|
2
|
+
margin-top: 20px;
|
|
3
|
+
border-collapse: collapse;
|
|
4
|
+
border: 1px solid #666;
|
|
5
|
+
background: #fff;
|
|
6
|
+
margin-bottom: 20px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
table tr.light {
|
|
10
|
+
background: #fff;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
table tr.dark {
|
|
14
|
+
background: #f9f9f9;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
table tr:hover {
|
|
18
|
+
background: #FFFFC0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
table td, table th {
|
|
22
|
+
padding: 4px;
|
|
23
|
+
font-size: 11px;
|
|
24
|
+
}
|
|
25
|
+
table th {
|
|
26
|
+
text-align: center;
|
|
27
|
+
color: #337022;
|
|
28
|
+
background: #DDFFCC;
|
|
29
|
+
font-weight: bold;
|
|
30
|
+
border: #99D688 1px solid;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
table td {
|
|
34
|
+
border: #d0d0d0 1px solid;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
table td.score {
|
|
38
|
+
text-align: right;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.warning {
|
|
42
|
+
background: yellow;
|
|
43
|
+
}
|