cornucopia 0.1.12

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 (107) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +51 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +16 -0
  6. data/LICENSE.TXT +22 -0
  7. data/README.md +341 -0
  8. data/Rakefile +18 -0
  9. data/cornucopia.gemspec +39 -0
  10. data/lib/cornucopia.rb +18 -0
  11. data/lib/cornucopia/capybara/finder_diagnostics.rb +536 -0
  12. data/lib/cornucopia/capybara/finder_extensions.rb +89 -0
  13. data/lib/cornucopia/capybara/install_finder_extensions.rb +105 -0
  14. data/lib/cornucopia/capybara/install_matcher_extensions.rb +39 -0
  15. data/lib/cornucopia/capybara/matcher_extensions.rb +83 -0
  16. data/lib/cornucopia/capybara/page_diagnostics.rb +228 -0
  17. data/lib/cornucopia/cucumber_hooks.rb +38 -0
  18. data/lib/cornucopia/factory_girl/dynamic_association.rb +14 -0
  19. data/lib/cornucopia/rspec_hooks.rb +37 -0
  20. data/lib/cornucopia/site_prism/element_extensions.rb +273 -0
  21. data/lib/cornucopia/site_prism/install_element_extensions.rb +23 -0
  22. data/lib/cornucopia/site_prism/page_application.rb +126 -0
  23. data/lib/cornucopia/source_files/collapse.gif +0 -0
  24. data/lib/cornucopia/source_files/cornucopia.css +162 -0
  25. data/lib/cornucopia/source_files/expand.gif +0 -0
  26. data/lib/cornucopia/source_files/index_base.html +10 -0
  27. data/lib/cornucopia/source_files/index_contents.html +2 -0
  28. data/lib/cornucopia/source_files/more_info.js +87 -0
  29. data/lib/cornucopia/source_files/report_base.html +10 -0
  30. data/lib/cornucopia/source_files/report_contents.html +3 -0
  31. data/lib/cornucopia/spinach_hooks.rb +51 -0
  32. data/lib/cornucopia/util/configuration.rb +493 -0
  33. data/lib/cornucopia/util/configured_report.rb +520 -0
  34. data/lib/cornucopia/util/file_asset.rb +46 -0
  35. data/lib/cornucopia/util/generic_settings.rb +37 -0
  36. data/lib/cornucopia/util/log_capture.rb +97 -0
  37. data/lib/cornucopia/util/pretty_formatter.rb +580 -0
  38. data/lib/cornucopia/util/report_builder.rb +474 -0
  39. data/lib/cornucopia/util/report_formatters.rb +11 -0
  40. data/lib/cornucopia/util/report_table.rb +195 -0
  41. data/lib/cornucopia/version.rb +3 -0
  42. data/lib/tasks/cornucopia_tasks.rake +4 -0
  43. data/spec/dummy/README.rdoc +28 -0
  44. data/spec/dummy/Rakefile +6 -0
  45. data/spec/dummy/app/assets/images/.keep +0 -0
  46. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  47. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  48. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  49. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  50. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  51. data/spec/dummy/app/mailers/.keep +0 -0
  52. data/spec/dummy/app/models/.keep +0 -0
  53. data/spec/dummy/app/models/concerns/.keep +0 -0
  54. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  55. data/spec/dummy/bin/bundle +3 -0
  56. data/spec/dummy/bin/rails +4 -0
  57. data/spec/dummy/bin/rake +4 -0
  58. data/spec/dummy/config.ru +4 -0
  59. data/spec/dummy/config/application.rb +27 -0
  60. data/spec/dummy/config/boot.rb +5 -0
  61. data/spec/dummy/config/cucumber.yml +8 -0
  62. data/spec/dummy/config/database.yml +37 -0
  63. data/spec/dummy/config/environment.rb +5 -0
  64. data/spec/dummy/config/environments/development.rb +29 -0
  65. data/spec/dummy/config/environments/production.rb +80 -0
  66. data/spec/dummy/config/environments/test.rb +36 -0
  67. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  68. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  69. data/spec/dummy/config/initializers/inflections.rb +16 -0
  70. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  71. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  72. data/spec/dummy/config/initializers/session_store.rb +3 -0
  73. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  74. data/spec/dummy/config/locales/en.yml +23 -0
  75. data/spec/dummy/config/routes.rb +56 -0
  76. data/spec/dummy/db/schema.rb +16 -0
  77. data/spec/dummy/features/support/env.rb +66 -0
  78. data/spec/dummy/lib/assets/.keep +0 -0
  79. data/spec/dummy/lib/tasks/cucumber.rake +65 -0
  80. data/spec/dummy/public/404.html +58 -0
  81. data/spec/dummy/public/422.html +58 -0
  82. data/spec/dummy/public/500.html +57 -0
  83. data/spec/dummy/public/favicon.ico +0 -0
  84. data/spec/dummy/script/cucumber +10 -0
  85. data/spec/fixtures/sample_page.html +150 -0
  86. data/spec/lib/capybara/finder_diagnostics_spec.rb +517 -0
  87. data/spec/lib/capybara/finder_extensions_spec.rb +328 -0
  88. data/spec/lib/capybara/page_diagnostics_spec.rb +277 -0
  89. data/spec/lib/site_prism/element_extensions_spec.rb +290 -0
  90. data/spec/lib/site_prism/page_application_spec.rb +81 -0
  91. data/spec/lib/util/configuration_spec.rb +254 -0
  92. data/spec/lib/util/configured_report_spec.rb +1058 -0
  93. data/spec/lib/util/file_asset_spec.rb +86 -0
  94. data/spec/lib/util/generic_settings_spec.rb +48 -0
  95. data/spec/lib/util/log_capture_spec.rb +151 -0
  96. data/spec/lib/util/pretty_formatter_spec.rb +694 -0
  97. data/spec/lib/util/report_builder_spec.rb +983 -0
  98. data/spec/lib/util/report_formatters_spec.rb +13 -0
  99. data/spec/lib/util/report_table_exception_spec.rb +21 -0
  100. data/spec/lib/util/report_table_spec.rb +319 -0
  101. data/spec/pages/cornucopia_report_app.rb +10 -0
  102. data/spec/pages/google/email_page.rb +22 -0
  103. data/spec/pages/google/login_page.rb +25 -0
  104. data/spec/rails_helper.rb +43 -0
  105. data/spec/sample_report.rb +45 -0
  106. data/spec/spec_helper.rb +81 -0
  107. metadata +410 -0
@@ -0,0 +1,520 @@
1
+ require ::File.expand_path('report_builder', File.dirname(__FILE__))
2
+ require ::File.expand_path('report_table', File.dirname(__FILE__))
3
+ require ::File.expand_path('log_capture', File.dirname(__FILE__))
4
+ require ::File.expand_path('../capybara/page_diagnostics', File.dirname(__FILE__))
5
+
6
+ module Cornucopia
7
+ module Util
8
+ class ConfiguredReport
9
+ # ConfiguredReport outputs an error report based on symbol based configurations
10
+ #
11
+ # The configurations are as follows:
12
+ # min_fields
13
+ # more_info_fields
14
+ # expand_fields
15
+ # expand_inline_fields
16
+ # exclude_fields
17
+ # leaf_options
18
+ #
19
+ # min_field
20
+ # This is a list of the fields which are to be output at the top of the report
21
+ # such that they are always visible.
22
+ # Items in the min list which cannot be found will output an error.
23
+ #
24
+ # If any options are provided in a field that is a non-expanded leaf node, those options will
25
+ # be used instead of the leaf_options if any.
26
+ #
27
+ # more_info_fields
28
+ # This is a list of the fields which are to be output below the min fields
29
+ # in a section that is initially hidden. The user can expand these values
30
+ # If/when they need to.
31
+ # Items in the more info list which cannot be found will output an error.
32
+ #
33
+ # If any options are provided in a field that is a non-expanded leaf node, those options will
34
+ # be used instead of the leaf_options if any.
35
+ #
36
+ # expand_fields
37
+ # This is a list of the fields which are to be expanded when they are encountered.
38
+ # Expanded fields are shown in a sub-table of values so that the instance variables
39
+ # are then each output.
40
+ # items which are to be expanded may be explicitly or implicitly exported.
41
+ # items which are not encountered but are in the expand list will be ignored.
42
+ #
43
+ # If any options are provided here, these options will be applied to all expanded items which
44
+ # are leaf nodes that are not expanded.
45
+ #
46
+ # expand_inline_fields
47
+ # This is a list of the fields which are to be expanded, but unlike expanded fields
48
+ # when these items are expanded, they will be placed at the same level as the current
49
+ # items rather than in a sub-table.
50
+ #
51
+ # If any options are provided here, these options will be applied to all expanded items which
52
+ # are leaf nodes that are not expanded. If a field is specified in both expand and
53
+ # expand_inline, the options for expand will take precedence over expand_inline.
54
+ #
55
+ # exclude_fields
56
+ # This is a list of the fields which are not to be output when they are encountered.
57
+ # There are many implicit ways to output a field (such as the expanded fields).
58
+ # If a field is to be implicityly exported, it will not be exported if it is in this
59
+ # list. A field can always be explicitly exported. Items not encountered but
60
+ # in the exclude list will be ignored.
61
+ #
62
+ # If any options are provided here, they will be ignored.
63
+ #
64
+ # leaf_options
65
+ # When a leaf node is output, this set is checked to see if there are any options to be passed into the
66
+ # Cornucopia::Util::ReportTable.write_stats function.
67
+ # leaf_options is only useful if you provide options.
68
+ #
69
+ # Unlike the other nodes, leaf_options does not use the field names to specify a full path.
70
+ # Instead, the leaf options allows an arry of values in the report_element field to specify a list
71
+ # of leaf fields which all have the same options (if not overridden by the min or more_info lists).
72
+ #
73
+ # field names follow a set pattern:
74
+ # <object_name>__<function_property_or_hash_name>
75
+ #
76
+ # You can have as many following __<function_or_property_name> values as you need.
77
+ #
78
+ # OR
79
+ #
80
+ # { report_element: <field name>, report_options: {<options hash>} }
81
+ #
82
+ # Examples:
83
+ # self.exception.backtrace would be specified as: :self__exception__backtrace
84
+ # self.my_hash[:my_key] would be specified as: :self__my_hash__my_key
85
+ # self.to_s would be specified as: :self__to_s
86
+ # self.as_text_area may be specified as: { report_element: :self, report_options: { prevent_shrink: true } }
87
+ #
88
+ # There are a handful of special conditions:
89
+ # if the last_line is to_s, the label that is output will not be to_s, but the previous item level
90
+ #
91
+ # :logs
92
+ # This will output the logs using Cornucopia::Util::LogCapture.capture_logs
93
+ # Unlike normal items, if there are no logs to export, this will not generate an error.
94
+ #
95
+ # :capybara_page_diagnostics
96
+ # This will output Capybara infomration using
97
+ # Cornucopia::Capybara::Diagnostics.output_page_detail_section.
98
+ # NOTE: This option requres a parameter be passed into the report_options for :diagnostics_name
99
+ # Unlike normal items, if Capybara is not being used, this will not generate an error.
100
+
101
+ def initialize(options = {})
102
+ @min_fields = []
103
+ @more_info_fields = []
104
+ @expand_fields = []
105
+ @expand_inline_fields = []
106
+ @exclude_fields = []
107
+ @leaf_options = []
108
+ @report_objects = {}
109
+
110
+ self.min_fields = options[:min_fields]
111
+ self.more_info_fields = options[:more_info_fields]
112
+ self.expand_fields = options[:expand_fields]
113
+ self.expand_inline_fields = options[:expand_inline_fields]
114
+ self.exclude_fields = options[:exclude_fields]
115
+ self.leaf_options = options[:leaf_options]
116
+ @report = options[:report]
117
+ end
118
+
119
+ def min_fields=(value)
120
+ @min_fields = split_field_symbols(value)
121
+ end
122
+
123
+ def more_info_fields=(value)
124
+ @more_info_fields = split_field_symbols(value)
125
+ end
126
+
127
+ def expand_fields=(value)
128
+ @expand_fields = split_field_symbols(value)
129
+ end
130
+
131
+ def expand_inline_fields=(value)
132
+ @expand_inline_fields = split_field_symbols(value)
133
+ end
134
+
135
+ def exclude_fields=(value)
136
+ @exclude_fields = split_field_symbols(value)
137
+ end
138
+
139
+ def leaf_options=(value)
140
+ @leaf_options = split_field_symbols(value)
141
+ end
142
+
143
+ def add_report_objects(report_object_hash)
144
+ @report_objects.merge! report_object_hash
145
+ end
146
+
147
+ # This function generates the report.
148
+ #
149
+ # Options:
150
+ # report_table - If the report is to be run inside an already existing table, the table
151
+ # to output the values into.
152
+ # nested_table - If the report is running inside an existing table already, the table
153
+ # it is running in.
154
+ # NOTE: This value may not be
155
+ # diagnostics_name - The text to output when outputing capybara diagnostics if it is not expanded in-line.
156
+ def generate_report(report, options = {}, &block)
157
+ @report = (report ||= Cornucopia::Util::ReportBuilder.current_report)
158
+
159
+ options_report_table = options.delete(:report_table)
160
+ [@min_fields, @more_info_fields].each do |export_field_list|
161
+ if export_field_list
162
+ table_pre = nil
163
+ table_post = nil
164
+
165
+ if @min_fields != export_field_list && !options_report_table
166
+ options_report_table = nil
167
+
168
+ table_pre = "<div class=\"cornucopia-show-hide-section\">\n"
169
+ table_pre << " <div class=\"cornucopia-table\">\n"
170
+ table_pre << " <div class=\"cornucopia-row\">\n"
171
+ table_pre << " <div class=\"cornucopia-cell-data\">\n"
172
+ table_pre << " <a class =\"cornucopia-additional-details\" href=\"#\">More Details...</a>\n"
173
+ table_pre << " </div>\n"
174
+ table_pre << " </div>\n"
175
+ table_pre << " </div>\n"
176
+ table_pre << " <div class=\"cornucopia-additional-details hidden\">\n"
177
+ table_pre.html_safe
178
+ table_post = " </div>\n"
179
+ table_post << "</div>\n"
180
+ table_post.html_safe
181
+ end
182
+
183
+ report.within_table(table_prefix: table_pre,
184
+ table_postfix: table_post,
185
+ report_table: options_report_table,
186
+ nested_table: options.delete(:nested_table),
187
+ nested_table_label: options.delete(:nested_table_label),
188
+ not_a_table: table_pre,
189
+ suppress_blank_table: table_pre) do |outer_report_table|
190
+ Cornucopia::Util::ReportTable.new(
191
+ report_table: table_pre ? nil : outer_report_table,
192
+ nested_table: outer_report_table,
193
+ suppress_blank_table: table_pre) do |report_table|
194
+ export_field_list.each do |export_field|
195
+ if @report_objects[export_field[:report_element][0]] ||
196
+ export_field[:report_element][0] == :capybara_page_diagnostics ||
197
+ export_field[:report_element][0] == :logs
198
+ export_field_record(export_field,
199
+ @report_objects[export_field[:report_element][0]],
200
+ export_field[:report_element][0],
201
+ report_table,
202
+ 0,
203
+ options.merge(report_object_set: true))
204
+ end
205
+ end
206
+
207
+ if block
208
+ if @min_fields != export_field_list
209
+ block.yield report, report_table
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
215
+ end
216
+ end
217
+
218
+ def perform_expansion(export_field, level, sub_vars_report, options, sub_symbol_name, value)
219
+ sub_export_field = { report_element: export_field[:report_element].clone }
220
+ if level == sub_export_field[:report_element].length - 1
221
+ sub_export_field[:report_options] = export_field[:report_options]
222
+ end
223
+
224
+ if level == sub_export_field[:report_element].length - 1 ||
225
+ (level < sub_export_field[:report_element].length &&
226
+ sub_export_field[:report_element][level + 1] != sub_symbol_name.to_sym)
227
+ sub_export_field[:report_element] = sub_export_field[:report_element][0..level]
228
+ sub_export_field[:report_element] << sub_symbol_name.to_sym
229
+ end
230
+
231
+ export_field_record(sub_export_field,
232
+ value,
233
+ sub_symbol_name.to_sym,
234
+ sub_vars_report,
235
+ level + 1,
236
+ options.merge(report_object_set: true, expanded_field: true))
237
+ end
238
+
239
+ def expand_field_object(export_field, expand_object, symbol_name, report_table, level, options = {})
240
+ expand_inline = options.delete(:expand_inline)
241
+
242
+ Cornucopia::Util::ReportTable.new(report_table: expand_inline ? report_table : nil,
243
+ nested_table: report_table,
244
+ nested_table_label: symbol_name,
245
+ suppress_blank_table: true) do |sub_vars_report|
246
+ if expand_object.is_a?(Hash)
247
+ expand_object.each do |sub_symbol_name, value|
248
+ perform_expansion(export_field, level, sub_vars_report, options, sub_symbol_name, value)
249
+ end
250
+ elsif expand_object.respond_to?(:members)
251
+ key_values = expand_object.members
252
+
253
+ key_values.each do |sub_symbol_name|
254
+ perform_expansion(export_field,
255
+ level,
256
+ sub_vars_report,
257
+ options,
258
+ sub_symbol_name,
259
+ expand_object.send(sub_symbol_name))
260
+ end
261
+ elsif expand_object.respond_to?(:each)
262
+ each_index = 0
263
+ expand_object.each do |value|
264
+ perform_expansion(export_field, level, sub_vars_report, options, each_index.to_s, value)
265
+ each_index += 1
266
+ end
267
+ else
268
+ expand_object.instance_variable_names.sort.each do |variable_name|
269
+ var_symbol_name = variable_name.to_s
270
+ while var_symbol_name[0] == "@"
271
+ var_symbol_name = var_symbol_name[1..-1]
272
+ end
273
+
274
+ # if level == sub_export_field[:report_element].length - 1 ||
275
+ # (level < sub_export_field[:report_element].length &&
276
+ # sub_export_field[:report_element][level + 1] != var_symbol_name.to_sym)
277
+ # sub_export_field[:report_options] = nil
278
+ # end
279
+ perform_expansion(export_field,
280
+ level,
281
+ sub_vars_report,
282
+ options,
283
+ var_symbol_name,
284
+ get_instance_variable(expand_object, variable_name, var_symbol_name))
285
+ end
286
+ end
287
+ end
288
+ end
289
+
290
+ def instance_variables_contain(parent_object, variable_name)
291
+ found_name = nil
292
+
293
+ parent_object.instance_variable_names.any? do |instance_variable_name|
294
+ if instance_variable_name.to_sym == variable_name ||
295
+ instance_variable_name.to_sym == "@#{variable_name}".to_sym
296
+ found_name = instance_variable_name
297
+ true
298
+ end
299
+ end
300
+
301
+ found_name
302
+ end
303
+
304
+ def export_field_record(export_field, parent_object, parent_object_name, report_table, level, options = {})
305
+ parent_expanded = options.delete(:expanded_field)
306
+ report_object = nil
307
+
308
+ if (options.delete(:report_object_set))
309
+ report_object = parent_object
310
+ else
311
+ if parent_object.respond_to?(export_field[:report_element][level]) &&
312
+ (!parent_object.methods.include?(export_field[:report_element][level]) ||
313
+ parent_object.method(export_field[:report_element][level]).parameters.empty?)
314
+ report_object = parent_object.send(export_field[:report_element][level])
315
+ elsif parent_object.respond_to?(:[])
316
+ key_value = export_field[:report_element][level]
317
+ if key_value.to_s =~ /^-?[0-9]+$/
318
+ key_value = key_value.to_s.to_i
319
+ end
320
+
321
+ report_object = parent_object.send(:[], key_value)
322
+ else
323
+ instance_variable_name = instance_variables_contain(parent_object, export_field[:report_element][level])
324
+
325
+ if instance_variable_name
326
+ report_object = parent_object.instance_variable_get(instance_variable_name)
327
+ else
328
+ report_object = nil
329
+ print_value = "Could not identify field: #{export_field[:report_element][0..level].join("__")} while exporting #{export_field[:report_element].join("__")}"
330
+
331
+ report_table.write_stats "ERROR", print_value
332
+ end
333
+ end
334
+ end
335
+
336
+ if (level == 0 || !report_object.nil?) &&
337
+ (level > 0 || export_field[:report_element][level] == parent_object_name)
338
+ if level < export_field[:report_element].length - 1
339
+ export_field_record(export_field,
340
+ report_object,
341
+ export_field[:report_element][level],
342
+ report_table,
343
+ level + 1,
344
+ options)
345
+ else
346
+ case export_field[:report_element][level]
347
+ when :logs
348
+ if Cornucopia::Util::Configuration.grab_logs
349
+ Cornucopia::Util::LogCapture.capture_logs report_table
350
+ end
351
+
352
+ when :capybara_page_diagnostics
353
+ Cornucopia::Capybara::PageDiagnostics.dump_details_in_table(@report, report_table)
354
+
355
+ else
356
+ suppress = exclude_variable?(export_field[:report_element][0..-2], export_field[:report_element][-1])
357
+ suppress &&= parent_expanded
358
+
359
+ if !suppress &&
360
+ expand_variable?(export_field[:report_element][0..-2], export_field[:report_element][-1])
361
+ expand_field_object(export_field,
362
+ report_object,
363
+ export_field[:report_element][-1],
364
+ report_table,
365
+ level,
366
+ options.merge({ expand_inline:
367
+ expand_variable_inline?(export_field[:report_element][0..-2],
368
+ export_field[:report_element][-1]) }))
369
+ else
370
+ print_field_object(export_field, report_object, report_table, parent_expanded, options)
371
+ end
372
+ end
373
+ end
374
+ end
375
+ rescue Exception => error
376
+ report_table.write_stats "Configured Report Error", "#{export_field}\nError:\n#{error.to_s}\n#{error.backtrace.join("\n")}"
377
+ end
378
+
379
+ def print_field_object(export_field, report_object, report_table, parent_expanded, options)
380
+ unless parent_expanded &&
381
+ exclude_variable?(export_field[:report_element][0..-2], export_field[:report_element][-1])
382
+ if report_object == false ||
383
+ !(report_object.nil? || (report_object.respond_to?(:empty?) && (report_object.empty? rescue nil)))
384
+ if export_field[:report_element][-1] == :to_s
385
+ print_name = export_field[:report_element][-2]
386
+ else
387
+ print_name = export_field[:report_element][-1]
388
+ end
389
+
390
+ if export_field[:report_element].length >= 2
391
+ if print_name.to_s =~ /^-?[0-9]+$/
392
+ if !parent_expanded ||
393
+ expand_variable_inline?(export_field[:report_element][0..-3], export_field[:report_element][-2])
394
+ print_name = "#{export_field[:report_element][-2]}[#{export_field[:report_element][-1]}]"
395
+ end
396
+ end
397
+ end
398
+
399
+ print_options = export_field[:report_options]
400
+ print_options ||= find_leaf_options(print_name).try(:[], :report_options)
401
+ print_options ||= {}
402
+
403
+ if print_options[:label]
404
+ print_name = print_options[:label]
405
+ end
406
+
407
+ report_table.write_stats print_name, report_object, print_options
408
+ end
409
+ end
410
+ end
411
+
412
+ def find_leaf_options(variable_name)
413
+ found_options = nil
414
+
415
+ if @leaf_options
416
+ @leaf_options.each do |leaf_option|
417
+ if leaf_option[:report_element].include?(variable_name)
418
+ found_options = leaf_option
419
+ break
420
+ end
421
+ end
422
+ end
423
+
424
+ found_options
425
+ end
426
+
427
+ def exclude_variable?(export_field, variable_name)
428
+ find_variable_in_set(@exclude_fields, export_field, variable_name)
429
+ end
430
+
431
+ def expand_variable?(export_field, variable_name)
432
+ find_variable_in_set(@expand_fields, export_field, variable_name) ||
433
+ find_variable_in_set(@expand_inline_fields, export_field, variable_name)
434
+ end
435
+
436
+ def expand_variable_inline?(export_field, variable_name)
437
+ find_variable_in_set(@expand_inline_fields, export_field, variable_name)
438
+ end
439
+
440
+ def find_variable_in_set(variable_set, export_field, variable_name)
441
+ found_item = nil
442
+
443
+ if variable_set
444
+ variable_set.any? do |exclusion_item|
445
+ found_item = nil
446
+
447
+ if exclusion_item[:report_element].length == export_field.length + 1
448
+ found_item = true
449
+
450
+ export_field.each_with_index do |export_name, export_index|
451
+ found_item &&= (exclusion_item[:report_element][export_index] == export_name ||
452
+ exclusion_item[:report_element][export_index] == "*".to_sym)
453
+ end
454
+
455
+ found_item &&= (exclusion_item[:report_element][export_field.length] == variable_name ||
456
+ exclusion_item[:report_element][export_field.length] == "*".to_sym)
457
+
458
+ if found_item
459
+ found_item = exclusion_item
460
+ else
461
+ found_item = nil
462
+ end
463
+ end
464
+
465
+ found_item
466
+ end
467
+ end
468
+
469
+ found_item
470
+ end
471
+
472
+ def split_field_symbols(full_report_element)
473
+ if full_report_element
474
+ full_report_element.map do |full_symbol|
475
+ return_value = {}
476
+
477
+ if full_symbol.is_a?(Hash)
478
+ return_value = full_symbol.clone
479
+ return_value[:report_element] = split_full_field_symbol(return_value[:report_element])
480
+ else
481
+ return_value[:report_element] = split_full_field_symbol(full_symbol)
482
+ end
483
+
484
+ return_value
485
+ end
486
+ else
487
+ []
488
+ end
489
+ end
490
+
491
+ def split_full_field_symbol(full_symbol)
492
+ if full_symbol.is_a?(Array)
493
+ full_symbol
494
+ else
495
+ field_symbols = full_symbol.to_s.split("__")
496
+
497
+ field_symbols.reduce([]) do |array, symbol|
498
+ if (symbol.empty?)
499
+ array << nil
500
+ else
501
+ while (array.length > 0 && array[-1].blank?)
502
+ array.pop
503
+ symbol = "__#{symbol}"
504
+ end
505
+ array << symbol.to_sym
506
+ end
507
+ end
508
+ end
509
+ end
510
+
511
+ def get_instance_variable(the_object, instance_variable, variable_name)
512
+ if the_object.respond_to?(variable_name)
513
+ the_object.send(variable_name)
514
+ else
515
+ the_object.instance_variable_get(instance_variable)
516
+ end
517
+ end
518
+ end
519
+ end
520
+ end