openstudio_measure_tester 0.1.0 → 0.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/LICENSE.md +21 -6
- data/README.md +4 -3
- data/lib/openstudio_measure_tester/core_ext.rb +13 -4
- data/lib/openstudio_measure_tester/coverage.rb +21 -30
- data/lib/openstudio_measure_tester/dashboard.rb +4 -4
- data/lib/openstudio_measure_tester/minitest_result.rb +4 -9
- data/lib/openstudio_measure_tester/openstudio_style.rb +98 -104
- data/lib/openstudio_measure_tester/openstudio_testing_result.rb +16 -8
- data/lib/openstudio_measure_tester/rubocop_result.rb +34 -40
- data/lib/openstudio_measure_tester/templates/dashboard.html.erb +7 -0
- data/lib/openstudio_measure_tester/test_helper.rb +1 -1
- data/lib/openstudio_measure_tester/version.rb +1 -1
- data/openstudio_measure_tester.gemspec +2 -2
- metadata +17 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf7807726298de144c1f44ded68e11af9b389c38
|
4
|
+
data.tar.gz: afa2d01a892ea3fb49a5e4d93555b40974873d35
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e10be74cad42b0c28d455d2dca57c9dad75a3cc8e6f3d85436c7c2f8af64361afcd926595d00005339a7c3c720f1408630cb0b155e39a658215f8ee4ccdbb87
|
7
|
+
data.tar.gz: 2ca984e2587912994d06f0ca7d779c6b3fa2acb96730769e3928c423750e8285706814ec4529e68b7668df9cf9e234e599f2bf7638d3da3dd504fcd2d47a5024
|
data/CHANGELOG.md
ADDED
data/LICENSE.md
CHANGED
@@ -1,13 +1,28 @@
|
|
1
1
|
OpenStudio(R), Copyright (c) 2008-2018, Alliance for Sustainable Energy, LLC. All rights reserved.
|
2
2
|
|
3
|
-
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
4
|
+
that the following conditions are met:
|
4
5
|
|
5
|
-
(1) Redistributions of source code must retain the above copyright notice, this list of conditions and
|
6
|
+
(1) Redistributions of source code must retain the above copyright notice, this list of conditions and
|
7
|
+
the following disclaimer.
|
6
8
|
|
7
|
-
(2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
|
9
|
+
(2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
|
10
|
+
the following disclaimer in the documentation and/or other materials provided with the distribution.
|
8
11
|
|
9
|
-
(3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or
|
12
|
+
(3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or
|
13
|
+
promote products derived from this software without specific prior written permission from the respective
|
14
|
+
party.
|
10
15
|
|
11
|
-
(4) Other than as required in clauses (1) and (2), distributions in any form of modifications or other
|
16
|
+
(4) Other than as required in clauses (1) and (2), distributions in any form of modifications or other
|
17
|
+
derivative works may not use the "OpenStudio" trademark, "OS", "os", or any other confusingly similar
|
18
|
+
designation without specific prior written permission from Alliance for Sustainable Energy, LLC.
|
12
19
|
|
13
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
21
|
+
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
22
|
+
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE UNITED
|
23
|
+
STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY
|
24
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
25
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
27
|
+
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
28
|
+
DAMAGE.
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
# OpenStudio Measure Tester
|
1
|
+
# OpenStudio® Measure Tester
|
2
2
|
|
3
|
-
[](https://travis-ci.org/NREL/OpenStudio-measure-tester-gem)
|
4
|
+
[](https://badge.fury.io/rb/openstudio_measure_tester)
|
4
5
|
|
5
6
|
The OpenStudio Measure Tester is a rubygem that exposes rake tasks for testing OpenStudio measures.
|
6
7
|
|
@@ -17,7 +18,7 @@ The OpenStudio Measure Tester is a rubygem that exposes rake tasks for testing O
|
|
17
18
|
|
18
19
|
# or
|
19
20
|
|
20
|
-
gem 'openstudio_measure_tester', path: '../<path-to-checkout'
|
21
|
+
gem 'openstudio_measure_tester', path: '../<path-to-checkout>'
|
21
22
|
```
|
22
23
|
|
23
24
|
* Rakefile
|
@@ -29,10 +29,10 @@
|
|
29
29
|
class String
|
30
30
|
def to_snakecase
|
31
31
|
r = gsub(/::/, '/')
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
33
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
34
|
+
.tr('-', '_')
|
35
|
+
.downcase
|
36
36
|
r.gsub!('energy_plus', 'energyplus')
|
37
37
|
r.gsub!('open_studio', 'openstudio')
|
38
38
|
r
|
@@ -67,3 +67,12 @@ class String
|
|
67
67
|
r
|
68
68
|
end
|
69
69
|
end
|
70
|
+
|
71
|
+
# Extend the Git log to add an empty method - for rubocop autocorrect happiness.
|
72
|
+
module Git
|
73
|
+
class Log
|
74
|
+
def empty?
|
75
|
+
size.zero? # rubocop:disable Style/ZeroLengthPredicate
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -47,7 +47,6 @@ module OpenStudioMeasureTester
|
|
47
47
|
@measure_coverages = {}
|
48
48
|
|
49
49
|
parse_results
|
50
|
-
|
51
50
|
end
|
52
51
|
|
53
52
|
def parse_results
|
@@ -76,8 +75,8 @@ module OpenStudioMeasureTester
|
|
76
75
|
end
|
77
76
|
|
78
77
|
measure_names.each do |measure_name|
|
79
|
-
|
80
|
-
results = coverage_results['coverage'].select {|key, _data| key.include? measure_name}
|
78
|
+
cn = ''
|
79
|
+
results = coverage_results['coverage'].select { |key, _data| key.include? measure_name }
|
81
80
|
|
82
81
|
mhash = {}
|
83
82
|
mhash['total_lines'] = 0
|
@@ -93,29 +92,27 @@ module OpenStudioMeasureTester
|
|
93
92
|
fhash['total_lines'] = data.size
|
94
93
|
|
95
94
|
# get the class name
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
# end
|
112
|
-
# end
|
95
|
+
if fhash['name'] == 'measure.rb'
|
96
|
+
unless File.exist? key
|
97
|
+
# magically try to find the path name by dropping the first element of array
|
98
|
+
puts "Trying to determine the file path of unknown measure #{key}"
|
99
|
+
key = key.split('/')[1..-1].join('/') until File.exist?(key) || key.split('/').empty?
|
100
|
+
end
|
101
|
+
|
102
|
+
# file should exist now
|
103
|
+
File.readlines(key).each do |line|
|
104
|
+
if (line.include? 'class') && line.split(' ')[0] == 'class'
|
105
|
+
cn = line.split(' ')[1].gsub /_?[tT]est\z/, ''
|
106
|
+
break
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
113
110
|
|
114
111
|
mhash['total_lines'] += fhash['total_lines']
|
115
112
|
# remove nils from array
|
116
113
|
data.delete(nil)
|
117
114
|
|
118
|
-
cov = data.count {|x| x > 0}
|
115
|
+
cov = data.count { |x| x > 0 }
|
119
116
|
fhash['percent_coverage'] = ((cov.to_f / data.size.to_f) * 100).round(2)
|
120
117
|
fhash['missed_lines'] = data.size - cov
|
121
118
|
fhash['relevant_lines'] = data.size
|
@@ -127,16 +124,13 @@ module OpenStudioMeasureTester
|
|
127
124
|
mhash['missed_lines'] += fhash['missed_lines']
|
128
125
|
|
129
126
|
mhash['files'] << fhash
|
130
|
-
|
131
127
|
end
|
132
128
|
mhash['percent_coverage'] = (mhash['covered_lines'].to_f / mhash['relevant_lines'].to_f * 100).round(2)
|
133
|
-
|
134
|
-
@measure_coverages[measure_name] = mhash
|
129
|
+
@measure_coverages[cn] = mhash
|
135
130
|
@total_lines += mhash['total_lines']
|
136
131
|
@total_relevant_lines += mhash['relevant_lines']
|
137
132
|
@total_covered_lines += mhash['covered_lines']
|
138
133
|
@total_missed_lines += mhash['missed_lines']
|
139
|
-
|
140
134
|
end
|
141
135
|
|
142
136
|
# pp @measure_coverages
|
@@ -146,11 +140,10 @@ module OpenStudioMeasureTester
|
|
146
140
|
@total_percent_coverage = (@total_covered_lines.to_f / lines.to_f * 100).round(2)
|
147
141
|
end
|
148
142
|
pp "Total Coverage: #{@total_percent_coverage}"
|
149
|
-
|
150
143
|
end
|
151
144
|
|
152
145
|
def to_hash
|
153
|
-
results = {}
|
146
|
+
results = {}
|
154
147
|
results['total_percent_coverage'] = @total_percent_coverage
|
155
148
|
results['total_lines'] = @total_lines
|
156
149
|
results['total_relevant_lines'] = @total_relevant_lines
|
@@ -168,7 +161,5 @@ module OpenStudioMeasureTester
|
|
168
161
|
file << JSON.pretty_generate(res_hash)
|
169
162
|
end
|
170
163
|
end
|
171
|
-
|
172
164
|
end
|
173
|
-
|
174
|
-
end
|
165
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'erb'
|
2
2
|
module OpenStudioMeasureTester
|
3
3
|
class Dashboard
|
4
4
|
attr_reader :html
|
@@ -15,7 +15,7 @@ module OpenStudioMeasureTester
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def render
|
18
|
-
rendered = ERB.new(@template, 0,
|
18
|
+
rendered = ERB.new(@template, 0, '', '@html').result(binding)
|
19
19
|
save_dir = "#{@base_dir}/test_results/dashboard"
|
20
20
|
|
21
21
|
# Render the dashboard
|
@@ -26,8 +26,8 @@ module OpenStudioMeasureTester
|
|
26
26
|
# KAF: for some reason, not overwriting the files. delete them from destination first
|
27
27
|
FileUtils.remove_dir("#{save_dir}/css") if Dir.exist?"#{save_dir}/css"
|
28
28
|
FileUtils.remove_dir("#{save_dir}/js") if Dir.exist? "#{save_dir}/js"
|
29
|
-
FileUtils.cp_r("#{resource_path}/css", "#{save_dir}/css", :
|
30
|
-
FileUtils.cp_r("#{resource_path}/js", "#{save_dir}/js", :
|
29
|
+
FileUtils.cp_r("#{resource_path}/css", "#{save_dir}/css", remove_destination: true)
|
30
|
+
FileUtils.cp_r("#{resource_path}/js", "#{save_dir}/js", remove_destination: true)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -52,7 +52,6 @@ module OpenStudioMeasureTester
|
|
52
52
|
|
53
53
|
parse_results
|
54
54
|
to_file
|
55
|
-
|
56
55
|
end
|
57
56
|
|
58
57
|
def parse_results
|
@@ -60,9 +59,9 @@ module OpenStudioMeasureTester
|
|
60
59
|
puts "Parsing minitest report #{file}"
|
61
60
|
hash = Hash.from_xml(File.read(file))
|
62
61
|
|
63
|
-
#pp hash
|
62
|
+
# pp hash
|
64
63
|
|
65
|
-
measure_name = file.split('/')[-1].split('.')[0].split('-')[1]
|
64
|
+
measure_name = file.split('/')[-1].split('.')[0].split('-')[1].gsub /-?[tT]est\z/, ''
|
66
65
|
|
67
66
|
mhash = {}
|
68
67
|
|
@@ -75,7 +74,7 @@ module OpenStudioMeasureTester
|
|
75
74
|
|
76
75
|
# Note: only 1 failure and 1 error possible per test
|
77
76
|
errors, failures = parse_measure(hash)
|
78
|
-
mhash['issues'] = {errors: errors, failures: failures}
|
77
|
+
mhash['issues'] = { errors: errors, failures: failures }
|
79
78
|
|
80
79
|
@measure_results[measure_name] = mhash
|
81
80
|
|
@@ -84,13 +83,11 @@ module OpenStudioMeasureTester
|
|
84
83
|
@total_errors += mhash['measure_errors']
|
85
84
|
@total_failures += mhash['measure_failures']
|
86
85
|
@total_skipped += mhash['measure_skipped']
|
87
|
-
|
88
86
|
end
|
89
87
|
|
90
88
|
@error_status = true if @total_errors > 0
|
91
89
|
|
92
|
-
#pp measure_results
|
93
|
-
|
90
|
+
# pp measure_results
|
94
91
|
end
|
95
92
|
|
96
93
|
def to_file
|
@@ -115,7 +112,6 @@ module OpenStudioMeasureTester
|
|
115
112
|
private
|
116
113
|
|
117
114
|
def parse_measure(measure)
|
118
|
-
|
119
115
|
errors = []
|
120
116
|
failures = []
|
121
117
|
|
@@ -138,7 +134,6 @@ module OpenStudioMeasureTester
|
|
138
134
|
end
|
139
135
|
|
140
136
|
return errors, failures
|
141
|
-
|
142
137
|
end
|
143
138
|
end
|
144
139
|
end
|
@@ -32,90 +32,76 @@ module OpenStudioMeasureTester
|
|
32
32
|
attr_reader :measure_messages
|
33
33
|
|
34
34
|
CHECKS = [
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
regex: /MiniTest::Unit::TestCase/,
|
100
|
-
check_type: :if_exists,
|
101
|
-
message: "MiniTest::Unit::TestCase is deprecated. Use MiniTest::Test.",
|
102
|
-
type: :syntax,
|
103
|
-
severity: :warning,
|
104
|
-
file_type: :test
|
105
|
-
}, {
|
106
|
-
regex: /require .openstudio\/ruleset /,
|
107
|
-
check_type: :if_exists,
|
108
|
-
message: "Require openstudio/ruleset/* is deprecated. Use require 'openstudio/measure/*'",
|
109
|
-
type: :syntax,
|
110
|
-
severity: :warning,
|
111
|
-
file_type: :test
|
112
|
-
}
|
35
|
+
{
|
36
|
+
regex: /OpenStudio::Ruleset::ModelUserScript/,
|
37
|
+
check_type: :if_exists,
|
38
|
+
message: 'OpenStudio::Ruleset::ModelUserScript is deprecated, use OpenStudio::Measure::ModelMeasure instead.',
|
39
|
+
type: :deprecated,
|
40
|
+
severity: :error,
|
41
|
+
file_type: :measure
|
42
|
+
}, {
|
43
|
+
regex: /OpenStudio::Ruleset::OSRunner/,
|
44
|
+
check_type: :if_exists,
|
45
|
+
message: 'OpenStudio::Ruleset::OSRunner is deprecated, use OpenStudio::Measure::OSRunner.new(OpenStudio::WorkflowJSON.new) instead.',
|
46
|
+
type: :deprecated,
|
47
|
+
severity: :error,
|
48
|
+
file_type: :measure
|
49
|
+
}, {
|
50
|
+
regex: /OpenStudio::Ruleset::OSRunner/,
|
51
|
+
check_type: :if_exists,
|
52
|
+
message: 'OpenStudio::Ruleset::OSRunner is deprecated, use OpenStudio::Measure::OSRunner.new(OpenStudio::WorkflowJSON.new) instead.',
|
53
|
+
type: :deprecated,
|
54
|
+
severity: :error,
|
55
|
+
file_type: :test
|
56
|
+
}, {
|
57
|
+
regex: /OpenStudio::Ruleset::OSArgumentVector/,
|
58
|
+
check_type: :if_exists,
|
59
|
+
message: 'OpenStudio::Ruleset::OSArgumentVector is deprecated, use OpenStudio::Measure::OSArgumentVector instead.',
|
60
|
+
type: :deprecated,
|
61
|
+
severity: :error,
|
62
|
+
file_type: :measure
|
63
|
+
}, {
|
64
|
+
regex: /OpenStudio::Ruleset::OSArgument/,
|
65
|
+
check_type: :if_exists,
|
66
|
+
message: 'OpenStudio::Ruleset::OSArgument is deprecated, use OpenStudio::Measure::OSArgument instead.',
|
67
|
+
type: :deprecated,
|
68
|
+
severity: :error,
|
69
|
+
file_type: :measure
|
70
|
+
}, {
|
71
|
+
regex: /OpenStudio::Ruleset::OSArgumentMap/,
|
72
|
+
check_type: :if_exists,
|
73
|
+
message: 'OpenStudio::Ruleset::OSArgumentMap is deprecated, use OpenStudio::Measure.convertOSArgumentVectorToMap(arguments) instead.',
|
74
|
+
type: :deprecated,
|
75
|
+
severity: :error,
|
76
|
+
file_type: :measure
|
77
|
+
}, {
|
78
|
+
regex: /require .openstudio_measure_tester\/test_helper./,
|
79
|
+
check_type: :if_missing,
|
80
|
+
message: "Must include 'require 'openstudio_measure_tester/test_helper'' in Test file to report coverage correctly.",
|
81
|
+
type: :syntax,
|
82
|
+
severity: :error,
|
83
|
+
file_type: :test
|
84
|
+
}, {
|
85
|
+
regex: /MiniTest::Unit::TestCase/,
|
86
|
+
check_type: :if_exists,
|
87
|
+
message: 'MiniTest::Unit::TestCase is deprecated. Use MiniTest::Test.',
|
88
|
+
type: :syntax,
|
89
|
+
severity: :warning,
|
90
|
+
file_type: :test
|
91
|
+
}, {
|
92
|
+
regex: /require .openstudio\/ruleset /,
|
93
|
+
check_type: :if_exists,
|
94
|
+
message: "Require openstudio/ruleset/* is deprecated. Use require 'openstudio/measure/*'",
|
95
|
+
type: :syntax,
|
96
|
+
severity: :warning,
|
97
|
+
file_type: :test
|
98
|
+
}
|
113
99
|
].freeze
|
114
100
|
|
115
101
|
# Pass in the measures_glob with the filename (typically measure.rb)
|
116
102
|
def initialize(measures_glob)
|
117
103
|
@measures_glob = measures_glob
|
118
|
-
@results = {by_measure: {}}
|
104
|
+
@results = { by_measure: {} }
|
119
105
|
|
120
106
|
# Individual measure messages
|
121
107
|
@measure_messages = []
|
@@ -158,6 +144,12 @@ module OpenStudioMeasureTester
|
|
158
144
|
measure_missing = true
|
159
145
|
end
|
160
146
|
|
147
|
+
# Test the existence of LICENSE.md
|
148
|
+
unless File.exist? "#{measure_dir}/LICENSE.md"
|
149
|
+
log_message("Could not find LICENSE.md in '#{measure_dir}'.", :general, :warning)
|
150
|
+
end
|
151
|
+
|
152
|
+
|
161
153
|
unless measure_missing
|
162
154
|
measure = OpenStudio::BCLMeasure.load(measure_dir)
|
163
155
|
if measure.empty?
|
@@ -181,23 +173,25 @@ module OpenStudioMeasureTester
|
|
181
173
|
|
182
174
|
# pp @measure_messages
|
183
175
|
|
176
|
+
|
177
|
+
|
184
178
|
# calculate the info, warnings, errors and return the measure data
|
185
179
|
# TODO: break out the issues by file
|
186
180
|
return {
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
181
|
+
@measure_classname.to_sym => {
|
182
|
+
measure_info: @measure_messages.nil? ? 0 : @measure_messages.count { |h| h[:severity] == :info },
|
183
|
+
measure_warnings: @measure_messages.nil? ? 0 : @measure_messages.count { |h| h[:severity] == :warning },
|
184
|
+
measure_errors: @measure_messages.nil? ? 0 : @measure_messages.count { |h| h[:severity] == :error },
|
185
|
+
issues: @measure_messages.clone
|
186
|
+
}
|
193
187
|
}
|
194
188
|
end
|
195
189
|
|
196
190
|
def log_message(message, type = :syntax, severity = :info)
|
197
191
|
new_message = {
|
198
|
-
|
199
|
-
|
200
|
-
|
192
|
+
message: message,
|
193
|
+
type: type,
|
194
|
+
severity: severity
|
201
195
|
}
|
202
196
|
@measure_messages << new_message
|
203
197
|
end
|
@@ -219,7 +213,7 @@ module OpenStudioMeasureTester
|
|
219
213
|
|
220
214
|
def save_results
|
221
215
|
FileUtils.mkdir 'openstudio_style' unless Dir.exist? 'openstudio_style'
|
222
|
-
File.open(
|
216
|
+
File.open('openstudio_style/openstudio_style.json', 'w') do |file|
|
223
217
|
file << JSON.pretty_generate(@results)
|
224
218
|
end
|
225
219
|
end
|
@@ -320,7 +314,7 @@ module OpenStudioMeasureTester
|
|
320
314
|
end
|
321
315
|
|
322
316
|
if measure_hash[:values_from_file][:name] != measure_hash[:name]
|
323
|
-
log_message(
|
317
|
+
log_message('Measure class as snake_case name does not match <name> in XML. Run openstudio measure -u .', :structure, :error)
|
324
318
|
end
|
325
319
|
|
326
320
|
if measure_hash[:values_from_file][:description].empty?
|
@@ -352,12 +346,12 @@ module OpenStudioMeasureTester
|
|
352
346
|
|
353
347
|
def get_attributes_from_measure(measure_dir, class_name)
|
354
348
|
result = {
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
349
|
+
values_from_file: {
|
350
|
+
name: '',
|
351
|
+
display_name: '',
|
352
|
+
description: '',
|
353
|
+
modeler_description: ''
|
354
|
+
}
|
361
355
|
}
|
362
356
|
|
363
357
|
begin
|
@@ -408,7 +402,7 @@ module OpenStudioMeasureTester
|
|
408
402
|
result[:description] = measure.description
|
409
403
|
result[:modeler_description] = measure.modelerDescription
|
410
404
|
result[:tags] = []
|
411
|
-
measure.tags.each {|tag| result[:tags] << tag}
|
405
|
+
measure.tags.each { |tag| result[:tags] << tag }
|
412
406
|
|
413
407
|
result[:outputs] = []
|
414
408
|
begin
|
@@ -431,15 +425,15 @@ module OpenStudioMeasureTester
|
|
431
425
|
measure.attributes.each do |a|
|
432
426
|
value_type = a.valueType
|
433
427
|
if value_type == 'Boolean'.to_AttributeValueType
|
434
|
-
attributes << {name: a.name, display_name: a.displayName(true).get, value: a.valueAsBoolean}
|
428
|
+
attributes << { name: a.name, display_name: a.displayName(true).get, value: a.valueAsBoolean }
|
435
429
|
elsif value_type == 'Double'.to_AttributeValueType
|
436
|
-
attributes << {name: a.name, display_name: a.displayName(true).get, value: a.valueAsDouble}
|
430
|
+
attributes << { name: a.name, display_name: a.displayName(true).get, value: a.valueAsDouble }
|
437
431
|
elsif value_type == 'Integer'.to_AttributeValueType
|
438
|
-
attributes << {name: a.name, display_name: a.displayName(true).get, value: a.valueAsInteger}
|
432
|
+
attributes << { name: a.name, display_name: a.displayName(true).get, value: a.valueAsInteger }
|
439
433
|
elsif value_type == 'Unsigned'.to_AttributeValueType
|
440
|
-
attributes << {name: a.name, display_name: a.displayName(true).get, value: a.valueAsUnsigned}
|
434
|
+
attributes << { name: a.name, display_name: a.displayName(true).get, value: a.valueAsUnsigned }
|
441
435
|
elsif value_type == 'String'.to_AttributeValueType
|
442
|
-
attributes << {name: a.name, display_name: a.displayName(true).get, value: a.valueAsString}
|
436
|
+
attributes << { name: a.name, display_name: a.displayName(true).get, value: a.valueAsString }
|
443
437
|
end
|
444
438
|
end
|
445
439
|
result[:attributes] = attributes
|
@@ -484,9 +478,9 @@ module OpenStudioMeasureTester
|
|
484
478
|
elsif type == 'Choice'.to_OSArgumentType
|
485
479
|
arg[:default_value] = argument.defaultValueAsString if argument.hasDefaultValue
|
486
480
|
arg[:choice_values] = []
|
487
|
-
argument.choiceValues.each {|value| arg[:choice_values] << value}
|
481
|
+
argument.choiceValues.each { |value| arg[:choice_values] << value }
|
488
482
|
arg[:choice_display_names] = []
|
489
|
-
argument.choiceValueDisplayNames.each {|value| arg[:choice_display_names] << value}
|
483
|
+
argument.choiceValueDisplayNames.each { |value| arg[:choice_display_names] << value }
|
490
484
|
|
491
485
|
elsif type == 'Path'.to_OSArgumentType
|
492
486
|
arg[:default_value] = argument.defaultValueAsPath.to_s if argument.hasDefaultValue
|
@@ -39,16 +39,25 @@ module OpenStudioMeasureTester
|
|
39
39
|
@results = {}
|
40
40
|
|
41
41
|
# get the repository info
|
42
|
+
# TODO add failsafe
|
42
43
|
g = Git.open(Dir.pwd)
|
43
44
|
config = g.config
|
44
|
-
repo_name = config['remote.origin.url'].split('/')
|
45
|
-
current_branch = g.branch.name
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
repo_name = config['remote.origin.url'] ? config['remote.origin.url'].split('/').last.chomp('.git') : nil
|
46
|
+
current_branch = g.branch.name ? g.branch.name : nil
|
47
|
+
logs = g.log
|
48
|
+
sha = nil
|
49
|
+
if !logs.empty?
|
50
|
+
sha = logs.first.sha
|
51
|
+
end
|
49
52
|
|
50
53
|
# check if the results data already exist, and if so, then load the file now to keep the results
|
51
54
|
load_results
|
55
|
+
|
56
|
+
# add/overwrite repo info in results
|
57
|
+
@results['repo_name'] = repo_name
|
58
|
+
@results['current_branch'] = current_branch
|
59
|
+
@results['sha'] = sha
|
60
|
+
|
52
61
|
aggregate_results
|
53
62
|
end
|
54
63
|
|
@@ -61,7 +70,7 @@ module OpenStudioMeasureTester
|
|
61
70
|
FileUtils.mv "#{@results_dir}/coverage", "#{@test_results_dir}/."
|
62
71
|
|
63
72
|
cov = OpenStudioMeasureTester::Coverage.new("#{@test_results_dir}/coverage")
|
64
|
-
@results[
|
73
|
+
@results['coverage'] = cov.to_hash
|
65
74
|
end
|
66
75
|
|
67
76
|
# minitest
|
@@ -110,7 +119,7 @@ module OpenStudioMeasureTester
|
|
110
119
|
filename = "#{@test_results_dir}/combined_results.json"
|
111
120
|
begin
|
112
121
|
@results = JSON.parse(File.read(filename)) if File.exist? filename
|
113
|
-
rescue
|
122
|
+
rescue StandardError
|
114
123
|
@results = {}
|
115
124
|
end
|
116
125
|
end
|
@@ -164,4 +173,3 @@ module OpenStudioMeasureTester
|
|
164
173
|
end
|
165
174
|
end
|
166
175
|
end
|
167
|
-
|
@@ -47,7 +47,6 @@ module OpenStudioMeasureTester
|
|
47
47
|
attr_reader :by_measure
|
48
48
|
|
49
49
|
def initialize(path_to_results)
|
50
|
-
|
51
50
|
@path_to_results = path_to_results
|
52
51
|
@error_status = false
|
53
52
|
@total_files = 0
|
@@ -63,7 +62,6 @@ module OpenStudioMeasureTester
|
|
63
62
|
|
64
63
|
parse_results
|
65
64
|
to_file
|
66
|
-
|
67
65
|
end
|
68
66
|
|
69
67
|
def parse_results
|
@@ -72,14 +70,19 @@ module OpenStudioMeasureTester
|
|
72
70
|
puts "Parsing Rubocop report #{file}"
|
73
71
|
hash = Hash.from_xml(File.read(file))
|
74
72
|
|
73
|
+
if hash.nil?
|
74
|
+
puts 'Error reporting Rubocop'
|
75
|
+
return
|
76
|
+
end
|
77
|
+
|
75
78
|
# get measure names
|
76
79
|
measure_names = []
|
77
|
-
#cn= ''
|
80
|
+
# cn= ''
|
78
81
|
hash['checkstyle']['file'].each do |key, data|
|
79
82
|
parts = key['name'].split('/')
|
80
83
|
if parts.last == 'measure.rb'
|
81
|
-
|
82
|
-
|
84
|
+
name = parts[-2]
|
85
|
+
measure_names << name
|
83
86
|
end
|
84
87
|
end
|
85
88
|
|
@@ -87,14 +90,13 @@ module OpenStudioMeasureTester
|
|
87
90
|
@total_files = hash['checkstyle']['file'].length
|
88
91
|
|
89
92
|
measure_names.each do |measure_name|
|
90
|
-
|
91
|
-
|
92
|
-
results = hash['checkstyle']['file'].select {|data| data['name'].include? measure_name }
|
93
|
+
cn = ''
|
94
|
+
results = hash['checkstyle']['file'].select { |data| data['name'].include? measure_name }
|
93
95
|
|
94
96
|
mhash = {}
|
95
97
|
mhash['measure_issues'] = 0
|
96
98
|
mhash['measure_info'] = 0
|
97
|
-
mhash['measure_warnings'] = 0
|
99
|
+
mhash['measure_warnings'] = 0
|
98
100
|
mhash['measure_errors'] = 0
|
99
101
|
mhash['files'] = []
|
100
102
|
|
@@ -104,14 +106,14 @@ module OpenStudioMeasureTester
|
|
104
106
|
fhash['violations'] = []
|
105
107
|
|
106
108
|
# get the class name
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
109
|
+
if fhash['file_name'] == 'measure.rb'
|
110
|
+
File.readlines(key['name']).each do |line|
|
111
|
+
if (line.include? 'class') && line.split(' ')[0] == 'class'
|
112
|
+
cn = line.split(' ')[1].gsub /_?[tT]est\z/, ''
|
113
|
+
break
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
115
117
|
|
116
118
|
if key['error']
|
117
119
|
@file_issues = 0
|
@@ -124,28 +126,27 @@ module OpenStudioMeasureTester
|
|
124
126
|
if key['error'].class == Array
|
125
127
|
@file_issues = key['error'].length
|
126
128
|
key['error'].each do |s|
|
127
|
-
|
128
|
-
if s['severity'] === "info"
|
129
|
+
if s['severity'] === 'info'
|
129
130
|
@file_info += 1
|
130
|
-
elsif s['severity'] ===
|
131
|
+
elsif s['severity'] === 'warning'
|
131
132
|
@file_warnings += 1
|
132
|
-
elsif s['severity'] ===
|
133
|
+
elsif s['severity'] === 'error' # TODO: look up complete list of codes
|
133
134
|
@file_errors += 1
|
134
135
|
end
|
135
|
-
violations << {line: s['line'], column: s['column'], severity: s['severity'], message: s['message']}
|
136
|
+
violations << { line: s['line'], column: s['column'], severity: s['severity'], message: s['message'] }
|
136
137
|
end
|
137
138
|
end
|
138
139
|
|
139
140
|
if key['error'].class == Hash
|
140
141
|
@file_issues = 1
|
141
|
-
if key['error']['severity'] ===
|
142
|
+
if key['error']['severity'] === 'info'
|
142
143
|
@file_info += 1
|
143
|
-
elsif key['error']['severity'] ===
|
144
|
+
elsif key['error']['severity'] === 'warning'
|
144
145
|
@file_warnings += 1
|
145
|
-
elsif key['error']['severity'] ===
|
146
|
+
elsif key['error']['severity'] === 'error'
|
146
147
|
@file_errors += 1
|
147
148
|
end
|
148
|
-
violations << {line: key['error']['line'], column: key['error']['column'], severity: key['error']['severity'], message: key['error']['message']}
|
149
|
+
violations << { line: key['error']['line'], column: key['error']['column'], severity: key['error']['severity'], message: key['error']['message'] }
|
149
150
|
end
|
150
151
|
|
151
152
|
fhash['issues'] = @file_issues
|
@@ -153,7 +154,7 @@ module OpenStudioMeasureTester
|
|
153
154
|
fhash['warning'] = @file_warnings
|
154
155
|
fhash['error'] = @file_errors
|
155
156
|
fhash['violations'] = violations
|
156
|
-
|
157
|
+
|
157
158
|
mhash['measure_issues'] += @file_issues
|
158
159
|
mhash['measure_info'] += @file_info
|
159
160
|
mhash['measure_warnings'] += @file_warnings
|
@@ -161,33 +162,27 @@ module OpenStudioMeasureTester
|
|
161
162
|
|
162
163
|
@total_issues += @file_issues
|
163
164
|
@total_info += @file_info
|
164
|
-
@total_warnings += @file_warnings
|
165
|
+
@total_warnings += @file_warnings
|
165
166
|
@total_errors += @file_errors
|
166
|
-
|
167
|
+
|
167
168
|
end
|
168
|
-
|
169
|
-
mhash['files'] << fhash
|
170
169
|
|
170
|
+
mhash['files'] << fhash
|
171
171
|
end
|
172
172
|
|
173
|
-
|
174
|
-
|
175
|
-
@by_measure[measure_name] = mhash
|
176
|
-
|
173
|
+
# @summary << mhash
|
174
|
+
@by_measure[cn] = mhash
|
177
175
|
end
|
178
|
-
|
179
176
|
end
|
180
177
|
|
181
178
|
puts "total files: #{total_files}"
|
182
179
|
puts "total issues: #{@total_issues} (#{@total_info} info, #{@total_warnings} warnings, #{@total_errors} errors)"
|
183
180
|
|
184
|
-
# TODO: still need to get errors ID'd
|
185
181
|
@error_status = true if @total_errors > 0
|
186
|
-
|
187
182
|
end
|
188
183
|
|
189
184
|
def to_hash
|
190
|
-
results = {}
|
185
|
+
results = {}
|
191
186
|
results['total_measures'] = @total_measures
|
192
187
|
results['total_files'] = @total_files
|
193
188
|
results['total_issues'] = @total_issues
|
@@ -206,7 +201,6 @@ module OpenStudioMeasureTester
|
|
206
201
|
FileUtils.mkdir_p "#{@path_to_results}/" unless Dir.exist? "#{@path_to_results}/"
|
207
202
|
File.open("#{@path_to_results}/rubocop.json", 'w') do |file|
|
208
203
|
file << JSON.pretty_generate(res_hash)
|
209
|
-
|
210
204
|
end
|
211
205
|
end
|
212
206
|
end
|
@@ -26,6 +26,13 @@
|
|
26
26
|
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pb-2 mb-3 border-bottom">
|
27
27
|
<h1 class="h2 accent">Overview</h1>
|
28
28
|
</div>
|
29
|
+
<div class="justify-content-between align-items-center pb-2 mb-3 border-bottom">
|
30
|
+
<div class="row px-1">
|
31
|
+
<div class="col-sm-4"><span class="h5 pr-1">Repo</span><% if @hash['repo_name'] %><%= @hash['repo_name'] %><% end %></div>
|
32
|
+
<div class="col-sm-3"><span class="h5 pr-1">Branch</span><% if @hash['current_branch'] %><%= @hash['current_branch'] %><% end %></div>
|
33
|
+
<div class="col-sm-5"><span class="h5 pr-1">Commit</span><% if @hash['sha'] %><%= @hash['sha'] %><% end %></div>
|
34
|
+
</div>
|
35
|
+
</div>
|
29
36
|
<div class="row">
|
30
37
|
<div class="col-sm">
|
31
38
|
<div class="card">
|
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
lib = File.expand_path('
|
2
|
+
lib = File.expand_path('lib', __dir__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
require 'openstudio_measure_tester/version'
|
5
5
|
|
@@ -25,11 +25,11 @@ Gem::Specification.new do |spec|
|
|
25
25
|
|
26
26
|
spec.add_dependency 'activesupport', '~> 5.1.4'
|
27
27
|
spec.add_dependency 'ci_reporter_minitest', '~> 1.0.0'
|
28
|
+
spec.add_dependency 'git', '~> 1.3.0'
|
28
29
|
spec.add_dependency 'minitest', '~> 5.4.0'
|
29
30
|
spec.add_dependency 'minitest-reporters', '~> 1.1'
|
30
31
|
spec.add_dependency 'rake', '~> 12.3'
|
31
32
|
spec.add_dependency 'rubocop', '~> 0.52'
|
32
33
|
spec.add_dependency 'rubocop-checkstyle_formatter', '~> 0.4'
|
33
34
|
spec.add_dependency 'simplecov', '~> 0.15'
|
34
|
-
spec.add_dependency 'git', '~> 1.3.0'
|
35
35
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openstudio_measure_tester
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicholas Long
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-03-
|
11
|
+
date: 2018-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 1.0.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: git
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.3.0
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.3.0
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: minitest
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,20 +164,6 @@ dependencies:
|
|
150
164
|
- - "~>"
|
151
165
|
- !ruby/object:Gem::Version
|
152
166
|
version: '0.15'
|
153
|
-
- !ruby/object:Gem::Dependency
|
154
|
-
name: git
|
155
|
-
requirement: !ruby/object:Gem::Requirement
|
156
|
-
requirements:
|
157
|
-
- - "~>"
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
version: 1.3.0
|
160
|
-
type: :runtime
|
161
|
-
prerelease: false
|
162
|
-
version_requirements: !ruby/object:Gem::Requirement
|
163
|
-
requirements:
|
164
|
-
- - "~>"
|
165
|
-
- !ruby/object:Gem::Version
|
166
|
-
version: 1.3.0
|
167
167
|
description: Testing framework for OpenStudio measures
|
168
168
|
email:
|
169
169
|
- nicholas.long@nrel.gov
|
@@ -175,6 +175,7 @@ files:
|
|
175
175
|
- ".rspec"
|
176
176
|
- ".rubocop.yml"
|
177
177
|
- ".travis.yml"
|
178
|
+
- CHANGELOG.md
|
178
179
|
- Gemfile
|
179
180
|
- LICENSE.md
|
180
181
|
- README.md
|