hiptest-publisher-fork 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (498) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +295 -0
  3. data/LICENSE +21 -0
  4. data/README.md +265 -0
  5. data/bin/hiptest-publisher +47 -0
  6. data/config/i18n-tasks.yml +137 -0
  7. data/config/locales/en.yml +250 -0
  8. data/lib/config/behat.conf +44 -0
  9. data/lib/config/behave.conf +40 -0
  10. data/lib/config/csharp-nunit.conf +15 -0
  11. data/lib/config/cucumber-groovy.conf +40 -0
  12. data/lib/config/cucumber-java.conf +24 -0
  13. data/lib/config/cucumber-javascript.conf +23 -0
  14. data/lib/config/cucumber-ruby.conf +22 -0
  15. data/lib/config/cucumber-typescript.conf +41 -0
  16. data/lib/config/cucumber_legacy-groovy.conf +40 -0
  17. data/lib/config/cucumber_legacy-java.conf +24 -0
  18. data/lib/config/cucumber_legacy-typescript.conf +41 -0
  19. data/lib/config/groovy-spock.conf +25 -0
  20. data/lib/config/java-espresso.conf +15 -0
  21. data/lib/config/java-junit.conf +21 -0
  22. data/lib/config/java-testng.conf +15 -0
  23. data/lib/config/javascript-codeceptjs.conf +23 -0
  24. data/lib/config/javascript-jasmine.conf +12 -0
  25. data/lib/config/javascript-mocha.conf +12 -0
  26. data/lib/config/javascript-protractor.conf +12 -0
  27. data/lib/config/javascript-qunit.conf +12 -0
  28. data/lib/config/jbehave.conf +24 -0
  29. data/lib/config/php-phpunit.conf +14 -0
  30. data/lib/config/python-unittest.conf +13 -0
  31. data/lib/config/robotframework.conf +13 -0
  32. data/lib/config/ruby-minitest.conf +11 -0
  33. data/lib/config/ruby-rspec.conf +11 -0
  34. data/lib/config/seleniumide.conf +12 -0
  35. data/lib/config/specflow.conf +25 -0
  36. data/lib/config/swift-xctest.conf +18 -0
  37. data/lib/hiptest-publisher/cli_options_checker.rb +270 -0
  38. data/lib/hiptest-publisher/client.rb +326 -0
  39. data/lib/hiptest-publisher/export_cache.rb +85 -0
  40. data/lib/hiptest-publisher/file_writer.rb +30 -0
  41. data/lib/hiptest-publisher/formatters/console_formatter.rb +101 -0
  42. data/lib/hiptest-publisher/formatters/diff_displayer.rb +173 -0
  43. data/lib/hiptest-publisher/formatters/reporter.rb +74 -0
  44. data/lib/hiptest-publisher/handlebars_helper.rb +314 -0
  45. data/lib/hiptest-publisher/i18n.rb +5 -0
  46. data/lib/hiptest-publisher/indexers/actionword_indexer.rb +32 -0
  47. data/lib/hiptest-publisher/indexers/library_actionword_indexer.rb +32 -0
  48. data/lib/hiptest-publisher/node_modifiers/actionword_uniq_renamer.rb +39 -0
  49. data/lib/hiptest-publisher/node_modifiers/add_all.rb +21 -0
  50. data/lib/hiptest-publisher/node_modifiers/call_arguments_adder.rb +46 -0
  51. data/lib/hiptest-publisher/node_modifiers/datatable_fixer.rb +32 -0
  52. data/lib/hiptest-publisher/node_modifiers/gherkin_adder.rb +252 -0
  53. data/lib/hiptest-publisher/node_modifiers/items_orderer.rb +33 -0
  54. data/lib/hiptest-publisher/node_modifiers/parameter_type_adder.rb +141 -0
  55. data/lib/hiptest-publisher/node_modifiers/parent_adder.rb +18 -0
  56. data/lib/hiptest-publisher/nodes.rb +601 -0
  57. data/lib/hiptest-publisher/nodes_walker.rb +34 -0
  58. data/lib/hiptest-publisher/options_parser.rb +826 -0
  59. data/lib/hiptest-publisher/project_grapher.rb +94 -0
  60. data/lib/hiptest-publisher/render_context_maker.rb +194 -0
  61. data/lib/hiptest-publisher/renderer.rb +52 -0
  62. data/lib/hiptest-publisher/renderer_addons/behave_addon.rb +23 -0
  63. data/lib/hiptest-publisher/renderer_addons/gherkin_addon.rb +59 -0
  64. data/lib/hiptest-publisher/renderer_addons/groovy_spock_addon.rb +34 -0
  65. data/lib/hiptest-publisher/renderer_addons/robot_framework_addon.rb +42 -0
  66. data/lib/hiptest-publisher/renderer_addons.rb +4 -0
  67. data/lib/hiptest-publisher/signature_differ.rb +105 -0
  68. data/lib/hiptest-publisher/signature_exporter.rb +56 -0
  69. data/lib/hiptest-publisher/string.rb +76 -0
  70. data/lib/hiptest-publisher/utils.rb +39 -0
  71. data/lib/hiptest-publisher/version_checker.rb +41 -0
  72. data/lib/hiptest-publisher/xml_parser.rb +407 -0
  73. data/lib/hiptest-publisher.rb +261 -0
  74. data/lib/templates/behat/actionword.hbs +8 -0
  75. data/lib/templates/behat/actionwords/parameter.hbs +1 -0
  76. data/lib/templates/behat/actionwords.hbs +16 -0
  77. data/lib/templates/behat/library.hbs +16 -0
  78. data/lib/templates/behat/libraryactionword.hbs +8 -0
  79. data/lib/templates/behat/parameter.hbs +1 -0
  80. data/lib/templates/behave/actionword.hbs +4 -0
  81. data/lib/templates/behave/actionwords.hbs +12 -0
  82. data/lib/templates/behave/library.hbs +7 -0
  83. data/lib/templates/behave/libraryactionword.hbs +4 -0
  84. data/lib/templates/behave/nullliteral.hbs +1 -0
  85. data/lib/templates/common/_gherkin_pattern.hbs +1 -0
  86. data/lib/templates/common/_gherkin_typed_pattern.hbs +1 -0
  87. data/lib/templates/common/booleanliteral.hbs +1 -0
  88. data/lib/templates/common/dataset.hbs +0 -0
  89. data/lib/templates/common/datatable.hbs +3 -0
  90. data/lib/templates/common/empty.hbs +0 -0
  91. data/lib/templates/common/nullliteral.hbs +1 -0
  92. data/lib/templates/common/numericliteral.hbs +1 -0
  93. data/lib/templates/common/stringliteral.hbs +1 -0
  94. data/lib/templates/common/symbol.hbs +1 -0
  95. data/lib/templates/common/unaryexpression.hbs +1 -0
  96. data/lib/templates/common/variable.hbs +1 -0
  97. data/lib/templates/csharp/_body.hbs +5 -0
  98. data/lib/templates/csharp/_item_as_function.hbs +8 -0
  99. data/lib/templates/csharp/_scenario.hbs +8 -0
  100. data/lib/templates/csharp/actionword.hbs +1 -0
  101. data/lib/templates/csharp/actionwords.hbs +10 -0
  102. data/lib/templates/csharp/argument.hbs +1 -0
  103. data/lib/templates/csharp/assign.hbs +1 -0
  104. data/lib/templates/csharp/binaryexpression.hbs +1 -0
  105. data/lib/templates/csharp/call.hbs +2 -0
  106. data/lib/templates/csharp/dataset.hbs +4 -0
  107. data/lib/templates/csharp/dict.hbs +1 -0
  108. data/lib/templates/csharp/field.hbs +1 -0
  109. data/lib/templates/csharp/folder.hbs +22 -0
  110. data/lib/templates/csharp/ifthen.hbs +7 -0
  111. data/lib/templates/csharp/index.hbs +1 -0
  112. data/lib/templates/csharp/list.hbs +1 -0
  113. data/lib/templates/csharp/nullliteral.hbs +1 -0
  114. data/lib/templates/csharp/parameter.hbs +1 -0
  115. data/lib/templates/csharp/parenthesis.hbs +1 -0
  116. data/lib/templates/csharp/property.hbs +1 -0
  117. data/lib/templates/csharp/scenario.hbs +1 -0
  118. data/lib/templates/csharp/scenarios.hbs +20 -0
  119. data/lib/templates/csharp/single_scenario.hbs +16 -0
  120. data/lib/templates/csharp/single_test.hbs +15 -0
  121. data/lib/templates/csharp/step.hbs +1 -0
  122. data/lib/templates/csharp/stringliteral.hbs +1 -0
  123. data/lib/templates/csharp/tag.hbs +1 -0
  124. data/lib/templates/csharp/template.hbs +1 -0
  125. data/lib/templates/csharp/test.hbs +1 -0
  126. data/lib/templates/csharp/tests.hbs +15 -0
  127. data/lib/templates/csharp/variable.hbs +1 -0
  128. data/lib/templates/csharp/while.hbs +4 -0
  129. data/lib/templates/cucumber/actionword.hbs +5 -0
  130. data/lib/templates/cucumber/actionwords.hbs +5 -0
  131. data/lib/templates/cucumber/groovy/step-definitions/_gherkin_pattern.hbs +1 -0
  132. data/lib/templates/cucumber/groovy/step-definitions/actionword.hbs +5 -0
  133. data/lib/templates/cucumber/groovy/step-definitions/actionwords.hbs +11 -0
  134. data/lib/templates/cucumber/groovy/step-definitions/library.hbs +11 -0
  135. data/lib/templates/cucumber/groovy/step-definitions/libraryactionword.hbs +5 -0
  136. data/lib/templates/cucumber/groovy/step-definitions/parameter.hbs +1 -0
  137. data/lib/templates/cucumber/java/actionword.hbs +6 -0
  138. data/lib/templates/cucumber/java/actionwords/parameter.hbs +1 -0
  139. data/lib/templates/cucumber/java/actionwords.hbs +12 -0
  140. data/lib/templates/cucumber/java/parameter.hbs +1 -0
  141. data/lib/templates/cucumber/javascript/_after_hook.hbs +4 -0
  142. data/lib/templates/cucumber/javascript/_before_hook.hbs +4 -0
  143. data/lib/templates/cucumber/javascript/actionword.hbs +6 -0
  144. data/lib/templates/cucumber/javascript/actionwords.hbs +8 -0
  145. data/lib/templates/cucumber/parameter.hbs +1 -0
  146. data/lib/templates/cucumber/typescript/_after_hook.hbs +4 -0
  147. data/lib/templates/cucumber/typescript/_before_hook.hbs +4 -0
  148. data/lib/templates/cucumber/typescript/actionword.hbs +5 -0
  149. data/lib/templates/cucumber/typescript/actionwords.hbs +10 -0
  150. data/lib/templates/cucumber/typescript/library.hbs +12 -0
  151. data/lib/templates/cucumber/typescript/libraryactionword.hbs +5 -0
  152. data/lib/templates/cucumber_legacy/groovy/step-definitions/actionword.hbs +5 -0
  153. data/lib/templates/cucumber_legacy/groovy/step-definitions/actionwords.hbs +10 -0
  154. data/lib/templates/cucumber_legacy/groovy/step-definitions/library.hbs +10 -0
  155. data/lib/templates/cucumber_legacy/groovy/step-definitions/libraryactionword.hbs +5 -0
  156. data/lib/templates/cucumber_legacy/java/actionword.hbs +6 -0
  157. data/lib/templates/cucumber_legacy/java/actionwords.hbs +12 -0
  158. data/lib/templates/cucumber_legacy/typescript/actionword.hbs +5 -0
  159. data/lib/templates/cucumber_legacy/typescript/libraryactionword.hbs +5 -0
  160. data/lib/templates/gherkin/_call.hbs +5 -0
  161. data/lib/templates/gherkin/_gherkin_text.hbs +1 -0
  162. data/lib/templates/gherkin/_scenario.hbs +18 -0
  163. data/lib/templates/gherkin/_scenario_outline_title.hbs +1 -0
  164. data/lib/templates/gherkin/argument.hbs +1 -0
  165. data/lib/templates/gherkin/call.hbs +1 -0
  166. data/lib/templates/gherkin/dataset.hbs +1 -0
  167. data/lib/templates/gherkin/datatable.hbs +2 -0
  168. data/lib/templates/gherkin/folder.hbs +10 -0
  169. data/lib/templates/gherkin/inlined_uids/_scenario_outline_title.hbs +1 -0
  170. data/lib/templates/gherkin/java/single_scenario.hbs +1 -0
  171. data/lib/templates/gherkin/parameter.hbs +1 -0
  172. data/lib/templates/gherkin/scenarios.hbs +3 -0
  173. data/lib/templates/gherkin/single_scenario.hbs +1 -0
  174. data/lib/templates/gherkin/single_test.hbs +3 -0
  175. data/lib/templates/gherkin/step.hbs +1 -0
  176. data/lib/templates/gherkin/stringliteral.hbs +1 -0
  177. data/lib/templates/gherkin/tag.hbs +1 -0
  178. data/lib/templates/gherkin/template.hbs +1 -0
  179. data/lib/templates/groovy/_body.hbs +8 -0
  180. data/lib/templates/groovy/_desc.hbs +5 -0
  181. data/lib/templates/groovy/_scenario.hbs +10 -0
  182. data/lib/templates/groovy/_steps.hbs +4 -0
  183. data/lib/templates/groovy/_test.hbs +4 -0
  184. data/lib/templates/groovy/actionword.hbs +2 -0
  185. data/lib/templates/groovy/actionwords.hbs +7 -0
  186. data/lib/templates/groovy/assign.hbs +1 -0
  187. data/lib/templates/groovy/call.hbs +2 -0
  188. data/lib/templates/groovy/dataset.hbs +1 -0
  189. data/lib/templates/groovy/datatable.hbs +2 -0
  190. data/lib/templates/groovy/dict.hbs +1 -0
  191. data/lib/templates/groovy/folder.hbs +18 -0
  192. data/lib/templates/groovy/index.hbs +1 -0
  193. data/lib/templates/groovy/libraries.hbs +9 -0
  194. data/lib/templates/groovy/library.hbs +8 -0
  195. data/lib/templates/groovy/libraryactionword.hbs +2 -0
  196. data/lib/templates/groovy/list.hbs +1 -0
  197. data/lib/templates/groovy/nullliteral.hbs +1 -0
  198. data/lib/templates/groovy/parameter.hbs +1 -0
  199. data/lib/templates/groovy/property.hbs +1 -0
  200. data/lib/templates/groovy/scenario.hbs +1 -0
  201. data/lib/templates/groovy/scenarios.hbs +10 -0
  202. data/lib/templates/groovy/single_scenario.hbs +9 -0
  203. data/lib/templates/groovy/single_test.hbs +10 -0
  204. data/lib/templates/groovy/template.hbs +1 -0
  205. data/lib/templates/groovy/test.hbs +1 -0
  206. data/lib/templates/groovy/tests.hbs +10 -0
  207. data/lib/templates/java/_body.hbs +5 -0
  208. data/lib/templates/java/_item_as_function.hbs +8 -0
  209. data/lib/templates/java/_scenario.hbs +7 -0
  210. data/lib/templates/java/actionword.hbs +1 -0
  211. data/lib/templates/java/actionwords.hbs +8 -0
  212. data/lib/templates/java/argument.hbs +1 -0
  213. data/lib/templates/java/assign.hbs +1 -0
  214. data/lib/templates/java/binaryexpression.hbs +1 -0
  215. data/lib/templates/java/call.hbs +2 -0
  216. data/lib/templates/java/dataset.hbs +3 -0
  217. data/lib/templates/java/dict.hbs +1 -0
  218. data/lib/templates/java/espresso/_scenario.hbs +8 -0
  219. data/lib/templates/java/espresso/dataset.hbs +4 -0
  220. data/lib/templates/java/espresso/folder.hbs +29 -0
  221. data/lib/templates/java/espresso/scenarios.hbs +23 -0
  222. data/lib/templates/java/espresso/single_scenario.hbs +24 -0
  223. data/lib/templates/java/espresso/single_test.hbs +22 -0
  224. data/lib/templates/java/espresso/tests.hbs +23 -0
  225. data/lib/templates/java/field.hbs +1 -0
  226. data/lib/templates/java/folder.hbs +18 -0
  227. data/lib/templates/java/ifthen.hbs +7 -0
  228. data/lib/templates/java/index.hbs +1 -0
  229. data/lib/templates/java/libraries.hbs +9 -0
  230. data/lib/templates/java/library.hbs +7 -0
  231. data/lib/templates/java/libraryactionword.hbs +1 -0
  232. data/lib/templates/java/list.hbs +1 -0
  233. data/lib/templates/java/nullliteral.hbs +1 -0
  234. data/lib/templates/java/parameter.hbs +1 -0
  235. data/lib/templates/java/parenthesis.hbs +1 -0
  236. data/lib/templates/java/property.hbs +1 -0
  237. data/lib/templates/java/scenario.hbs +1 -0
  238. data/lib/templates/java/scenarios.hbs +11 -0
  239. data/lib/templates/java/single_scenario.hbs +12 -0
  240. data/lib/templates/java/single_test.hbs +11 -0
  241. data/lib/templates/java/step.hbs +1 -0
  242. data/lib/templates/java/stringliteral.hbs +1 -0
  243. data/lib/templates/java/tag.hbs +1 -0
  244. data/lib/templates/java/template.hbs +1 -0
  245. data/lib/templates/java/test.hbs +1 -0
  246. data/lib/templates/java/testng/_scenario.hbs +8 -0
  247. data/lib/templates/java/testng/dataset.hbs +4 -0
  248. data/lib/templates/java/testng/folder.hbs +19 -0
  249. data/lib/templates/java/testng/scenarios.hbs +16 -0
  250. data/lib/templates/java/testng/single_scenario.hbs +12 -0
  251. data/lib/templates/java/testng/single_test.hbs +11 -0
  252. data/lib/templates/java/testng/tests.hbs +16 -0
  253. data/lib/templates/java/tests.hbs +11 -0
  254. data/lib/templates/java/variable.hbs +1 -0
  255. data/lib/templates/java/while.hbs +4 -0
  256. data/lib/templates/javascript/_body.hbs +10 -0
  257. data/lib/templates/javascript/_item_as_function.hbs +3 -0
  258. data/lib/templates/javascript/_item_as_hash_key.hbs +3 -0
  259. data/lib/templates/javascript/_module_declaration.hbs +5 -0
  260. data/lib/templates/javascript/_scenario.hbs +4 -0
  261. data/lib/templates/javascript/actionword.hbs +1 -0
  262. data/lib/templates/javascript/actionwords.hbs +4 -0
  263. data/lib/templates/javascript/argument.hbs +1 -0
  264. data/lib/templates/javascript/assign.hbs +1 -0
  265. data/lib/templates/javascript/binaryexpression.hbs +1 -0
  266. data/lib/templates/javascript/call.hbs +2 -0
  267. data/lib/templates/javascript/codeceptjs/actionword.hbs +5 -0
  268. data/lib/templates/javascript/codeceptjs/actionwords.hbs +9 -0
  269. data/lib/templates/javascript/dataset.hbs +3 -0
  270. data/lib/templates/javascript/dict.hbs +1 -0
  271. data/lib/templates/javascript/es6/actionwords.hbs +4 -0
  272. data/lib/templates/javascript/field.hbs +1 -0
  273. data/lib/templates/javascript/folder.hbs +14 -0
  274. data/lib/templates/javascript/ifthen.hbs +7 -0
  275. data/lib/templates/javascript/index.hbs +1 -0
  276. data/lib/templates/javascript/jasmine/_before_each.hbs +3 -0
  277. data/lib/templates/javascript/jasmine/_scenario.hbs +8 -0
  278. data/lib/templates/javascript/jasmine/dataset.hbs +3 -0
  279. data/lib/templates/javascript/jasmine/folder.hbs +11 -0
  280. data/lib/templates/javascript/jasmine/scenarios.hbs +8 -0
  281. data/lib/templates/javascript/jasmine/single_scenario.hbs +6 -0
  282. data/lib/templates/javascript/jasmine/single_test.hbs +6 -0
  283. data/lib/templates/javascript/jasmine/tests.hbs +8 -0
  284. data/lib/templates/javascript/list.hbs +1 -0
  285. data/lib/templates/javascript/mocha/_before_each.hbs +4 -0
  286. data/lib/templates/javascript/mocha/folder.hbs +11 -0
  287. data/lib/templates/javascript/nullliteral.hbs +1 -0
  288. data/lib/templates/javascript/parameter.hbs +1 -0
  289. data/lib/templates/javascript/parenthesis.hbs +1 -0
  290. data/lib/templates/javascript/project.hbs +2 -0
  291. data/lib/templates/javascript/property.hbs +1 -0
  292. data/lib/templates/javascript/scenario.hbs +1 -0
  293. data/lib/templates/javascript/scenarios.hbs +8 -0
  294. data/lib/templates/javascript/single_scenario.hbs +6 -0
  295. data/lib/templates/javascript/single_test.hbs +6 -0
  296. data/lib/templates/javascript/step.hbs +1 -0
  297. data/lib/templates/javascript/tag.hbs +1 -0
  298. data/lib/templates/javascript/template.hbs +1 -0
  299. data/lib/templates/javascript/test.hbs +1 -0
  300. data/lib/templates/javascript/tests.hbs +8 -0
  301. data/lib/templates/javascript/while.hbs +5 -0
  302. data/lib/templates/jbehave/_scenario.hbs +9 -0
  303. data/lib/templates/jbehave/actionwords/parameter.hbs +1 -0
  304. data/lib/templates/jbehave/call.hbs +5 -0
  305. data/lib/templates/jbehave/folder.hbs +16 -0
  306. data/lib/templates/jbehave/single_test.hbs +3 -0
  307. data/lib/templates/jbehave/steps/_gherkin_pattern.hbs +1 -0
  308. data/lib/templates/jbehave/steps/actionword.hbs +6 -0
  309. data/lib/templates/jbehave/steps/actionwords.hbs +18 -0
  310. data/lib/templates/php/_body.hbs +9 -0
  311. data/lib/templates/php/_item_as_function.hbs +3 -0
  312. data/lib/templates/php/_scenario.hbs +4 -0
  313. data/lib/templates/php/_setup.hbs +4 -0
  314. data/lib/templates/php/actionword.hbs +1 -0
  315. data/lib/templates/php/actionwords.hbs +9 -0
  316. data/lib/templates/php/argument.hbs +1 -0
  317. data/lib/templates/php/assign.hbs +1 -0
  318. data/lib/templates/php/binaryexpression.hbs +1 -0
  319. data/lib/templates/php/call.hbs +2 -0
  320. data/lib/templates/php/dataset.hbs +3 -0
  321. data/lib/templates/php/dict.hbs +1 -0
  322. data/lib/templates/php/field.hbs +1 -0
  323. data/lib/templates/php/folder.hbs +17 -0
  324. data/lib/templates/php/ifthen.hbs +7 -0
  325. data/lib/templates/php/index.hbs +1 -0
  326. data/lib/templates/php/libraries.hbs +11 -0
  327. data/lib/templates/php/library.hbs +20 -0
  328. data/lib/templates/php/libraryactionword.hbs +1 -0
  329. data/lib/templates/php/list.hbs +1 -0
  330. data/lib/templates/php/nullliteral.hbs +1 -0
  331. data/lib/templates/php/parameter.hbs +1 -0
  332. data/lib/templates/php/parenthesis.hbs +1 -0
  333. data/lib/templates/php/project.hbs +2 -0
  334. data/lib/templates/php/property.hbs +1 -0
  335. data/lib/templates/php/scenario.hbs +1 -0
  336. data/lib/templates/php/scenarios.hbs +13 -0
  337. data/lib/templates/php/single_scenario.hbs +11 -0
  338. data/lib/templates/php/single_test.hbs +11 -0
  339. data/lib/templates/php/step.hbs +1 -0
  340. data/lib/templates/php/tag.hbs +1 -0
  341. data/lib/templates/php/template.hbs +1 -0
  342. data/lib/templates/php/test.hbs +1 -0
  343. data/lib/templates/php/tests.hbs +13 -0
  344. data/lib/templates/php/variable.hbs +1 -0
  345. data/lib/templates/php/while.hbs +5 -0
  346. data/lib/templates/python/_body.hbs +11 -0
  347. data/lib/templates/python/_item_as_def.hbs +2 -0
  348. data/lib/templates/python/_parameters.hbs +1 -0
  349. data/lib/templates/python/_scenario.hbs +4 -0
  350. data/lib/templates/python/actionword.hbs +1 -0
  351. data/lib/templates/python/actionwords.hbs +12 -0
  352. data/lib/templates/python/argument.hbs +1 -0
  353. data/lib/templates/python/assign.hbs +1 -0
  354. data/lib/templates/python/binaryexpression.hbs +1 -0
  355. data/lib/templates/python/booleanliteral.hbs +1 -0
  356. data/lib/templates/python/call.hbs +2 -0
  357. data/lib/templates/python/dataset.hbs +2 -0
  358. data/lib/templates/python/dict.hbs +1 -0
  359. data/lib/templates/python/field.hbs +1 -0
  360. data/lib/templates/python/folder.hbs +12 -0
  361. data/lib/templates/python/ifthen.hbs +4 -0
  362. data/lib/templates/python/index.hbs +1 -0
  363. data/lib/templates/python/libraries.hbs +9 -0
  364. data/lib/templates/python/library.hbs +17 -0
  365. data/lib/templates/python/libraryactionword.hbs +1 -0
  366. data/lib/templates/python/list.hbs +1 -0
  367. data/lib/templates/python/nullliteral.hbs +1 -0
  368. data/lib/templates/python/parameter.hbs +1 -0
  369. data/lib/templates/python/parenthesis.hbs +1 -0
  370. data/lib/templates/python/project.hbs +2 -0
  371. data/lib/templates/python/property.hbs +1 -0
  372. data/lib/templates/python/scenario.hbs +1 -0
  373. data/lib/templates/python/scenarios.hbs +11 -0
  374. data/lib/templates/python/single_scenario.hbs +9 -0
  375. data/lib/templates/python/single_test.hbs +9 -0
  376. data/lib/templates/python/step.hbs +1 -0
  377. data/lib/templates/python/tag.hbs +1 -0
  378. data/lib/templates/python/template.hbs +1 -0
  379. data/lib/templates/python/test.hbs +1 -0
  380. data/lib/templates/python/tests.hbs +11 -0
  381. data/lib/templates/python/unittest/actionwords.hbs +9 -0
  382. data/lib/templates/python/while.hbs +4 -0
  383. data/lib/templates/robotframework/_keyword.hbs +1 -0
  384. data/lib/templates/robotframework/_keyword_body.hbs +4 -0
  385. data/lib/templates/robotframework/_scenario.hbs +12 -0
  386. data/lib/templates/robotframework/actionword.hbs +3 -0
  387. data/lib/templates/robotframework/actionwords.hbs +4 -0
  388. data/lib/templates/robotframework/argument.hbs +1 -0
  389. data/lib/templates/robotframework/call.hbs +1 -0
  390. data/lib/templates/robotframework/dataset.hbs +1 -0
  391. data/lib/templates/robotframework/datatable.hbs +2 -0
  392. data/lib/templates/robotframework/folder.hbs +35 -0
  393. data/lib/templates/robotframework/ifthen.hbs +1 -0
  394. data/lib/templates/robotframework/parameter.hbs +1 -0
  395. data/lib/templates/robotframework/property.hbs +1 -0
  396. data/lib/templates/robotframework/scenarios.hbs +25 -0
  397. data/lib/templates/robotframework/single_scenario.hbs +10 -0
  398. data/lib/templates/robotframework/single_test.hbs +10 -0
  399. data/lib/templates/robotframework/stringliteral.hbs +1 -0
  400. data/lib/templates/robotframework/template.hbs +1 -0
  401. data/lib/templates/robotframework/test.hbs +1 -0
  402. data/lib/templates/robotframework/tests.hbs +7 -0
  403. data/lib/templates/robotframework/variable.hbs +1 -0
  404. data/lib/templates/robotframework/while.hbs +1 -0
  405. data/lib/templates/ruby/_body.hbs +10 -0
  406. data/lib/templates/ruby/_item_as_def.hbs +3 -0
  407. data/lib/templates/ruby/_scenario.hbs +5 -0
  408. data/lib/templates/ruby/actionword.hbs +1 -0
  409. data/lib/templates/ruby/actionwords.hbs +6 -0
  410. data/lib/templates/ruby/argument.hbs +1 -0
  411. data/lib/templates/ruby/assign.hbs +1 -0
  412. data/lib/templates/ruby/binaryexpression.hbs +1 -0
  413. data/lib/templates/ruby/call.hbs +2 -0
  414. data/lib/templates/ruby/dataset.hbs +3 -0
  415. data/lib/templates/ruby/dict.hbs +1 -0
  416. data/lib/templates/ruby/field.hbs +1 -0
  417. data/lib/templates/ruby/folder.hbs +16 -0
  418. data/lib/templates/ruby/ifthen.hbs +7 -0
  419. data/lib/templates/ruby/index.hbs +1 -0
  420. data/lib/templates/ruby/list.hbs +1 -0
  421. data/lib/templates/ruby/minitest/_item_as_def.hbs +3 -0
  422. data/lib/templates/ruby/minitest/_scenario.hbs +4 -0
  423. data/lib/templates/ruby/minitest/dataset.hbs +3 -0
  424. data/lib/templates/ruby/minitest/folder.hbs +18 -0
  425. data/lib/templates/ruby/minitest/scenario.hbs +1 -0
  426. data/lib/templates/ruby/minitest/scenarios.hbs +13 -0
  427. data/lib/templates/ruby/minitest/single_scenario.hbs +11 -0
  428. data/lib/templates/ruby/minitest/single_test.hbs +11 -0
  429. data/lib/templates/ruby/minitest/test.hbs +1 -0
  430. data/lib/templates/ruby/minitest/tests.hbs +13 -0
  431. data/lib/templates/ruby/parameter.hbs +1 -0
  432. data/lib/templates/ruby/parenthesis.hbs +1 -0
  433. data/lib/templates/ruby/project.hbs +2 -0
  434. data/lib/templates/ruby/property.hbs +1 -0
  435. data/lib/templates/ruby/scenario.hbs +1 -0
  436. data/lib/templates/ruby/scenarios.hbs +12 -0
  437. data/lib/templates/ruby/single_scenario.hbs +11 -0
  438. data/lib/templates/ruby/single_test.hbs +11 -0
  439. data/lib/templates/ruby/step.hbs +1 -0
  440. data/lib/templates/ruby/symbol.hbs +1 -0
  441. data/lib/templates/ruby/tag.hbs +1 -0
  442. data/lib/templates/ruby/template.hbs +1 -0
  443. data/lib/templates/ruby/test.hbs +1 -0
  444. data/lib/templates/ruby/tests.hbs +12 -0
  445. data/lib/templates/ruby/while.hbs +5 -0
  446. data/lib/templates/seleniumide/argument.hbs +1 -0
  447. data/lib/templates/seleniumide/call.hbs +6 -0
  448. data/lib/templates/seleniumide/single_test.hbs +28 -0
  449. data/lib/templates/seleniumide/step.hbs +0 -0
  450. data/lib/templates/seleniumide/stringliteral.hbs +1 -0
  451. data/lib/templates/seleniumide/template.hbs +1 -0
  452. data/lib/templates/seleniumide/test.hbs +4 -0
  453. data/lib/templates/seleniumide/tests.hbs +19 -0
  454. data/lib/templates/specflow/actionword.hbs +6 -0
  455. data/lib/templates/specflow/actionwords/parameter.hbs +1 -0
  456. data/lib/templates/specflow/actionwords.hbs +14 -0
  457. data/lib/templates/specflow/gherkin/tag.hbs +1 -0
  458. data/lib/templates/specflow/parameter.hbs +1 -0
  459. data/lib/templates/swift/_body.hbs +11 -0
  460. data/lib/templates/swift/_item_as_def.hbs +5 -0
  461. data/lib/templates/swift/_scenario.hbs +7 -0
  462. data/lib/templates/swift/actionword.hbs +1 -0
  463. data/lib/templates/swift/actionwords.hbs +6 -0
  464. data/lib/templates/swift/argument.hbs +1 -0
  465. data/lib/templates/swift/assign.hbs +1 -0
  466. data/lib/templates/swift/binaryexpression.hbs +1 -0
  467. data/lib/templates/swift/call.hbs +2 -0
  468. data/lib/templates/swift/dataset.hbs +4 -0
  469. data/lib/templates/swift/dict.hbs +1 -0
  470. data/lib/templates/swift/field.hbs +1 -0
  471. data/lib/templates/swift/folder.hbs +23 -0
  472. data/lib/templates/swift/ifthen.hbs +7 -0
  473. data/lib/templates/swift/index.hbs +1 -0
  474. data/lib/templates/swift/list.hbs +1 -0
  475. data/lib/templates/swift/parameter.hbs +1 -0
  476. data/lib/templates/swift/parenthesis.hbs +1 -0
  477. data/lib/templates/swift/project.hbs +2 -0
  478. data/lib/templates/swift/property.hbs +1 -0
  479. data/lib/templates/swift/scenario.hbs +1 -0
  480. data/lib/templates/swift/scenarios.hbs +25 -0
  481. data/lib/templates/swift/single_scenario.hbs +24 -0
  482. data/lib/templates/swift/single_test.hbs +23 -0
  483. data/lib/templates/swift/step.hbs +1 -0
  484. data/lib/templates/swift/stringliteral.hbs +1 -0
  485. data/lib/templates/swift/symbol.hbs +1 -0
  486. data/lib/templates/swift/tag.hbs +1 -0
  487. data/lib/templates/swift/template.hbs +1 -0
  488. data/lib/templates/swift/test.hbs +1 -0
  489. data/lib/templates/swift/tests.hbs +25 -0
  490. data/lib/templates/swift/while.hbs +5 -0
  491. data/lib/templates/typescript/_item_as_function.hbs +3 -0
  492. data/lib/templates/typescript/actionword.hbs +1 -0
  493. data/lib/templates/typescript/actionwords.hbs +7 -0
  494. data/lib/templates/typescript/libraries.hbs +9 -0
  495. data/lib/templates/typescript/library.hbs +18 -0
  496. data/lib/templates/typescript/libraryactionword.hbs +1 -0
  497. data/lib/templates/typescript/parameter.hbs +1 -0
  498. metadata +783 -0
@@ -0,0 +1,826 @@
1
+ require 'i18n'
2
+ require 'optparse'
3
+ require 'parseconfig'
4
+ require 'ostruct'
5
+ require 'digest/md5'
6
+ require 'pathname'
7
+ require 'ruby-handlebars/escapers/dummy_escaper'
8
+
9
+ require 'hiptest-publisher/formatters/console_formatter'
10
+ require 'hiptest-publisher/renderer_addons'
11
+ require 'hiptest-publisher/utils'
12
+ require 'hiptest-publisher/handlebars_helper'
13
+
14
+
15
+ class FileConfigParser
16
+ FALSY_VALUE_PATTERN = /\A(false|no|0)\Z/i
17
+
18
+ def self.update_options(options, reporter)
19
+ config = ParseConfig.new(options.config)
20
+ config.get_params.each do |param|
21
+ next if options.__cli_args && options.__cli_args.include?(param.to_sym)
22
+ if param.start_with?("no_")
23
+ value = falsy?(config[param]) ? "true" : "false"
24
+ param = param.sub("no_", "")
25
+ else
26
+ value = config[param]
27
+ end
28
+ if falsy?(value)
29
+ options[param] = false
30
+ else
31
+ options[param] = value
32
+ end
33
+ if %w(overriden_templates output_directory).include?(param)
34
+ update_path!(param, config, options)
35
+ end
36
+ options.__config_args << param.to_sym if options.__config_args
37
+ end
38
+ rescue => err
39
+ reporter.dump_error(err)
40
+ end
41
+
42
+ def self.falsy?(value)
43
+ FALSY_VALUE_PATTERN.match(value)
44
+ end
45
+
46
+ def self.update_path!(param, config, options)
47
+ path = Pathname.new(config[param])
48
+ return unless path.relative?
49
+ config_path = Pathname.new(options.config)
50
+ config_absolute_path = config_path.relative? ? Pathname.pwd + config_path : config_path
51
+ resolved_path = config_absolute_path.cleanpath.dirname + path
52
+ options[param] = resolved_path.cleanpath.to_path
53
+ end
54
+ end
55
+
56
+ class Option
57
+ attr_reader :short, :long, :default, :type, :help, :attribute
58
+
59
+ def initialize(short, long, default, type, help, attribute)
60
+ @short = short
61
+ @long = long
62
+ @default = default
63
+ @type = type
64
+ @help = help
65
+ @attribute = attribute
66
+ end
67
+
68
+ def help
69
+ if default == nil || default == ""
70
+ @help
71
+ else
72
+ "#{@help} (#{I18n.t(:default)}: #{@default})"
73
+ end
74
+ end
75
+
76
+ def register(opts, options)
77
+ options[attribute] = @default unless default.nil?
78
+ on_values = [
79
+ @short ? "-#{@short}" : nil,
80
+ "--#{@long}",
81
+ @type,
82
+ help
83
+ ].compact
84
+
85
+ opts.on(*on_values) do |value|
86
+ options[attribute] = value
87
+ options.__cli_args << attribute
88
+ end
89
+ end
90
+ end
91
+
92
+ class CliOptions < OpenStruct
93
+ def initialize(hash = nil)
94
+ hash ||= {}
95
+ hash[:language] ||= ""
96
+ hash[:framework] ||= ""
97
+
98
+ super(__cli_args: Set.new, __config_args: Set.new, **hash)
99
+ end
100
+
101
+ def actionwords_diff?
102
+ actionwords_diff || actionwords_diff_json || aw_deleted || aw_created || aw_renamed || aw_signature_changed || aw_definition_changed
103
+ end
104
+
105
+ def push?
106
+ option_present?(push)
107
+ end
108
+
109
+ def test_run_id?
110
+ option_present?(test_run_id)
111
+ end
112
+
113
+ def test_run_name?
114
+ option_present?(test_run_name)
115
+ end
116
+
117
+ def test_run?
118
+ test_run_id? || test_run_name?
119
+ end
120
+
121
+ def language_framework
122
+ if framework.empty?
123
+ language
124
+ else
125
+ "#{language}-#{framework}"
126
+ end
127
+ end
128
+
129
+ def groups_to_keep
130
+ only.split(",") if only
131
+ end
132
+
133
+ def command_line_used(exclude: [])
134
+ args = self.__cli_args.map do |key|
135
+ next if exclude.include?(key)
136
+ "--#{key.to_s.gsub('_', '-')}=#{self[key]}"
137
+ end.compact
138
+
139
+ "hiptest-publisher #{args.join(' ')}".strip
140
+ end
141
+
142
+ def uids_not_set_yet?
143
+ !__cli_args.include?(:uids) && !__config_args.include?(:uids)
144
+ end
145
+
146
+ def normalize!(reporter = nil)
147
+ self.uids = true if test_run? && uids_not_set_yet?
148
+ self.no_uids = !uids # silent normalization
149
+ modified_options = self.clone
150
+ if actionwords_only
151
+ modified_options.only = 'actionwords'
152
+ elsif tests_only
153
+ modified_options.only = 'tests'
154
+ end
155
+
156
+ if language.include?('-')
157
+ modified_options.language, modified_options.framework = language.split("-", 2)
158
+ elsif framework.empty?
159
+ # pick first framework for the language
160
+ _, frameworks = OptionsParser.languages.find do |language, frameworks|
161
+ language.downcase.gsub(' ', '') == self.language.downcase.gsub(' ', '')
162
+ end
163
+ if frameworks
164
+ modified_options.framework = frameworks.first.downcase
165
+ end
166
+ end
167
+
168
+ if without
169
+ begin
170
+ available_groups = LanguageConfigParser.new(modified_options).filtered_group_names
171
+ modified_options.only = (available_groups - without.split(',')).join(',')
172
+ rescue ArgumentError
173
+ # Ok, that will be handled by cli_options_checkers later on
174
+ end
175
+ end
176
+
177
+ if self != modified_options
178
+ delta = modified_options.table.select do |key, value|
179
+ modified_options[key] != self[key]
180
+ end
181
+ marshal_load(modified_options.marshal_dump)
182
+ if reporter
183
+ reporter.show_options(delta, I18n.t("help.options.nomalized_options"))
184
+ end
185
+ return delta
186
+ end
187
+ end
188
+
189
+ private
190
+
191
+ def option_present?(value)
192
+ value && !value.empty?
193
+ end
194
+ end
195
+
196
+ class EmptiableString
197
+ end
198
+
199
+ class OptionsParser
200
+ def self.languages
201
+ # First framework is default framework
202
+
203
+ {
204
+ 'Ruby' => ['Rspec', 'MiniTest'],
205
+ 'Cucumber' => ['Ruby', 'Java', 'Javascript', 'Groovy', 'TypeScript'],
206
+ 'Cucumber_Legacy' => ['Java', 'Groovy', 'TypeScript'],
207
+ 'Java' => ['JUnit', 'Test NG', 'Espresso'],
208
+ 'Python' => ['Unittest'],
209
+ 'Robot Framework' => [''],
210
+ 'Selenium IDE' => [''],
211
+ 'Javascript' => ['qUnit', 'Jasmine', 'Mocha', 'Protractor', 'CodeceptJS'],
212
+ 'CSharp' => ['NUnit'],
213
+ 'PHP' => ['PHPUnit'],
214
+ 'SpecFlow' => [''],
215
+ 'Behave' => [''],
216
+ 'Behat' => [''],
217
+ 'Groovy' => ['Spock'],
218
+ 'JBehave' => [''],
219
+ 'Swift' => ['XCTest']
220
+ }
221
+ end
222
+
223
+ def self.all_options
224
+ [
225
+ Option.new('t', 'token=TOKEN', nil, String, I18n.t('options.token'), :token),
226
+ Option.new('l', 'language=LANG', 'ruby', String, I18n.t('options.language'), :language),
227
+ Option.new('f', 'framework=FRAMEWORK', '', String, I18n.t('options.framework'), :framework),
228
+ Option.new('o', 'output-directory=PATH', '.', String, I18n.t('options.output_directory'), :output_directory),
229
+ Option.new(nil, 'filename-pattern=PATTERN', nil, String, I18n.t('options.filename_pattern'), :filename_pattern),
230
+ Option.new('c', 'config-file=PATH', nil, String, I18n.t('options.config'), :config),
231
+ Option.new(nil, 'overriden-templates=PATH', '', String, I18n.t('options.overriden_templates'), :overriden_templates),
232
+ Option.new(nil, 'overriden-language-configs=PATH', '', String, I18n.t('options.overriden_language_configs'), :overriden_language_configs),
233
+ Option.new(nil, 'test-run-id=ID', '', String, I18n.t('options.test_run_id'), :test_run_id),
234
+ Option.new(nil, 'test-run-name=NAME', '', String, I18n.t('options.test_run_name'), :test_run_name),
235
+ Option.new(nil, 'only=CATEGORIES', nil, String, I18n.t('options.only'), :only),
236
+ Option.new(nil, 'without=CATEGORIES', nil, String, I18n.t('options.without'), :without),
237
+ Option.new('x', 'xml-file=PROJECT_XML', nil, String, I18n.t('options.xml_file'), :xml_file),
238
+ Option.new(nil, 'cache-dir=PATH', self.default_cache_directory, String, I18n.t('options.cache_dir'), :cache_dir),
239
+ Option.new(nil, 'cache-duration=DURATION', 60, Integer, I18n.t('options.cache_duration'), :cache_duration),
240
+ Option.new(nil, 'tests-only', false, nil, I18n.t('options.tests_only'), :tests_only),
241
+ Option.new(nil, 'actionwords-only', false, nil, I18n.t('options.actionwords_only'), :actionwords_only),
242
+ Option.new(nil, 'actionwords-signature', false, nil, I18n.t('options.actionwords_signature'), :actionwords_signature),
243
+ Option.new(nil, 'show-actionwords-diff', false, nil, I18n.t('options.actionwords_diff'), :actionwords_diff),
244
+ Option.new(nil, 'show-actionwords-diff-as-json', false, nil, I18n.t('options.actionwords_diff_json'), :actionwords_diff_json),
245
+ Option.new(nil, 'show-actionwords-deleted', false, nil, I18n.t('options.aw_deleted'), :aw_deleted),
246
+ Option.new(nil, 'show-actionwords-created', false, nil, I18n.t('options.aw_created'), :aw_created),
247
+ Option.new(nil, 'show-actionwords-renamed', false, nil, I18n.t('options.aw_renamed'), :aw_renamed),
248
+ Option.new(nil, 'show-actionwords-signature-changed', false, nil, I18n.t('options.aw_signature_changed'), :aw_signature_changed),
249
+ Option.new(nil, 'show-actionwords-definition-changed', false, nil, I18n.t('options.aw_definition_changed'), :aw_definition_changed),
250
+ Option.new(nil, 'library-name=LIBRARY_NAME', nil, String, I18n.t('options.library_name'), :library_name),
251
+ Option.new(nil, 'with-folders', false, nil, I18n.t('options.with_folders'), :with_folders),
252
+ Option.new(nil, 'empty-folders', false, nil, I18n.t('options.empty_folders'), :empty_folders),
253
+ Option.new(nil, 'split-scenarios', false, nil, I18n.t('options.split_scenarios'), :split_scenarios),
254
+ Option.new(nil, 'leafless-export', false, nil, I18n.t('options.leafless_export'), :leafless_export),
255
+ Option.new('s', 'site=SITE', 'https://studio.cucumber.io', String, I18n.t('options.site'), :site),
256
+ Option.new(nil, 'http-proxy=PROXY_URL', nil, String, I18n.t('options.http_proxy'), :http_proxy),
257
+ Option.new('p', 'push=FILE.TAP', '', String, I18n.t('options.push'), :push),
258
+ Option.new(nil, 'global-failure-on-missing-reports', false, nil, I18n.t('options.global_failure_on_missing_reports'), :global_failure_on_missing_reports),
259
+ Option.new(nil, 'push-format=tap', 'tap', String, I18n.t('options.push_format'), :push_format),
260
+ Option.new(nil, 'execution-environment=NAME', '', String, I18n.t('options.execution_environment'), :execution_environment),
261
+ Option.new(nil, 'build-id=ID', '', String, I18n.t('options.build_id'), :build_id),
262
+ Option.new(nil, 'build-name=NAME', '', String, I18n.t('options.build_name'), :build_name),
263
+ Option.new(nil, 'sort=[id,order,alpha]', 'order', String, I18n.t('options.sort'), :sort),
264
+ Option.new(nil, '[no-]uids', false, nil, I18n.t('options.uids'), :uids),
265
+ Option.new(nil, '[no-]parent-folder-tags', true, nil, I18n.t('options.parent_folder_tags'), :parent_folder_tags),
266
+ Option.new(nil, 'parameter-delimiter=DELIMITER', '"', EmptiableString, I18n.t('options.parameter_delimiter'), :parameter_delimiter),
267
+ Option.new(nil, 'with-dataset-names', false, nil, I18n.t('options.with_dataset_names'), :with_dataset_names),
268
+ Option.new(nil, 'keep-filenames', false, nil, I18n.t('options.keep_filenames'), :keep_filenames),
269
+ Option.new(nil, 'keep-foldernames', false, nil, I18n.t('options.keep_foldernames'), :keep_foldernames),
270
+ Option.new(nil, 'filter-on-scenario-ids=IDS', '', String, I18n.t('options.filter_on_scenario_ids'), :filter_on_scenario_ids),
271
+ Option.new(nil, 'filter-on-folder-ids=IDS', '', String, I18n.t('options.filter_on_folder_ids'), :filter_on_folder_ids),
272
+ Option.new(nil, 'filter-on-scenario-name=NAME', '', String, I18n.t('options.filter_on_scenario_name'), :filter_on_scenario_name),
273
+ Option.new(nil, 'filter-on-folder-name=NAME', '', String, I18n.t('options.filter_on_folder_name'), :filter_on_folder_name),
274
+ Option.new(nil, 'filter-on-tags=TAGS', '', String, I18n.t('options.filter_on_tags'), :filter_on_tags),
275
+ Option.new(nil, 'filter-on-status=STATUS', '', String, I18n.t('options.filter_on_status'), :filter_on_status),
276
+ Option.new(nil, 'not-recursive', false, nil, I18n.t('options.not_recursive'), :not_recursive),
277
+ Option.new(nil, 'meta=META', '', String, I18n.t('options.meta'), :meta),
278
+ Option.new(nil, 'check-version', false, nil, I18n.t('options.check_version'), :check_version),
279
+ Option.new(nil, 'force', false, nil, I18n.t('options.force_overwrite'), :force_overwrite),
280
+ Option.new(nil, '[no-]color', nil, nil, I18n.t('options.color'), :color),
281
+ Option.new('v', 'verbose', false, nil, I18n.t('options.verbose'), :verbose),
282
+ Option.new(nil, 'indentation=INDENTATION', nil, EmptiableString, I18n.t('options.indentation'), :indent)
283
+ ]
284
+ end
285
+
286
+ def self.default_cache_directory
287
+ home_dir = begin
288
+ Dir.home
289
+ rescue
290
+ '.'
291
+ end
292
+
293
+ File.join(home_dir, '.hiptest-publisher', 'cache')
294
+ end
295
+
296
+ def self.parse(args, reporter)
297
+ options = CliOptions.new
298
+ opt_parser = OptionParser.new do |opts|
299
+ opts.version = hiptest_publisher_version if hiptest_publisher_version
300
+ opts.banner = I18n.t('help.header')
301
+ opts.separator I18n.t("help.description")
302
+ opts.accept(EmptiableString, /.*/m) { |s,*| s }
303
+
304
+ all_options.each {|o| o.register(opts, options)}
305
+
306
+ opts.on("-H", "--languages-help", I18n.t('options.languages_help')) do
307
+ self.show_languages
308
+ exit
309
+ end
310
+
311
+ opts.on_tail("-h", "--help", I18n.t('options.help')) do
312
+ puts opts
313
+ exit
314
+ end
315
+ end
316
+
317
+ args << "--help" if args.empty?
318
+ opt_parser.parse!(args)
319
+ reporter.add_listener(ConsoleFormatter.new(options.verbose, color: options.color))
320
+ FileConfigParser.update_options(options, reporter)
321
+
322
+ reporter.show_options(options.marshal_dump)
323
+ options.normalize!(reporter)
324
+ options
325
+ end
326
+
327
+ def self.make_language_option(lang, framework = '')
328
+ lang_opt = "--language=#{lang.downcase.gsub(' ', '')}"
329
+ framework_opt = "--framework=#{framework.downcase.gsub(' ', '')}"
330
+
331
+ framework.empty? ? lang_opt : "#{lang_opt} #{framework_opt}"
332
+ end
333
+
334
+ def self.show_languages
335
+ puts I18n.t('help.languages.supported_languages')
336
+ languages.each do |language, frameworks|
337
+ puts "#{language}:"
338
+ if frameworks.empty?
339
+ puts I18n.t('help.languages.no_framework_available', language: make_language_option(language, ''))
340
+ else
341
+ frameworks.each_with_index do |fw, index|
342
+ if index == 0
343
+ puts " - #{fw} [#{I18n.t(:default)}] #{make_language_option(language, '')}"
344
+ else
345
+ puts " - #{fw} #{make_language_option(language, fw)}"
346
+ end
347
+ end
348
+ end
349
+ end
350
+ end
351
+ end
352
+
353
+ class NodeRenderingContext
354
+ def initialize(properties)
355
+ # should contain :node, :path, :description, :indentation
356
+ @properties = OpenStruct.new(properties)
357
+ end
358
+
359
+ def method_missing(name, *)
360
+ @properties[name]
361
+ end
362
+
363
+ def node
364
+ @properties.node
365
+ end
366
+
367
+ def [](key)
368
+ @properties[key]
369
+ end
370
+
371
+ def has_key?(key)
372
+ @properties.respond_to?(key)
373
+ end
374
+
375
+ def filename
376
+ File.basename(@properties.path)
377
+ end
378
+
379
+ def folder
380
+ File.dirname(@properties.path)
381
+ end
382
+
383
+ def relative_folder
384
+ File.dirname(@properties.relative_path)
385
+ end
386
+
387
+ def renderer_addons
388
+ addons = @properties.renderer_addons || ""
389
+
390
+ addons.split.map do |addon_name|
391
+ Hiptest.const_get(addon_name)
392
+ end
393
+ end
394
+ end
395
+
396
+ class TemplateFinder
397
+ attr_reader :template_dirs, :overriden_templates, :overriden_language_configs, :forced_templates, :fallback_template
398
+
399
+ def initialize(
400
+ template_dirs: nil,
401
+ overriden_templates: nil,
402
+ overriden_language_configs: nil,
403
+ indentation: ' ',
404
+ forced_templates: nil,
405
+ fallback_template: nil,
406
+ **)
407
+ @template_dirs = template_dirs || []
408
+ @overriden_templates = overriden_templates
409
+ @compiled_handlebars = {}
410
+ @template_path_by_name = {}
411
+ @forced_templates = forced_templates || {}
412
+ @fallback_template = fallback_template
413
+ @context = {indentation: indentation}
414
+ end
415
+
416
+ def dirs
417
+ @dirs ||= begin
418
+ search_dirs = []
419
+ # search in overriden template base dir first
420
+ search_dirs << overriden_templates if overriden_templates
421
+ template_dirs.each {|template_dir|
422
+ # search template paths in overriden_templates
423
+ search_dirs << "#{overriden_templates}/#{template_dir}" if overriden_templates
424
+ # search template paths in hiptest_publisher
425
+ search_dirs << "#{hiptest_publisher_path}/lib/templates/#{template_dir}"
426
+ }
427
+ search_dirs
428
+ end
429
+ end
430
+
431
+ def get_compiled_handlebars(template_name)
432
+ template_path = get_template_path(template_name)
433
+ @compiled_handlebars[template_path] ||= handlebars.compile(File.read(template_path))
434
+ end
435
+
436
+ def get_template_by_name(name)
437
+ return if name.nil?
438
+ name = forced_templates.fetch(name, name)
439
+ dirs.each do |path|
440
+ template_path = File.join(path, "#{name}.hbs")
441
+ return template_path if File.file?(template_path)
442
+ end
443
+ nil
444
+ end
445
+
446
+ def get_template_path(template_name)
447
+ unless @template_path_by_name.has_key?(template_name)
448
+ @template_path_by_name[template_name] = get_template_by_name(template_name) || get_template_by_name(@fallback_template)
449
+ end
450
+ @template_path_by_name[template_name] or raise ArgumentError.new(I18n.t('errors.template_not_found', template_name: template_name, dirs: dirs))
451
+ end
452
+
453
+ def register_partials
454
+ dirs.reverse_each do |path|
455
+ next unless File.directory?(path)
456
+ Dir.entries(path).select do |file_name|
457
+ file_path = File.join(path, file_name)
458
+ next unless File.file?(file_path) && file_name.start_with?('_')
459
+ @handlebars.register_partial(file_name[1..-5], File.read(file_path))
460
+ end
461
+ end
462
+ end
463
+
464
+ private
465
+
466
+ def handlebars
467
+ if !@handlebars
468
+ @handlebars = Handlebars::Handlebars.new
469
+ @handlebars.set_escaper(Handlebars::Escapers::DummyEscaper)
470
+
471
+ register_partials
472
+ Hiptest::HandlebarsHelper.register_helpers(@handlebars, @context)
473
+ end
474
+ @handlebars
475
+ end
476
+ end
477
+
478
+ class LanguageGroupConfig
479
+ @@MAX_FILE_SIZE = 255
480
+
481
+ def initialize(user_params, language_group_params = nil)
482
+ @output_directory = user_params.output_directory || ""
483
+ @filename_pattern = user_params.filename_pattern
484
+ @split_scenarios = user_params.split_scenarios
485
+ @with_folders = user_params.with_folders
486
+ @leafless_export = user_params.leafless_export
487
+ @language_group_params = language_group_params || {}
488
+
489
+ @user_params = user_params
490
+ end
491
+
492
+ def [](key)
493
+ @language_group_params[key]
494
+ end
495
+
496
+ def filename_pattern
497
+ @filename_pattern || self[:named_filename]
498
+ end
499
+
500
+ def with_folders?
501
+ @with_folders && (node_name == :scenarios || node_name == :folders)
502
+ end
503
+
504
+ def splitted_files?
505
+ if filename_pattern.nil?
506
+ # if we can't give a different name for each file, we can't split them
507
+ false
508
+ elsif self[:filename].nil?
509
+ # if we can't give a name to a single file, we must split them
510
+ true
511
+ else
512
+ # both options are possible, do as user specified
513
+ @split_scenarios
514
+ end
515
+ end
516
+
517
+ def can_name_files?
518
+ if filename_pattern.nil?
519
+ false
520
+ else
521
+ splitted_files? || with_folders?
522
+ end
523
+ end
524
+
525
+ def nodes(project)
526
+ case node_name
527
+ when :tests, :scenarios, :actionwords, :libraries
528
+ if splitted_files?
529
+ project.children[node_name].children[node_name]
530
+ elsif with_folders?
531
+ get_folder_nodes(project)
532
+ else
533
+ [project.children[node_name]]
534
+ end
535
+ when :library
536
+ [project.children[:libraries]]
537
+ when :folders
538
+ get_folder_nodes(project)
539
+ end
540
+ end
541
+
542
+ def forced_templates
543
+ forced = {}
544
+ if splitted_files?
545
+ forced.merge!(
546
+ "scenario" => "single_scenario",
547
+ "test" => "single_test",
548
+ )
549
+ end
550
+ if @language_group_params[:forced_templates]
551
+ forced.merge!(@language_group_params[:forced_templates])
552
+ end
553
+ forced
554
+ end
555
+
556
+ def template_dirs
557
+ if @language_group_params[:template_dirs]
558
+ @language_group_params[:template_dirs].split(',').map(&:strip)
559
+ else
560
+ []
561
+ end
562
+ end
563
+
564
+ def template_finder
565
+ @template_finder ||= TemplateFinder.new(
566
+ template_dirs: template_dirs,
567
+ overriden_templates: @language_group_params[:overriden_templates],
568
+ indentation: indentation,
569
+ forced_templates: forced_templates,
570
+ fallback_template: @language_group_params[:fallback_template],
571
+ )
572
+ end
573
+
574
+ def each_node_rendering_context(project)
575
+ return to_enum(:each_node_rendering_context, project) unless block_given?
576
+ nodes(project).each do |node|
577
+ yield build_node_rendering_context(node)
578
+ end
579
+ end
580
+
581
+ def indentation
582
+ return @user_params[:indent] unless @user_params[:indent].nil?
583
+ @language_group_params[:indentation] || ' '
584
+ end
585
+
586
+ def build_node_rendering_context(node)
587
+ relative_path = File.join(output_dirname(node), output_filename(node))
588
+ relative_path = relative_path[1..-1] if relative_path[0] == '/'
589
+ path = File.join(language_group_output_directory, relative_path)
590
+
591
+ if splitted_files?
592
+ description = "#{singularize(node_name)} \"#{node.children[:name]}\""
593
+ else
594
+ description = node_name.to_s
595
+ end
596
+
597
+ NodeRenderingContext.new(
598
+ path: path,
599
+ relative_path: relative_path,
600
+ indentation: indentation,
601
+ template_finder: template_finder,
602
+ description: description,
603
+ node: node,
604
+ call_prefix: @language_group_params[:call_prefix],
605
+ package: @language_group_params[:package],
606
+ meta: @language_group_params[:meta],
607
+ parameter_delimiter: @user_params[:parameter_delimiter],
608
+ namespace: @language_group_params[:namespace],
609
+ uids: @user_params[:uids],
610
+ parent_folder_tags: @user_params[:parent_folder_tags],
611
+ with_dataset_names: @user_params[:with_dataset_names],
612
+ renderer_addons: @language_group_params[:renderer_addons]
613
+ )
614
+ end
615
+
616
+ def language_group_output_directory
617
+ @user_params["#{@language_group_params[:group_name]}_output_directory"] || @output_directory
618
+ end
619
+
620
+ def output_dirname(node)
621
+ return "" unless with_folders?
622
+ folder = node.folder
623
+ hierarchy = []
624
+ while folder && !folder.root?
625
+ hierarchy << normalized_dirname(folder.children[:name])
626
+ folder = folder.parent
627
+ end
628
+ File.join(*hierarchy.reverse)
629
+ end
630
+
631
+ def output_filename(node)
632
+ if can_name_files?
633
+ name = shorten_filename(normalized_filename(node.children[:name] || ''))
634
+ filename = filename_pattern.gsub('%s', name)
635
+ else
636
+ self[:filename]
637
+ end
638
+ end
639
+
640
+ def shorten_filename(name)
641
+ mandatory_characters = filename_pattern.gsub('%s', '').length
642
+ if name.length + mandatory_characters > @@MAX_FILE_SIZE
643
+ "#{name[0, (@@MAX_FILE_SIZE - 32 - mandatory_characters)]}#{Digest::MD5.hexdigest(name)}"
644
+ else
645
+ name
646
+ end
647
+ end
648
+
649
+ private
650
+
651
+ def node_name
652
+ if self[:node_name] == "tests" || self[:node_name] == "scenarios" || self[:group_name] == "tests"
653
+ @leafless_export ? :tests : :scenarios
654
+ elsif self[:node_name] == "actionwords" || self[:group_name] == "actionwords"
655
+ :actionwords
656
+ elsif self[:node_name] == "libraries" || self[:group_name] == "libraries"
657
+ :libraries
658
+ elsif self[:node_name] == "library" || self[:group_name] == "library"
659
+ :library
660
+ elsif self[:node_name] == "folders"
661
+ :folders
662
+ else
663
+ raise I18n.t('errors.invalid_node', name: self[:node_name], group_name: self[:group_name])
664
+ end
665
+ end
666
+
667
+ def get_folder_nodes(project)
668
+ folders = project.children[:test_plan].children[:folders]
669
+ unless @user_params.empty_folders
670
+ folders.select {|folder| folder.children[:scenarios].length > 0}
671
+ else
672
+ folders
673
+ end
674
+ end
675
+
676
+ def normalized_dirname(name)
677
+ return name if @user_params.keep_foldernames
678
+
679
+ dirname_convention = @language_group_params[:dirname_convention] || @language_group_params[:filename_convention] || :normalize
680
+ name.send(dirname_convention)
681
+ end
682
+
683
+ def normalized_filename(name)
684
+ return name if @user_params.keep_filenames
685
+
686
+ filename_convention = @language_group_params[:filename_convention] || :normalize
687
+ name.send(filename_convention)
688
+ end
689
+ end
690
+
691
+ class LanguageConfigParser
692
+ def initialize(cli_options, language_config_path = nil)
693
+ @cli_options = cli_options
694
+ language_config_path ||= LanguageConfigParser.config_path_for(cli_options)
695
+ @config = ParseConfig.new(language_config_path)
696
+ end
697
+
698
+ def self.config_path_for(cli_options)
699
+ config_name = if cli_options.framework.empty?
700
+ "#{cli_options.language}.conf"
701
+ else
702
+ "#{cli_options.language}-#{cli_options.framework}.conf"
703
+ end
704
+ config_path = "/lib/config/#{config_name.downcase}"
705
+ config_prefix = if !cli_options.overriden_language_configs.to_s.empty?
706
+ # If the user has specified a overiden language config path, check it first. If the config
707
+ # exists there, return that, otherwise fall back to the default setup and look for a config there.
708
+ expanded = File.expand_path("#{cli_options.overriden_language_configs}/#{config_name.downcase}")
709
+
710
+ # If the file exists in the path the user specified, set the config path to blank so we will be
711
+ # looking in the exact path that the user requested.
712
+ if File.file?(expanded)
713
+ config_path = ''
714
+ expanded
715
+ end
716
+ end
717
+
718
+ config_path = File.expand_path("#{config_prefix || hiptest_publisher_path}#{config_path}")
719
+
720
+ if !File.file?(config_path)
721
+ if cli_options.framework.to_s.empty?
722
+ message = I18n.t('errors.invalid_config_file_no_framework', hiptest_publisher_path: hiptest_publisher_path, language: cli_options.language.inspect)
723
+ else
724
+ message = I18n.t('errors.invalid_config_file', hiptest_publisher_path: hiptest_publisher_path, language: cli_options.language.inspect, framework: cli_options.framework.inspect)
725
+ end
726
+ raise ArgumentError.new(message)
727
+ end
728
+ File.expand_path(config_path)
729
+ end
730
+
731
+ def group_names
732
+ @config.groups.reject {|group_name|
733
+ group_name.start_with?('_')
734
+ }
735
+ end
736
+
737
+ def filtered_group_names
738
+ if @cli_options.groups_to_keep
739
+ group_names.select {|group_name| @cli_options.groups_to_keep.include?(group_name)}
740
+ else
741
+ group_names
742
+ end
743
+ end
744
+
745
+ def include_group?(group_name)
746
+ filtered_group_names.include?(group_name)
747
+ end
748
+
749
+ def language_group_configs
750
+ filtered_group_names.map {|group_name| make_language_group_config(group_name)}
751
+ end
752
+
753
+ def name_action_word(name)
754
+ name.send(get_key_from_group('actionwords', 'naming_convention'))
755
+ end
756
+
757
+ def meta
758
+ treated = {}
759
+ meta_opt = @cli_options.meta || ""
760
+
761
+ meta_opt.split(',').each do |m|
762
+ key, value = m.split(':')
763
+ value = true if value == 'true'
764
+ value = false if value == 'false'
765
+
766
+ treated[key.strip] = value
767
+ end
768
+
769
+ treated
770
+ end
771
+
772
+ private
773
+
774
+ def get_key_from_group(group, key)
775
+ @config[group][key] || @config['_common'][key]
776
+ end
777
+
778
+ def group_config(group_name)
779
+ if @config[group_name]
780
+ key_values = @config[group_name].map {|key, value| [key.to_sym, value]}
781
+ Hash[key_values]
782
+ else
783
+ {}
784
+ end
785
+ end
786
+
787
+ def make_language_group_config group_name
788
+ # List of options that can be set in the config file but not in command line
789
+ non_visible_options = {
790
+ package: @cli_options.package,
791
+ meta: meta,
792
+ namespace: @cli_options.namespace,
793
+ test_export_dir: @cli_options.test_export_dir,
794
+ tests_ouput_dir: @cli_options.tests_ouput_dir,
795
+ features_output_directory: @cli_options.features_output_directory,
796
+ step_definitions_output_directory: @cli_options.step_definitions_output_directory,
797
+ step_definitions_library_output_directory: @cli_options.step_definitions_output_directory,
798
+ libraries_output_directory: @cli_options.actionwords_output_directory,
799
+ library_output_directory: @cli_options.actionwords_output_directory,
800
+ actionwords_output_directory: @cli_options.actionwords_output_directory
801
+ }
802
+
803
+ language_group_params = group_config('_common')
804
+ language_group_params.merge!(group_config(group_name))
805
+ language_group_params[:group_name] = group_name
806
+
807
+ non_visible_options.each do |key, value|
808
+ language_group_params[key] = value if value
809
+ end
810
+
811
+ unless @cli_options.overriden_templates.nil? || @cli_options.overriden_templates.empty?
812
+ language_group_params[:overriden_templates] = @cli_options.overriden_templates
813
+ end
814
+
815
+ if @cli_options.step_definitions_output_directory
816
+ @cli_options.step_definitions_library_output_directory = @cli_options.step_definitions_output_directory
817
+ end
818
+
819
+ if @cli_options.actionwords_output_directory
820
+ @cli_options.libraries_output_directory = @cli_options.actionwords_output_directory
821
+ @cli_options.library_output_directory = @cli_options.actionwords_output_directory
822
+ end
823
+
824
+ LanguageGroupConfig.new(@cli_options, language_group_params)
825
+ end
826
+ end