hiptest-publisher 1.13.0 → 1.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/lib/config/cucumber-groovy.conf +15 -0
  3. data/lib/config/java-junit.conf +6 -0
  4. data/lib/hiptest-publisher.rb +6 -15
  5. data/lib/hiptest-publisher/{diff_displayer.rb → formatters/diff_displayer.rb} +0 -0
  6. data/lib/hiptest-publisher/formatters/reporter.rb +0 -2
  7. data/lib/hiptest-publisher/{actionword_indexer.rb → indexers/actionword_indexer.rb} +8 -1
  8. data/lib/hiptest-publisher/indexers/actionword_uid_indexer.rb +34 -0
  9. data/lib/hiptest-publisher/node_modifiers/actionword_uniq_renamer.rb +39 -0
  10. data/lib/hiptest-publisher/node_modifiers/add_all.rb +23 -0
  11. data/lib/hiptest-publisher/node_modifiers/call_arguments_adder.rb +52 -0
  12. data/lib/hiptest-publisher/{datatable_fixer.rb → node_modifiers/datatable_fixer.rb} +3 -3
  13. data/lib/hiptest-publisher/node_modifiers/gherkin_adder.rb +243 -0
  14. data/lib/hiptest-publisher/node_modifiers/items_orderer.rb +33 -0
  15. data/lib/hiptest-publisher/{parameter_type_adder.rb → node_modifiers/parameter_type_adder.rb} +15 -14
  16. data/lib/hiptest-publisher/{parent_adder.rb → node_modifiers/parent_adder.rb} +4 -4
  17. data/lib/hiptest-publisher/node_modifiers/uid_call_reference_adder.rb +27 -0
  18. data/lib/hiptest-publisher/nodes.rb +49 -4
  19. data/lib/hiptest-publisher/options_parser.rb +8 -1
  20. data/lib/hiptest-publisher/render_context_maker.rb +28 -8
  21. data/lib/hiptest-publisher/signature_differ.rb +17 -7
  22. data/lib/hiptest-publisher/signature_exporter.rb +18 -4
  23. data/lib/hiptest-publisher/xml_parser.rb +24 -1
  24. data/lib/templates/cucumber/groovy/actionwords-library/actionword.hbs +2 -0
  25. data/lib/templates/cucumber/groovy/actionwords-library/libraries.hbs +9 -0
  26. data/lib/templates/cucumber/groovy/actionwords-library/library.hbs +8 -0
  27. data/lib/templates/cucumber/groovy/actionwords-library/uidcall.hbs +1 -0
  28. data/lib/templates/cucumber/groovy/actionwords/actionwords.hbs +1 -1
  29. data/lib/templates/cucumber/groovy/step-definitions/actionword.hbs +1 -1
  30. data/lib/templates/cucumber/groovy/step-definitions/library.hbs +10 -0
  31. data/lib/templates/gherkin/_call.hbs +5 -0
  32. data/lib/templates/gherkin/call.hbs +1 -5
  33. data/lib/templates/gherkin/uidcall.hbs +1 -0
  34. data/lib/templates/java/_item_as_function.hbs +1 -1
  35. data/lib/templates/java/actionwords.hbs +1 -1
  36. data/lib/templates/java/libraries.hbs +9 -0
  37. data/lib/templates/java/library.hbs +7 -0
  38. data/lib/templates/java/uidcall.hbs +1 -0
  39. metadata +24 -9
  40. data/lib/hiptest-publisher/call_arguments_adder.rb +0 -34
  41. data/lib/hiptest-publisher/items_orderer.rb +0 -31
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf3135292196dceadbed7955498ce586d8f08b075a3bab0323efd92403876835
4
- data.tar.gz: 6af5171a3e54d523bdcd79970e8847f1e94e89019a7c33a98e3436de27f44b47
3
+ metadata.gz: 93bcd3b1fd153cfef0772ddca03018f5286a9818c2027c051ab294db962593f3
4
+ data.tar.gz: e2e270ed0e0df6974697c41465fac47b46dd479db86971897b614e70fdc143dc
5
5
  SHA512:
6
- metadata.gz: 1d7e65e2f1d31e605cb24a48cc1cb8c87137098571b76da485fc2513dd5795fabe81e561ea102f2e7fc17462b8389aa0ab1d0a05979436ccf3c62540cd3ca057
7
- data.tar.gz: 3c5d13ec78ba4f3fa828ec053652a05f29cdb1f23c1a0e266efd3611c851c4b38c53b3d9eef8b41a0a3a58c0538420a3aa2c21220516d920a66175fe80734b74
6
+ metadata.gz: 5e07c6ab53bf5cb4d4884c3079a253ae654574a6ced1ef54528c8b1213e188f708d72811b928bdd7212368189ad376d4bb28890dc7e777a8efc97b07532d1934
7
+ data.tar.gz: c54b5414d1c7bd4a08286f1631e85850b1894b8fbee973fe63c6d967e8785acd2d1a8efda06c7222dbd07af3ce54a864025ddfc937e22cf25a46a58073468531
@@ -20,6 +20,21 @@ filename = 'StepDefinitions.groovy'
20
20
  call_prefix = 'actionwords'
21
21
  renderer_addons = 'GherkinAddon'
22
22
 
23
+ [step_definitions_library]
24
+ node_name = libraries
25
+ call_prefix = 'actionwords'
26
+ template_dirs = cucumber/groovy/step-definitions, groovy, java, common
27
+ named_filename = 'StepDefinitions%s.groovy'
28
+ renderer_addons = 'GherkinAddon'
29
+
23
30
  [actionwords]
24
31
  template_dirs = cucumber/groovy/actionwords, groovy, java, common
25
32
  filename = 'Actionwords.groovy'
33
+
34
+ [library]
35
+ template_dirs = cucumber/groovy/actionwords-library, groovy, java, common
36
+ filename = 'ActionwordLibrary.groovy'
37
+
38
+ [libraries]
39
+ template_dirs = cucumber/groovy/actionwords-library, groovy, java, common
40
+ named_filename = '%sLibrary.groovy'
@@ -13,3 +13,9 @@ call_prefix = 'actionwords'
13
13
 
14
14
  [actionwords]
15
15
  filename = 'Actionwords.java'
16
+
17
+ [library]
18
+ filename = 'ActionwordLibrary.java'
19
+
20
+ [libraries]
21
+ named_filename = '%sLibrary.java'
@@ -2,19 +2,14 @@ require 'colorize'
2
2
  require 'json'
3
3
  require 'yaml'
4
4
 
5
- require 'hiptest-publisher/call_arguments_adder'
5
+ require 'hiptest-publisher/node_modifiers/add_all'
6
6
  require 'hiptest-publisher/cli_options_checker'
7
7
  require 'hiptest-publisher/client'
8
- require 'hiptest-publisher/datatable_fixer'
9
- require 'hiptest-publisher/diff_displayer'
8
+ require 'hiptest-publisher/formatters/diff_displayer'
10
9
  require 'hiptest-publisher/formatters/reporter'
11
10
  require 'hiptest-publisher/file_writer'
12
- require 'hiptest-publisher/gherkin_adder'
13
11
  require 'hiptest-publisher/handlebars_helper'
14
- require 'hiptest-publisher/items_orderer'
15
12
  require 'hiptest-publisher/options_parser'
16
- require 'hiptest-publisher/parameter_type_adder'
17
- require 'hiptest-publisher/parent_adder'
18
13
  require 'hiptest-publisher/renderer'
19
14
  require 'hiptest-publisher/signature_differ'
20
15
  require 'hiptest-publisher/signature_exporter'
@@ -143,7 +138,8 @@ module Hiptest
143
138
 
144
139
  def export_files
145
140
  @language_config.language_group_configs.each do |language_group_config|
146
- ask_overwrite = language_group_config[:group_name] == 'actionwords'
141
+ next if ['library', 'libraries'].include?(language_group_config[:group_name]) && !@project.has_libraries?
142
+ ask_overwrite = ['actionwords', 'libraries'].include?(language_group_config[:group_name])
147
143
 
148
144
  language_group_config.each_node_rendering_context(@project) do |node_rendering_context|
149
145
  write_node_to_file(
@@ -176,7 +172,7 @@ module Hiptest
176
172
  analyze_project_data
177
173
 
178
174
  current = Hiptest::SignatureExporter.export_actionwords(@project, true)
179
- diff = Hiptest::SignatureDiffer.diff( old, current)
175
+ diff = Hiptest::SignatureDiffer.diff(old, current, library_name: @cli_options.library_name)
180
176
  end
181
177
 
182
178
  def show_actionwords_diff
@@ -189,12 +185,7 @@ module Hiptest
189
185
  return if @project_data_analyzed
190
186
  reporter.with_status_message "Analyzing data" do
191
187
  @language_config = LanguageConfigParser.new(@cli_options)
192
- Hiptest::Nodes::DatatableFixer.add(@project)
193
- Hiptest::Nodes::ParentAdder.add(@project)
194
- Hiptest::Nodes::ParameterTypeAdder.add(@project)
195
- Hiptest::DefaultArgumentAdder.add(@project)
196
- Hiptest::GherkinAdder.add(@project)
197
- Hiptest::ItemsOrderer.add(@project, @cli_options.sort)
188
+ Hiptest::NodeModifiers.add_all(@project, @cli_options.sort)
198
189
  end
199
190
  @project_data_analyzed = true
200
191
  end
@@ -1,5 +1,3 @@
1
-
2
-
3
1
  class Reporter
4
2
  def initialize(listeners = nil)
5
3
  @listeners = listeners || []
@@ -3,6 +3,7 @@ module Hiptest
3
3
  def initialize(project)
4
4
  @project = project
5
5
  @indexed = {}
6
+ @uid_indexed = {}
6
7
  index_actionwords
7
8
  end
8
9
 
@@ -16,16 +17,22 @@ module Hiptest
16
17
  indexed_parameters[param_name] = param.children[:default]
17
18
  end
18
19
 
19
- @indexed[aw_name] = {
20
+ data = {
20
21
  actionword: aw,
21
22
  parameters: indexed_parameters
22
23
  }
23
24
 
25
+ @indexed[aw_name] = data
26
+ @uid_indexed[aw.children[:uid]] = data
24
27
  end
25
28
  end
26
29
 
27
30
  def get_index(name)
28
31
  @indexed[name]
29
32
  end
33
+
34
+ def get_uid_index(uid)
35
+ @uid_indexed[uid]
36
+ end
30
37
  end
31
38
  end
@@ -0,0 +1,34 @@
1
+ module Hiptest
2
+ class ActionwordUidIndexer
3
+ def initialize(project)
4
+ @project = project
5
+ @indexed = {}
6
+ index_actionwords
7
+ end
8
+
9
+ def index_actionwords
10
+ @project.children[:actionwords].children[:actionwords].each do |actionword|
11
+ index_actionword(actionword)
12
+ end
13
+
14
+ @project.children[:libraries].children[:libraries].each do |library|
15
+ library.children[:actionwords].each do |actionword|
16
+ index_actionword(actionword, library: library)
17
+ end
18
+ end
19
+ end
20
+
21
+ def get_index(uid)
22
+ @indexed[uid]
23
+ end
24
+
25
+ private
26
+
27
+ def index_actionword(actionword, library: nil)
28
+ @indexed[actionword.children[:uid]] = {
29
+ actionword: actionword,
30
+ library: library
31
+ }
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,39 @@
1
+ module Hiptest
2
+ module NodeModifiers
3
+ class ActionwordUniqRenamer
4
+ def self.add(project)
5
+ self.new(project).make_uniq_names
6
+ end
7
+
8
+ def initialize(project)
9
+ @project = project
10
+ end
11
+
12
+ def make_uniq_names
13
+ @project.children[:libraries].children[:libraries].each do |library|
14
+ library.children[:actionwords].each do |actionword|
15
+ existing_names = library.children[:actionwords].reject{|aw| aw == actionword}.map(&:uniq_name)
16
+ new_name = find_uniq_name(actionword.children[:name], existing_names)
17
+ actionword.uniq_name = new_name
18
+ end
19
+ end
20
+ end
21
+
22
+ def find_uniq_name(name, existing)
23
+ return name unless existing.include?(name)
24
+
25
+ index = 1
26
+ new_name = ""
27
+
28
+ loop do
29
+ new_name = "#{name} #{index}"
30
+
31
+ break unless existing.include?(new_name)
32
+ index += 1
33
+ end
34
+
35
+ new_name
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,23 @@
1
+ require 'hiptest-publisher/node_modifiers/actionword_uniq_renamer'
2
+ require 'hiptest-publisher/node_modifiers/call_arguments_adder'
3
+ require 'hiptest-publisher/node_modifiers/datatable_fixer'
4
+ require 'hiptest-publisher/node_modifiers/gherkin_adder'
5
+ require 'hiptest-publisher/node_modifiers/items_orderer'
6
+ require 'hiptest-publisher/node_modifiers/parameter_type_adder'
7
+ require 'hiptest-publisher/node_modifiers/parent_adder'
8
+ require 'hiptest-publisher/node_modifiers/uid_call_reference_adder'
9
+
10
+ module Hiptest
11
+ module NodeModifiers
12
+ def self.add_all(project, sort_method = nil)
13
+ DatatableFixer.add(project)
14
+ ParentAdder.add(project)
15
+ UidCallReferencerAdder.add(project)
16
+ ParameterTypeAdder.add(project)
17
+ DefaultArgumentAdder.add(project)
18
+ ActionwordUniqRenamer.add(project)
19
+ GherkinAdder.add(project)
20
+ ItemsOrderer.add(project, sort_method) unless sort_method.nil?
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,52 @@
1
+ require 'hiptest-publisher/indexers/actionword_indexer'
2
+ require 'hiptest-publisher/nodes'
3
+
4
+ module Hiptest
5
+ module NodeModifiers
6
+ class DefaultArgumentAdder
7
+ def self.add(project)
8
+ self.new(project).update_all_calls
9
+ end
10
+
11
+ def initialize(project)
12
+ @project = project
13
+ @indexer = ActionwordIndexer.new(project)
14
+ end
15
+
16
+ def update_all_calls
17
+ update_calls
18
+ update_uid_calls
19
+ end
20
+
21
+ def update_calls
22
+ @project.each_sub_nodes(Hiptest::Nodes::Call) do |call|
23
+ update_call(call, @indexer.get_index(call.children[:actionword]))
24
+ end
25
+ end
26
+
27
+ def update_uid_calls
28
+ @project.each_sub_nodes(Hiptest::Nodes::UIDCall) do |uid_call|
29
+ update_call(uid_call, @indexer.get_uid_index(uid_call.children[:uid]))
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def update_call(call, aw_data)
36
+ return if aw_data.nil?
37
+
38
+ arguments = {}
39
+ call.children[:arguments].each do |arg|
40
+ arguments[arg.children[:name]] = arg.children[:value]
41
+ end
42
+
43
+ call.children[:all_arguments] = aw_data[:parameters].map do |p_name, default_value|
44
+ Hiptest::Nodes::Argument.new(
45
+ p_name,
46
+ arguments.has_key?(p_name) ? arguments[p_name] : default_value
47
+ )
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -1,10 +1,10 @@
1
1
  require 'hiptest-publisher/nodes_walker'
2
2
 
3
3
  module Hiptest
4
- module Nodes
5
- class DatatableFixer < Walker
4
+ module NodeModifiers
5
+ class DatatableFixer < Nodes::Walker
6
6
  def self.add(project)
7
- Hiptest::Nodes::DatatableFixer.new.walk_node(project)
7
+ self.new.walk_node(project)
8
8
  end
9
9
 
10
10
  def walk_scenario(scenario)
@@ -0,0 +1,243 @@
1
+ require 'hiptest-publisher/indexers/actionword_indexer'
2
+ require 'hiptest-publisher/nodes'
3
+
4
+ module Hiptest
5
+ module NodeModifiers
6
+ class GherkinAdder
7
+ def self.add(project)
8
+ self.new(project).update_calls
9
+ end
10
+
11
+ def initialize(project)
12
+ @project = project
13
+ @indexer = ActionwordIndexer.new(project)
14
+ @annotations_counter = AnnotationsCounter.new
15
+
16
+ @special_params = ['__free_text', '__datatable']
17
+ end
18
+
19
+ def update_calls
20
+ @project.each_sub_nodes(Hiptest::Nodes::Scenario, Hiptest::Nodes::Actionword, Hiptest::Nodes::Test, Hiptest::Nodes::Folder) do |item|
21
+ @last_annotation = nil
22
+ item.each_sub_nodes(Hiptest::Nodes::Call, Hiptest::Nodes::UIDCall) do |call|
23
+ set_call_chunks(call)
24
+ call.children[:gherkin_text] ||= "#{text_annotation(call)} #{prettified(call)}"
25
+
26
+ if actionword = get_actionword(call)
27
+ @annotations_counter.increment(actionword, code_annotation(call))
28
+ set_actionwords_chunks(actionword)
29
+
30
+ actionword.children[:gherkin_pattern] ||= pattern(actionword)
31
+ actionword.children[:parameters_ordered_by_pattern] ||= order_parameters_by_pattern(actionword)
32
+ end
33
+ end
34
+ end
35
+
36
+ @annotations_counter.actionwords.each do |actionword|
37
+ actionword.children[:gherkin_annotation] = @annotations_counter.most_used_annotation(actionword) || "Given"
38
+ actionword.children[:gherkin_used_annotations] = @annotations_counter.all_used_annotations(actionword) || ['Given']
39
+ end
40
+ end
41
+
42
+ def annotation(call)
43
+ call.children[:annotation].capitalize if call.children[:annotation]
44
+ end
45
+
46
+ def text_annotation(call)
47
+ annotation(call) || "*"
48
+ end
49
+
50
+ def code_annotation(call)
51
+ call_annotation = annotation(call)
52
+ if call_annotation
53
+ if ["And", "But"].include?(call_annotation)
54
+ call_annotation = @last_annotation || "Given"
55
+ end
56
+ @last_annotation = call_annotation
57
+ end
58
+ end
59
+
60
+ def prettified(call)
61
+ base = call.chunks.map {|chunk| chunk[:value]}.join("\"").strip
62
+ call.extra_inlined_arguments.each do |chunk|
63
+ base += " \"#{chunk[:value]}\""
64
+ end
65
+
66
+ base
67
+ end
68
+
69
+ def set_call_chunks(call)
70
+ all_arguments = all_valued_arguments_for(call)
71
+ inline_parameter_names = []
72
+ extra_inlined_arguments = []
73
+
74
+ call.chunks = []
75
+ call.extra_inlined_arguments = []
76
+
77
+ call_chunks = call.is_a?(Hiptest::Nodes::Call) ? call.children[:actionword].split("\"", -1) : call.children[:actionword_name].split("\"", -1)
78
+
79
+ call_chunks.each_slice(2) do |text, inline_parameter_name|
80
+ call.chunks << {
81
+ value: text,
82
+ is_argument: false
83
+ }
84
+
85
+ if all_arguments.has_key?(inline_parameter_name)
86
+ inline_parameter_names << inline_parameter_name.clone
87
+ value = all_arguments[inline_parameter_name]
88
+ inline_parameter_name.replace(value)
89
+
90
+ call.chunks << {
91
+ value: inline_parameter_name,
92
+ is_argument: true
93
+ }
94
+ else
95
+ call.chunks << {
96
+ value: inline_parameter_name,
97
+ is_argument: false
98
+ } unless inline_parameter_name.nil?
99
+ end
100
+ end
101
+
102
+ missing_parameter_names = all_arguments.keys - inline_parameter_names - @special_params
103
+ call.extra_inlined_arguments = missing_parameter_names.map do |missing_parameter_name|
104
+ {
105
+ value: all_arguments[missing_parameter_name],
106
+ is_argument: true
107
+ }
108
+ end
109
+ end
110
+
111
+ def pattern(actionword)
112
+ patterned = actionword.chunks.map {|chunk| chunk[:value]}.join("\"")
113
+ actionword.extra_inlined_parameters.each do |param|
114
+ patterned += " \"#{param[:value]}\""
115
+ end
116
+
117
+ "^#{patterned.strip}$"
118
+ end
119
+
120
+ def set_actionwords_chunks(actionword)
121
+ name = actionword.uniq_name
122
+ actionword_parameters = evaluated_map(actionword.children[:parameters])
123
+ name_chunks = name.split("\"", -1)
124
+ inline_parameter_names = []
125
+
126
+ actionword.chunks = []
127
+ actionword.extra_inlined_parameters = []
128
+
129
+ name_chunks.each_slice(2) do |text, inline_parameter_name|
130
+ actionword.chunks << {
131
+ value: text.gsub(/[.|()\\.+*?\[\]{}^$]/) { |c| "\\#{c}" },
132
+ is_parameter: false
133
+ }
134
+
135
+ inline_parameter_names << inline_parameter_name if inline_parameter_name
136
+ if actionword_parameters.has_key?(inline_parameter_name)
137
+ actionword.chunks << {
138
+ value: "(.*)",
139
+ name: inline_parameter_name,
140
+ is_parameter: true
141
+ }
142
+ else
143
+ actionword.chunks << {
144
+ value: inline_parameter_name,
145
+ is_parameter: false
146
+ } if inline_parameter_name
147
+ end
148
+ end
149
+ missing_parameter_names = actionword_parameters.keys - inline_parameter_names - @special_params
150
+
151
+ missing_parameter_names.each do |missing_parameter_name|
152
+ actionword.extra_inlined_parameters << {
153
+ value: "(.*)",
154
+ name: missing_parameter_name,
155
+ is_parameter: true
156
+ }
157
+ end
158
+ end
159
+
160
+ def order_parameters_by_pattern(actionword)
161
+ inline_parameter_names = actionword.children[:name].scan(/\"(.*?)\"/).flatten
162
+ actionword_parameters = {}
163
+ actionword.children[:parameters].map {|p| actionword_parameters[p.children[:name]] = p}
164
+
165
+ missing_parameter_names = actionword_parameters.keys - inline_parameter_names - @special_params
166
+ [inline_parameter_names, missing_parameter_names, @special_params].flatten.map do |name|
167
+ actionword_parameters[name]
168
+ end.compact
169
+ end
170
+
171
+ def all_valued_arguments_for(call)
172
+ evaluated_call_arguments = evaluated_map(call.children[:arguments])
173
+ evaluated_actionword_parameters = evaluated_map(get_actionword_parameters(call))
174
+ names = evaluated_actionword_parameters.keys
175
+
176
+ hash_array = names.map { |name|
177
+ value = evaluated_call_arguments[name] || evaluated_actionword_parameters[name] || ""
178
+ [name, value]
179
+ }
180
+ Hash[hash_array]
181
+ end
182
+
183
+ def get_actionword_parameters(call)
184
+ actionword = get_actionword(call)
185
+ actionword && actionword.children[:parameters] || []
186
+ end
187
+
188
+ def get_actionword(call)
189
+
190
+ actionword = call.is_a?(Hiptest::Nodes::UIDCall) ? @indexer.get_uid_index(call.children[:uid]) : @indexer.get_index(call.children[:actionword])
191
+
192
+ actionword && actionword[:actionword] || nil
193
+ end
194
+
195
+ def evaluated_map(named_values)
196
+ hash_array = named_values.map do |named_value|
197
+ name = named_value.children[:name]
198
+ value = evaluate(named_value.children[:value] || named_value.children[:default])
199
+ [name, value]
200
+ end
201
+ Hash[hash_array]
202
+ end
203
+
204
+ def evaluate(value)
205
+ if value.nil?
206
+ nil
207
+ elsif Hiptest::Nodes::Variable === value
208
+ "<#{value.children[:name]}>"
209
+ elsif value.children[:chunks]
210
+ value.children[:chunks].map {|chunk| evaluate(chunk) }.join('')
211
+ elsif value.children[:value]
212
+ value.children[:value]
213
+ else
214
+ nil
215
+ end
216
+ end
217
+ end
218
+
219
+ class AnnotationsCounter
220
+ def initialize
221
+ @counts_by_actionword = Hash.new {|counts, actionword| counts[actionword] = Hash.new(0) }
222
+ end
223
+
224
+ def actionwords
225
+ @counts_by_actionword.keys
226
+ end
227
+
228
+ def increment(actionword, annotation)
229
+ counts = @counts_by_actionword[actionword]
230
+ counts[annotation] += 1 if annotation
231
+ end
232
+
233
+ def most_used_annotation(actionword)
234
+ max = @counts_by_actionword[actionword].values.max
235
+ @counts_by_actionword[actionword].key(max)
236
+ end
237
+
238
+ def all_used_annotations(actionword)
239
+ @counts_by_actionword[actionword].keys
240
+ end
241
+ end
242
+ end
243
+ end