stupidedi 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (500) hide show
  1. data/README.md +215 -0
  2. data/Rakefile +108 -0
  3. data/bin/edi-ed +71 -0
  4. data/bin/edi-pp +81 -0
  5. data/doc/Defining.md +0 -0
  6. data/doc/Generating.md +321 -0
  7. data/doc/LICENSE.md +0 -0
  8. data/doc/Navigating.md +645 -0
  9. data/doc/Parsing.md +0 -0
  10. data/doc/Serializing.md +7 -0
  11. data/doc/Tokenizing.md +0 -0
  12. data/doc/Validating.md +0 -0
  13. data/doc/design/Parser.md +0 -0
  14. data/doc/design/Reader.md +0 -0
  15. data/lib/ruby/array.rb +164 -0
  16. data/lib/ruby/blank.rb +67 -0
  17. data/lib/ruby/enumerable.rb +35 -0
  18. data/lib/ruby/exception.rb +33 -0
  19. data/lib/ruby/hash.rb +4 -0
  20. data/lib/ruby/instance_exec.rb +26 -0
  21. data/lib/ruby/module.rb +79 -0
  22. data/lib/ruby/object.rb +63 -0
  23. data/lib/ruby/string.rb +73 -0
  24. data/lib/ruby/symbol.rb +24 -0
  25. data/lib/ruby/to_d.rb +81 -0
  26. data/lib/ruby/to_date.rb +33 -0
  27. data/lib/ruby/to_time.rb +24 -0
  28. data/lib/ruby/try.rb +43 -0
  29. data/lib/stupidedi/blank_slate.rb +11 -0
  30. data/lib/stupidedi/builder/builder_dsl.rb +281 -0
  31. data/lib/stupidedi/builder/constraint_table.rb +418 -0
  32. data/lib/stupidedi/builder/generation.rb +112 -0
  33. data/lib/stupidedi/builder/instruction.rb +102 -0
  34. data/lib/stupidedi/builder/instruction_table.rb +204 -0
  35. data/lib/stupidedi/builder/navigation.rb +655 -0
  36. data/lib/stupidedi/builder/state_machine.rb +55 -0
  37. data/lib/stupidedi/builder/states/abstract_state.rb +332 -0
  38. data/lib/stupidedi/builder/states/failure_state.rb +69 -0
  39. data/lib/stupidedi/builder/states/functional_group_state.rb +97 -0
  40. data/lib/stupidedi/builder/states/initial_state.rb +63 -0
  41. data/lib/stupidedi/builder/states/interchange_state.rb +94 -0
  42. data/lib/stupidedi/builder/states/loop_state.rb +79 -0
  43. data/lib/stupidedi/builder/states/table_state.rb +96 -0
  44. data/lib/stupidedi/builder/states/transaction_set_state.rb +112 -0
  45. data/lib/stupidedi/builder/states/transmission_state.rb +59 -0
  46. data/lib/stupidedi/builder/tokenization.rb +196 -0
  47. data/lib/stupidedi/builder.rb +23 -0
  48. data/lib/stupidedi/color.rb +93 -0
  49. data/lib/stupidedi/config/code_list_config.rb +42 -0
  50. data/lib/stupidedi/config/editor_config.rb +51 -0
  51. data/lib/stupidedi/config/functional_group_config.rb +62 -0
  52. data/lib/stupidedi/config/interchange_config.rb +79 -0
  53. data/lib/stupidedi/config/transaction_set_config.rb +91 -0
  54. data/lib/stupidedi/config.rb +101 -0
  55. data/lib/stupidedi/editor/00501.rb +341 -0
  56. data/lib/stupidedi/editor/005010/N2.rb +0 -0
  57. data/lib/stupidedi/editor/005010/N3.rb +0 -0
  58. data/lib/stupidedi/editor/005010/N4.rb +63 -0
  59. data/lib/stupidedi/editor/005010/NM1.rb +0 -0
  60. data/lib/stupidedi/editor/005010.rb +469 -0
  61. data/lib/stupidedi/editor/X222-HC837.rb +195 -0
  62. data/lib/stupidedi/editor/abstract_ed.rb +36 -0
  63. data/lib/stupidedi/editor/claim_ack.rb +9 -0
  64. data/lib/stupidedi/editor/implementation_ack.rb +213 -0
  65. data/lib/stupidedi/editor/interchange_ack.rb +9 -0
  66. data/lib/stupidedi/editor/result.rb +100 -0
  67. data/lib/stupidedi/editor/result_set.rb +69 -0
  68. data/lib/stupidedi/editor/transaction_set_ed.rb +275 -0
  69. data/lib/stupidedi/editor/transmission_ed.rb +90 -0
  70. data/lib/stupidedi/editor.rb +37 -0
  71. data/lib/stupidedi/either.rb +287 -0
  72. data/lib/stupidedi/exceptions/invalid_element_error.rb +8 -0
  73. data/lib/stupidedi/exceptions/invalid_schema_error.rb +8 -0
  74. data/lib/stupidedi/exceptions/output_error.rb +8 -0
  75. data/lib/stupidedi/exceptions/parse_error.rb +8 -0
  76. data/lib/stupidedi/exceptions/stupidedi_error.rb +8 -0
  77. data/lib/stupidedi/exceptions/tokenize_error.rb +8 -0
  78. data/lib/stupidedi/exceptions/zipper_error.rb +8 -0
  79. data/lib/stupidedi/exceptions.rb +11 -0
  80. data/lib/stupidedi/guides/005010/X214-HN277.rb +409 -0
  81. data/lib/stupidedi/guides/005010/X221-HP835.rb +613 -0
  82. data/lib/stupidedi/guides/005010/X221A1-HP835.rb +613 -0
  83. data/lib/stupidedi/guides/005010/X222-HC837P.rb +2291 -0
  84. data/lib/stupidedi/guides/005010/X222A1-HC837P.rb +2297 -0
  85. data/lib/stupidedi/guides/005010/X231-FA999.rb +123 -0
  86. data/lib/stupidedi/guides/005010/X231A1-FA999.rb +119 -0
  87. data/lib/stupidedi/guides/005010/element_reqs.rb +38 -0
  88. data/lib/stupidedi/guides/005010/guide_builder.rb +180 -0
  89. data/lib/stupidedi/guides/005010/segment_reqs.rb +32 -0
  90. data/lib/stupidedi/guides/005010.rb +64 -0
  91. data/lib/stupidedi/guides.rb +5 -0
  92. data/lib/stupidedi/inspect.rb +26 -0
  93. data/lib/stupidedi/reader/input/abstract_input.rb +133 -0
  94. data/lib/stupidedi/reader/input/delegated_input.rb +111 -0
  95. data/lib/stupidedi/reader/input/file_input.rb +155 -0
  96. data/lib/stupidedi/reader/input.rb +30 -0
  97. data/lib/stupidedi/reader/position.rb +69 -0
  98. data/lib/stupidedi/reader/result.rb +168 -0
  99. data/lib/stupidedi/reader/segment_dict.rb +175 -0
  100. data/lib/stupidedi/reader/separators.rb +85 -0
  101. data/lib/stupidedi/reader/stream_reader.rb +172 -0
  102. data/lib/stupidedi/reader/token_reader.rb +466 -0
  103. data/lib/stupidedi/reader/tokens/component_element_tok.rb +56 -0
  104. data/lib/stupidedi/reader/tokens/composite_element_tok.rb +64 -0
  105. data/lib/stupidedi/reader/tokens/repeated_element_tok.rb +64 -0
  106. data/lib/stupidedi/reader/tokens/segment_tok.rb +51 -0
  107. data/lib/stupidedi/reader/tokens/simple_element_tok.rb +63 -0
  108. data/lib/stupidedi/reader.rb +121 -0
  109. data/lib/stupidedi/schema/abstract_def.rb +74 -0
  110. data/lib/stupidedi/schema/abstract_use.rb +73 -0
  111. data/lib/stupidedi/schema/code_list.rb +94 -0
  112. data/lib/stupidedi/schema/element_def.rb +173 -0
  113. data/lib/stupidedi/schema/element_req.rb +56 -0
  114. data/lib/stupidedi/schema/element_use.rb +251 -0
  115. data/lib/stupidedi/schema/functional_group_def.rb +114 -0
  116. data/lib/stupidedi/schema/interchange_def.rb +93 -0
  117. data/lib/stupidedi/schema/loop_def.rb +152 -0
  118. data/lib/stupidedi/schema/repeat_count.rb +85 -0
  119. data/lib/stupidedi/schema/segment_def.rb +108 -0
  120. data/lib/stupidedi/schema/segment_req.rb +43 -0
  121. data/lib/stupidedi/schema/segment_use.rb +98 -0
  122. data/lib/stupidedi/schema/syntax_note.rb +63 -0
  123. data/lib/stupidedi/schema/table_def.rb +139 -0
  124. data/lib/stupidedi/schema/transaction_set_def.rb +88 -0
  125. data/lib/stupidedi/schema.rb +28 -0
  126. data/lib/stupidedi/sets/absolute_set.rb +297 -0
  127. data/lib/stupidedi/sets/abstract_set.rb +174 -0
  128. data/lib/stupidedi/sets/null_set.rb +125 -0
  129. data/lib/stupidedi/sets/relative_complement.rb +137 -0
  130. data/lib/stupidedi/sets/relative_set.rb +269 -0
  131. data/lib/stupidedi/sets/universal_set.rb +104 -0
  132. data/lib/stupidedi/sets.rb +57 -0
  133. data/lib/stupidedi/tail_call.rb +109 -0
  134. data/lib/stupidedi/thread_local.rb +174 -0
  135. data/lib/stupidedi/values/abstract_element_val.rb +19 -0
  136. data/lib/stupidedi/values/abstract_val.rb +130 -0
  137. data/lib/stupidedi/values/composite_element_val.rb +95 -0
  138. data/lib/stupidedi/values/functional_group_val.rb +102 -0
  139. data/lib/stupidedi/values/interchange_val.rb +86 -0
  140. data/lib/stupidedi/values/invalid_envelope_val.rb +61 -0
  141. data/lib/stupidedi/values/invalid_segment_val.rb +78 -0
  142. data/lib/stupidedi/values/loop_val.rb +70 -0
  143. data/lib/stupidedi/values/repeated_element_val.rb +105 -0
  144. data/lib/stupidedi/values/segment_val.rb +104 -0
  145. data/lib/stupidedi/values/segment_val_group.rb +20 -0
  146. data/lib/stupidedi/values/simple_element_val.rb +80 -0
  147. data/lib/stupidedi/values/table_val.rb +66 -0
  148. data/lib/stupidedi/values/transaction_set_val.rb +66 -0
  149. data/lib/stupidedi/values/transmission_val.rb +52 -0
  150. data/lib/stupidedi/values.rb +21 -0
  151. data/lib/stupidedi/version.rb +3 -0
  152. data/lib/stupidedi/versions/functional_groups/004010/element_defs.rb +54 -0
  153. data/lib/stupidedi/versions/functional_groups/004010/element_reqs.rb +18 -0
  154. data/lib/stupidedi/versions/functional_groups/004010/element_types/date_val.rb +527 -0
  155. data/lib/stupidedi/versions/functional_groups/004010/element_types/fixnum_val.rb +335 -0
  156. data/lib/stupidedi/versions/functional_groups/004010/element_types/float_val.rb +299 -0
  157. data/lib/stupidedi/versions/functional_groups/004010/element_types/identifier_val.rb +287 -0
  158. data/lib/stupidedi/versions/functional_groups/004010/element_types/string_val.rb +338 -0
  159. data/lib/stupidedi/versions/functional_groups/004010/element_types/time_val.rb +309 -0
  160. data/lib/stupidedi/versions/functional_groups/004010/element_types.rb +124 -0
  161. data/lib/stupidedi/versions/functional_groups/004010/functional_group_def.rb +30 -0
  162. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/GE.rb +20 -0
  163. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/GS.rb +27 -0
  164. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/SE.rb +20 -0
  165. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/ST.rb +20 -0
  166. data/lib/stupidedi/versions/functional_groups/004010/segment_defs.rb +23 -0
  167. data/lib/stupidedi/versions/functional_groups/004010/segment_reqs.rb +18 -0
  168. data/lib/stupidedi/versions/functional_groups/004010/syntax_notes.rb +174 -0
  169. data/lib/stupidedi/versions/functional_groups/004010.rb +38 -0
  170. data/lib/stupidedi/versions/functional_groups/005010/element_defs.rb +1405 -0
  171. data/lib/stupidedi/versions/functional_groups/005010/element_reqs.rb +18 -0
  172. data/lib/stupidedi/versions/functional_groups/005010/element_types/date_val.rb +577 -0
  173. data/lib/stupidedi/versions/functional_groups/005010/element_types/fixnum_val.rb +322 -0
  174. data/lib/stupidedi/versions/functional_groups/005010/element_types/float_val.rb +354 -0
  175. data/lib/stupidedi/versions/functional_groups/005010/element_types/identifier_val.rb +368 -0
  176. data/lib/stupidedi/versions/functional_groups/005010/element_types/operators.rb +117 -0
  177. data/lib/stupidedi/versions/functional_groups/005010/element_types/string_val.rb +398 -0
  178. data/lib/stupidedi/versions/functional_groups/005010/element_types/time_val.rb +327 -0
  179. data/lib/stupidedi/versions/functional_groups/005010/element_types.rb +132 -0
  180. data/lib/stupidedi/versions/functional_groups/005010/functional_group_def.rb +30 -0
  181. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK1.rb +21 -0
  182. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK2.rb +21 -0
  183. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK9.rb +28 -0
  184. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AMT.rb +21 -0
  185. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/BHT.rb +24 -0
  186. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/BPR.rb +49 -0
  187. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CAS.rb +56 -0
  188. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CL1.rb +22 -0
  189. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CLM.rb +41 -0
  190. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CLP.rb +34 -0
  191. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CN1.rb +24 -0
  192. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR1.rb +32 -0
  193. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR2.rb +35 -0
  194. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR3.rb +25 -0
  195. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CRC.rb +26 -0
  196. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CTP.rb +36 -0
  197. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CTX.rb +24 -0
  198. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CUR.rb +57 -0
  199. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DMG.rb +34 -0
  200. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DN1.rb +22 -0
  201. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DN2.rb +24 -0
  202. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DTM.rb +24 -0
  203. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DTP.rb +21 -0
  204. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/FRM.rb +25 -0
  205. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/GE.rb +20 -0
  206. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/GS.rb +27 -0
  207. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HCP.rb +39 -0
  208. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HI.rb +31 -0
  209. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HL.rb +22 -0
  210. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK3.rb +22 -0
  211. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK4.rb +22 -0
  212. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK5.rb +24 -0
  213. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/K3.rb +21 -0
  214. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LIN.rb +69 -0
  215. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LQ.rb +22 -0
  216. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LX.rb +19 -0
  217. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MEA.rb +39 -0
  218. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MIA.rb +45 -0
  219. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MOA.rb +28 -0
  220. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N1.rb +24 -0
  221. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N2.rb +20 -0
  222. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N3.rb +20 -0
  223. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N4.rb +30 -0
  224. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/NM1.rb +35 -0
  225. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/NTE.rb +20 -0
  226. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/OI.rb +24 -0
  227. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PAT.rb +31 -0
  228. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PER.rb +32 -0
  229. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PLB.rb +40 -0
  230. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PRV.rb +26 -0
  231. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PS1.rb +21 -0
  232. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PWK.rb +30 -0
  233. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/QTY.rb +25 -0
  234. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/RDM.rb +23 -0
  235. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/REF.rb +23 -0
  236. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SBR.rb +28 -0
  237. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SE.rb +20 -0
  238. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/ST.rb +21 -0
  239. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/STC.rb +30 -0
  240. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV1.rb +44 -0
  241. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV2.rb +29 -0
  242. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV3.rb +30 -0
  243. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV5.rb +29 -0
  244. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SVC.rb +26 -0
  245. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SVD.rb +24 -0
  246. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TOO.rb +21 -0
  247. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TRN.rb +22 -0
  248. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TS2.rb +40 -0
  249. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TS3.rb +45 -0
  250. data/lib/stupidedi/versions/functional_groups/005010/segment_defs.rb +227 -0
  251. data/lib/stupidedi/versions/functional_groups/005010/segment_reqs.rb +18 -0
  252. data/lib/stupidedi/versions/functional_groups/005010/syntax_notes.rb +165 -0
  253. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/FA999.rb +38 -0
  254. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HB271.rb +85 -0
  255. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HC837.rb +163 -0
  256. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HI278.rb +64 -0
  257. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HN277.rb +74 -0
  258. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HP835.rb +68 -0
  259. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HR276.rb +57 -0
  260. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HS270.rb +53 -0
  261. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/RA820.rb +240 -0
  262. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs.rb +68 -0
  263. data/lib/stupidedi/versions/functional_groups/005010.rb +38 -0
  264. data/lib/stupidedi/versions/functional_groups.rb +8 -0
  265. data/lib/stupidedi/versions/interchanges/00401/element_defs.rb +224 -0
  266. data/lib/stupidedi/versions/interchanges/00401/interchange_def.rb +45 -0
  267. data/lib/stupidedi/versions/interchanges/00401/segment_defs/IEA.rb +20 -0
  268. data/lib/stupidedi/versions/interchanges/00401/segment_defs/ISA.rb +34 -0
  269. data/lib/stupidedi/versions/interchanges/00401/segment_defs/TA1.rb +23 -0
  270. data/lib/stupidedi/versions/interchanges/00401/segment_defs.rb +28 -0
  271. data/lib/stupidedi/versions/interchanges/00401.rb +23 -0
  272. data/lib/stupidedi/versions/interchanges/00501/element_defs.rb +269 -0
  273. data/lib/stupidedi/versions/interchanges/00501/interchange_def.rb +47 -0
  274. data/lib/stupidedi/versions/interchanges/00501/segment_defs/IEA.rb +20 -0
  275. data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISA.rb +34 -0
  276. data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISB.rb +18 -0
  277. data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISE.rb +18 -0
  278. data/lib/stupidedi/versions/interchanges/00501/segment_defs/TA1.rb +23 -0
  279. data/lib/stupidedi/versions/interchanges/00501/segment_defs/TA3.rb +18 -0
  280. data/lib/stupidedi/versions/interchanges/00501/segment_defs.rb +37 -0
  281. data/lib/stupidedi/versions/interchanges/00501.rb +23 -0
  282. data/lib/stupidedi/versions/interchanges.rb +8 -0
  283. data/lib/stupidedi/versions.rb +6 -0
  284. data/lib/stupidedi/writer/claredi.rb +142 -0
  285. data/lib/stupidedi/writer/default.rb +124 -0
  286. data/lib/stupidedi/writer.rb +6 -0
  287. data/lib/stupidedi/zipper/abstract_cursor.rb +351 -0
  288. data/lib/stupidedi/zipper/dangling_cursor.rb +103 -0
  289. data/lib/stupidedi/zipper/edited_cursor.rb +157 -0
  290. data/lib/stupidedi/zipper/memoized_cursor.rb +131 -0
  291. data/lib/stupidedi/zipper/path.rb +124 -0
  292. data/lib/stupidedi/zipper/root_cursor.rb +120 -0
  293. data/lib/stupidedi/zipper.rb +25 -0
  294. data/lib/stupidedi.rb +66 -0
  295. data/spec/examples/integration/generating.example +551 -0
  296. data/spec/examples/integration/navigating.example +214 -0
  297. data/spec/examples/integration/parsing.example +445 -0
  298. data/spec/examples/ruby/array.example +476 -0
  299. data/spec/examples/ruby/blank.example +62 -0
  300. data/spec/examples/ruby/count.example +68 -0
  301. data/spec/examples/ruby/object.example +99 -0
  302. data/spec/examples/ruby/string.example +111 -0
  303. data/spec/examples/ruby/symbol.example +117 -0
  304. data/spec/examples/ruby/to_d.example +90 -0
  305. data/spec/examples/ruby/try.example +50 -0
  306. data/spec/examples/stupidedi/either.example +375 -0
  307. data/spec/examples/stupidedi/reader/failure.example +68 -0
  308. data/spec/examples/stupidedi/reader/input/delegated_input.example +292 -0
  309. data/spec/examples/stupidedi/reader/separators.example +73 -0
  310. data/spec/examples/stupidedi/reader/stream_reader.example +48 -0
  311. data/spec/examples/stupidedi/reader/success.example +34 -0
  312. data/spec/examples/stupidedi/reader/token_reader.example +775 -0
  313. data/spec/examples/stupidedi/reader.example +168 -0
  314. data/spec/examples/stupidedi/sets/absolute_set.example +1577 -0
  315. data/spec/examples/stupidedi/sets/null_set.example +2 -0
  316. data/spec/examples/stupidedi/sets/relative_set.example +2 -0
  317. data/spec/examples/stupidedi/sets/universal_set.example +1 -0
  318. data/spec/examples/stupidedi/versions/005010/element_types/an.example +201 -0
  319. data/spec/examples/stupidedi/versions/005010/element_types/dt.example +258 -0
  320. data/spec/examples/stupidedi/versions/005010/element_types/id.example +192 -0
  321. data/spec/examples/stupidedi/versions/005010/element_types/nn.example +177 -0
  322. data/spec/examples/stupidedi/versions/005010/element_types/r.example +178 -0
  323. data/spec/examples/stupidedi/versions/005010/element_types/tm.example +2 -0
  324. data/spec/examples/stupidedi/zipper/abstract_cursor.example +417 -0
  325. data/spec/examples/stupidedi/zipper.example +9 -0
  326. data/spec/fixtures/X186-AG824/1-bad.txt +21 -0
  327. data/spec/fixtures/X186-AG824/1-good.txt +17 -0
  328. data/spec/fixtures/X186-AG824/2-bad.txt +26 -0
  329. data/spec/fixtures/X186-AG824/2-good.txt +21 -0
  330. data/spec/fixtures/X186-AG824/3-bad.txt +87 -0
  331. data/spec/fixtures/X186-AG824/3-good.txt +61 -0
  332. data/spec/fixtures/X212-HN277/1-bad.txt +54 -0
  333. data/spec/fixtures/X212-HN277/1-good.txt +46 -0
  334. data/spec/fixtures/X212-HN277/2-bad.txt +37 -0
  335. data/spec/fixtures/X212-HN277/2-good.txt +29 -0
  336. data/spec/fixtures/X212-HN277/3-bad.txt +22 -0
  337. data/spec/fixtures/X212-HN277/3-good.txt +17 -0
  338. data/spec/fixtures/X212-HN277/4-bad.txt +30 -0
  339. data/spec/fixtures/X212-HN277/4-good.txt +24 -0
  340. data/spec/fixtures/X212-HR276/1-bad.txt +53 -0
  341. data/spec/fixtures/X212-HR276/1-good.txt +46 -0
  342. data/spec/fixtures/X212-HR276/2-bad.txt +45 -0
  343. data/spec/fixtures/X212-HR276/2-good.txt +38 -0
  344. data/spec/fixtures/X212-HR276/3-bad.txt +32 -0
  345. data/spec/fixtures/X212-HR276/3-good.txt +26 -0
  346. data/spec/fixtures/X212-HR276/4-bad.txt +32 -0
  347. data/spec/fixtures/X212-HR276/4-good.txt +26 -0
  348. data/spec/fixtures/X214-HN277/1-bad.txt +58 -0
  349. data/spec/fixtures/X214-HN277/1-good.txt +47 -0
  350. data/spec/fixtures/X214-HN277/2-bad.txt +34 -0
  351. data/spec/fixtures/X214-HN277/2-good.txt +22 -0
  352. data/spec/fixtures/X214-HN277/3-bad.txt +64 -0
  353. data/spec/fixtures/X214-HN277/3-good.txt +54 -0
  354. data/spec/fixtures/X214-HN277/4-bad.txt +77 -0
  355. data/spec/fixtures/X214-HN277/4-good.txt +63 -0
  356. data/spec/fixtures/X216-HI278/1-bad.txt +42 -0
  357. data/spec/fixtures/X216-HI278/1-good.txt +27 -0
  358. data/spec/fixtures/X216-HI278/2-bad.txt +43 -0
  359. data/spec/fixtures/X216-HI278/2-good.txt +29 -0
  360. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-1.txt +24 -0
  361. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-1_Clean.txt +20 -0
  362. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-2.txt +46 -0
  363. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-2_Clean.txt +30 -0
  364. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-3.txt +38 -0
  365. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-3_Clean.txt +24 -0
  366. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4a.txt +39 -0
  367. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4a_Clean.txt +24 -0
  368. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4b.txt +43 -0
  369. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4b_Clean.txt +25 -0
  370. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-5.txt +63 -0
  371. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-5_Clean.txt +41 -0
  372. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-6.txt +36 -0
  373. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-6_Clean.txt +20 -0
  374. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-1r.txt +34 -0
  375. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-1r_Clean.txt +23 -0
  376. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-2r.txt +46 -0
  377. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-2r_Clean.txt +31 -0
  378. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-3r.txt +44 -0
  379. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-3r_Clean.txt +26 -0
  380. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-4ar_Clean.txt +28 -0
  381. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-4br_Clean.txt +35 -0
  382. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-5r.txt +60 -0
  383. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-5r_Clean.txt +42 -0
  384. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-6r.txt +40 -0
  385. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-6r_Clean.txt +24 -0
  386. data/spec/fixtures/X218-RA820/1-bad.txt +31 -0
  387. data/spec/fixtures/X218-RA820/1-good.txt +25 -0
  388. data/spec/fixtures/X218-RA820/2-bad.txt +37 -0
  389. data/spec/fixtures/X218-RA820/2-good.txt +29 -0
  390. data/spec/fixtures/X218-RA820/3-bad.txt +29 -0
  391. data/spec/fixtures/X218-RA820/3-good.txt +23 -0
  392. data/spec/fixtures/X218-RA820/4-bad.txt +36 -0
  393. data/spec/fixtures/X218-RA820/4-good.txt +27 -0
  394. data/spec/fixtures/X220-BE834/1-bad.txt +35 -0
  395. data/spec/fixtures/X220-BE834/1-good.txt +29 -0
  396. data/spec/fixtures/X220-BE834/10-bad.txt +26 -0
  397. data/spec/fixtures/X220-BE834/10-good.txt +19 -0
  398. data/spec/fixtures/X220-BE834/2-bad.txt +31 -0
  399. data/spec/fixtures/X220-BE834/2-good.txt +23 -0
  400. data/spec/fixtures/X220-BE834/3-bad.txt +36 -0
  401. data/spec/fixtures/X220-BE834/3-good.txt +26 -0
  402. data/spec/fixtures/X220-BE834/4-bad.txt +27 -0
  403. data/spec/fixtures/X220-BE834/4-good.txt +21 -0
  404. data/spec/fixtures/X220-BE834/5-bad.txt +26 -0
  405. data/spec/fixtures/X220-BE834/5-good.txt +17 -0
  406. data/spec/fixtures/X220-BE834/6-bad.txt +25 -0
  407. data/spec/fixtures/X220-BE834/6-good.txt +20 -0
  408. data/spec/fixtures/X220-BE834/7-bad.txt +25 -0
  409. data/spec/fixtures/X220-BE834/7-good.txt +20 -0
  410. data/spec/fixtures/X220-BE834/8-bad.txt +25 -0
  411. data/spec/fixtures/X220-BE834/8-good.txt +20 -0
  412. data/spec/fixtures/X220-BE834/9-bad.txt +27 -0
  413. data/spec/fixtures/X220-BE834/9-good.txt +21 -0
  414. data/spec/fixtures/X221-HP835/1-bad.txt +58 -0
  415. data/spec/fixtures/X221-HP835/1-good.txt +40 -0
  416. data/spec/fixtures/X221-HP835/2-bad.txt +51 -0
  417. data/spec/fixtures/X221-HP835/2-good.txt +40 -0
  418. data/spec/fixtures/X221-HP835/3a-bad.txt +78 -0
  419. data/spec/fixtures/X221-HP835/3a-good.txt +49 -0
  420. data/spec/fixtures/X221-HP835/3b-bad.txt +60 -0
  421. data/spec/fixtures/X221-HP835/3b-good.txt +32 -0
  422. data/spec/fixtures/X221-HP835/3c-bad.txt +55 -0
  423. data/spec/fixtures/X221-HP835/3c-good.txt +34 -0
  424. data/spec/fixtures/X222-HC837/1-bad.txt +60 -0
  425. data/spec/fixtures/X222-HC837/1-good.txt +53 -0
  426. data/spec/fixtures/X222-HC837/10a-bad.txt +52 -0
  427. data/spec/fixtures/X222-HC837/10a-good.txt +40 -0
  428. data/spec/fixtures/X222-HC837/10b-bad.txt +99 -0
  429. data/spec/fixtures/X222-HC837/10b-good.txt +80 -0
  430. data/spec/fixtures/X222-HC837/10c-bad.txt +105 -0
  431. data/spec/fixtures/X222-HC837/10c-good.txt +80 -0
  432. data/spec/fixtures/X222-HC837/11-bad.txt +69 -0
  433. data/spec/fixtures/X222-HC837/11-good.txt +45 -0
  434. data/spec/fixtures/X222-HC837/12-bad.txt +73 -0
  435. data/spec/fixtures/X222-HC837/12-good.txt +51 -0
  436. data/spec/fixtures/X222-HC837/13-bad.txt +64 -0
  437. data/spec/fixtures/X222-HC837/13-good.txt +46 -0
  438. data/spec/fixtures/X222-HC837/3a-bad.txt +83 -0
  439. data/spec/fixtures/X222-HC837/3a-good.txt +59 -0
  440. data/spec/fixtures/X222-HC837/3b-bad.txt +97 -0
  441. data/spec/fixtures/X222-HC837/3b-good.txt +70 -0
  442. data/spec/fixtures/X222-HC837/3c-bad.txt +95 -0
  443. data/spec/fixtures/X222-HC837/3c-good.txt +74 -0
  444. data/spec/fixtures/X222-HC837/4-bad.txt +67 -0
  445. data/spec/fixtures/X222-HC837/4-good.txt +48 -0
  446. data/spec/fixtures/X222-HC837/5-bad.txt +73 -0
  447. data/spec/fixtures/X222-HC837/5-good.txt +60 -0
  448. data/spec/fixtures/X222-HC837/6-bad.txt +50 -0
  449. data/spec/fixtures/X222-HC837/6-good.txt +39 -0
  450. data/spec/fixtures/X222-HC837/7-bad.txt +93 -0
  451. data/spec/fixtures/X222-HC837/7-good.txt +78 -0
  452. data/spec/fixtures/X222-HC837/8-bad.txt +64 -0
  453. data/spec/fixtures/X222-HC837/8-good.txt +52 -0
  454. data/spec/fixtures/X222-HC837/9-bad.txt +56 -0
  455. data/spec/fixtures/X222-HC837/9-good.txt +38 -0
  456. data/spec/fixtures/X223-HC837/1-bad.txt +66 -0
  457. data/spec/fixtures/X223-HC837/1-good.txt +53 -0
  458. data/spec/fixtures/X223-HC837/2-bad.txt +69 -0
  459. data/spec/fixtures/X223-HC837/2-good.txt +60 -0
  460. data/spec/fixtures/X223-HC837/3-bad.txt +89 -0
  461. data/spec/fixtures/X223-HC837/3-good.txt +61 -0
  462. data/spec/fixtures/X223-HC837/4-bad.txt +60 -0
  463. data/spec/fixtures/X223-HC837/4-good.txt +40 -0
  464. data/spec/fixtures/X223-HC837/5-bad.txt +75 -0
  465. data/spec/fixtures/X223-HC837/5-good.txt +58 -0
  466. data/spec/fixtures/X224-HC837/1-bad.txt +54 -0
  467. data/spec/fixtures/X224-HC837/1-good.txt +44 -0
  468. data/spec/fixtures/X224-HC837/2a-bad.txt +52 -0
  469. data/spec/fixtures/X224-HC837/2a-good.txt +42 -0
  470. data/spec/fixtures/X224-HC837/2b-bad.txt +67 -0
  471. data/spec/fixtures/X224-HC837/2b-good.txt +52 -0
  472. data/spec/fixtures/X224-HC837/3-bad.txt +67 -0
  473. data/spec/fixtures/X224-HC837/3-good.txt +51 -0
  474. data/spec/fixtures/X224-HC837/4-bad.txt +49 -0
  475. data/spec/fixtures/X224-HC837/4-good.txt +40 -0
  476. data/spec/fixtures/X230-FA997/1-bad.txt +19 -0
  477. data/spec/fixtures/X230-FA997/1-good.txt +16 -0
  478. data/spec/fixtures/X231-FA999/1-bad.txt +20 -0
  479. data/spec/fixtures/X231-FA999/1-good.txt +20 -0
  480. data/spec/fixtures/X279-HB271/1-bad.txt +36 -0
  481. data/spec/fixtures/X279-HB271/1-good.txt +30 -0
  482. data/spec/fixtures/X279-HB271/2-bad.txt +22 -0
  483. data/spec/fixtures/X279-HB271/2-good.txt +16 -0
  484. data/spec/fixtures/X279-HB271/3-bad.txt +44 -0
  485. data/spec/fixtures/X279-HB271/3-good.txt +36 -0
  486. data/spec/fixtures/X279-HS270/1-bad.txt +29 -0
  487. data/spec/fixtures/X279-HS270/1-good.txt +23 -0
  488. data/spec/fixtures/X279-HS270/2-bad.txt +32 -0
  489. data/spec/fixtures/X279-HS270/2-good.txt +25 -0
  490. data/spec/spec_helper.rb +34 -0
  491. data/spec/support/fixtures.rb +26 -0
  492. data/spec/support/matchers/either_matchers.rb +26 -0
  493. data/spec/support/matchers/navigation_matchers.rb +247 -0
  494. data/spec/support/node.rb +41 -0
  495. data/spec/support/quickcheck/characters.rb +28 -0
  496. data/spec/support/quickcheck/property.rb +105 -0
  497. data/spec/support/quickcheck/serialized_edi.rb +399 -0
  498. data/spec/support/quickcheck.rb +302 -0
  499. data/spec/support/rcov.rb +34 -0
  500. metadata +577 -0
@@ -0,0 +1,775 @@
1
+ require "spec_helper"
2
+
3
+ describe Stupidedi::Reader::TokenReader do
4
+ include QuickCheck::SerializedEdi::Macro
5
+
6
+ let(:ty) { Stupidedi::Versions::FunctionalGroups::FiftyTen::ElementTypes }
7
+ let(:r) { ty::R .new("R" , "Float", 1, 1) }
8
+ let(:n0) { ty::N0.new("N0", "Whole Number", 1, 1) }
9
+ let(:n1) { ty::N1.new("N1", "Tenths Place", 1, 1) }
10
+ let(:n2) { ty::N2.new("N2", "Money", 1, 1) }
11
+ let(:n3) { ty::N3.new("N3", "N.nnn", 1, 1) }
12
+ let(:n4) { ty::N4.new("N4", "N.nnnn", 1, 1) }
13
+ let(:n5) { ty::N5.new("N5", "N.nnnnn", 1, 1) }
14
+ let(:n6) { ty::N6.new("N6", "N.nnnnnn", 1, 1) }
15
+ let(:n7) { ty::N7.new("N7", "N.nnnnnnn", 1, 1) }
16
+ let(:n8) { ty::N8.new("N8", "N.nnnnnnnnn", 1, 1) }
17
+ let(:n9) { ty::N9.new("N9", "N.nnnnnnnnnn", 1, 1) }
18
+ let(:id) { ty::ID.new("ID", "Qualifier", 1, 1) }
19
+ let(:an) { ty::AN.new("AN", "Free Text", 1, 1) }
20
+ let(:dt) { ty::DT.new("DT", "Date", 8, 8) }
21
+ let(:tm) { ty::TM.new("TM", "Time", 4, 6) }
22
+
23
+ let(:rq) { Stupidedi::Versions::FunctionalGroups::FiftyTen::ElementReqs }
24
+ let(:s) { Stupidedi::Schema }
25
+
26
+ let(:separators) do
27
+ Stupidedi::Reader::Separators.new(":", "^", "*", "~")
28
+ end
29
+
30
+ let(:dictionary) do
31
+ Stupidedi::Reader::SegmentDict.empty
32
+ end
33
+
34
+ def mkseparators(component = ":", repetition = "^", element = "*", segment = "~")
35
+ Stupidedi::Reader::Separators.new(component, repetition, element, segment)
36
+ end
37
+
38
+ def mkreader(input, separators = separators, segment_dict = dictionary)
39
+ Stupidedi::Reader::TokenReader.new(input, separators, segment_dict)
40
+ end
41
+
42
+ describe "#stream?" do
43
+ it "returns false" do
44
+ mkreader("").should_not be_stream
45
+ end
46
+ end
47
+
48
+ describe "#empty?" do
49
+ context "with no input available" do
50
+ it "is true" do
51
+ mkreader("").should be_empty
52
+ end
53
+ end
54
+
55
+ context "with some input available" do
56
+ it "is false" do
57
+ mkreader("abc").should_not be_empty
58
+ end
59
+ end
60
+ end
61
+
62
+ describe "#consume_prefix(s)" do
63
+ context "when s is empty" do
64
+ it "returns self" do
65
+ reader = mkreader("abc")
66
+ result = reader.consume_prefix("")
67
+ result.should be_defined
68
+ result.map{|x| x.should == reader }
69
+ end
70
+ end
71
+
72
+ context "when s is the entire input" do
73
+ property("returns empty reader") do
74
+ string(:alnum)
75
+ end.check do |s|
76
+ reader = mkreader(s)
77
+ result = reader.consume_prefix(s)
78
+ result.should be_defined
79
+ result.map{|x| x.should be_empty }
80
+ end
81
+ end
82
+
83
+ context "when s is a prefix of the input" do
84
+ property("returns the remaining input") do
85
+ string(:alnum).bind{|s| s.split_at(between(0, s.length)) }
86
+ end.check do |p, s|
87
+ reader = mkreader("#{p}#{s}")
88
+ result = reader.consume_prefix(p)
89
+ result.should be_defined
90
+ result.map{|x| x.input.should == s }
91
+ end
92
+ end
93
+
94
+ context "when s is not a prefix of the input" do
95
+ property("returns a failure") do
96
+ a = with(:size, between(0, 5)) { string(:alnum) }
97
+ b = with(:size, between(0, 9)) { string(:alnum) }
98
+ guard(a.take(b.length) != b)
99
+ [a, b]
100
+ end.check do |a, b|
101
+ reader = mkreader(a)
102
+ result = reader.consume_prefix(b)
103
+ result.should_not be_defined
104
+ result.remainder.should == a
105
+ end
106
+ end
107
+ end
108
+
109
+ describe "#consume(s)" do
110
+ context "when s is empty" do
111
+ it "returns self" do
112
+ reader = mkreader("abc")
113
+ result = reader.consume("")
114
+ result.should be_defined
115
+ result.map{|x| x.should == reader }
116
+ end
117
+ end
118
+
119
+ context "when s is the entire input" do
120
+ property("returns empty reader") do
121
+ string(:alnum)
122
+ end.check do |s|
123
+ reader = mkreader(s)
124
+ result = reader.consume(s)
125
+ result.should be_defined
126
+ result.map{|x| x.should be_empty }
127
+ end
128
+ end
129
+
130
+ context "when s is a prefix of the input" do
131
+ property("returns the remaining input") do
132
+ string(:alnum).bind{|s| s.split_at(between(0, s.length)) }
133
+ end.check do |p, s|
134
+ reader = mkreader("#{p}#{s}")
135
+ result = reader.consume(p)
136
+ result.should be_defined
137
+ result.map{|x| x.input.should == s }
138
+ end
139
+ end
140
+
141
+ context "when s is a suffix of the input" do
142
+ property("returns empty reader") do
143
+ p, s = string(:alnum).bind{|s| s.split_at(between(0, s.length)) }
144
+ guard("#{p}#{s}".index(s) >= p.length)
145
+ [p, s]
146
+ end.check do |p, s|
147
+ reader = mkreader("#{p}#{s}")
148
+ result = reader.consume(s)
149
+ result.should be_defined
150
+ result.map{|x| x.should be_empty }
151
+ end
152
+ end
153
+
154
+ context "when s does not occur in the input" do
155
+ property("returns a failure") do
156
+ a = with(:size, between(0, 5)) { string(:alnum) }
157
+ b = with(:size, between(0, 9)) { string(:alnum) }
158
+ guard(a.index(b).nil?)
159
+
160
+ [a, b]
161
+ end.check do |a, b|
162
+ reader = mkreader(a)
163
+ result = reader.consume(b)
164
+ result.should_not be_defined
165
+ result.remainder.should == a
166
+ end
167
+ end
168
+
169
+ context "when s occurs in the middle of the input" do
170
+ property("returns the remaining input") do
171
+ a = string(:alnum)
172
+ b = string(:alnum)
173
+ c = string(:alnum)
174
+ guard(a != b)
175
+ [a, b, c]
176
+ end.check do |a, b, c|
177
+ reader = mkreader("#{a}#{b}#{c}")
178
+ result = reader.consume(b)
179
+ result.should be_defined
180
+ result.map{|x| x.input.should == c }
181
+ end
182
+ end
183
+ end
184
+
185
+ describe "#read_character" do
186
+ context "when the input is empty" do
187
+ it "returns a failure" do
188
+ reader = mkreader("")
189
+ result = reader.read_character
190
+ result.should_not be_defined
191
+ result.remainder.should == ""
192
+ result.reason.should =~ /less than one character available/
193
+ end
194
+ end
195
+
196
+ context "when the input is not empty" do
197
+ it "returns the remaining input" do
198
+ reader = mkreader("abc")
199
+ result = reader.read_character
200
+ result.should be_defined
201
+ result.map{|x, remainder| remainder.input.should == "bc" }
202
+ end
203
+
204
+ it "returns one character" do
205
+ reader = mkreader("abc")
206
+ result = reader.read_character
207
+ result.should be_defined
208
+ result.map{|x, remainder| x.should == "a" }
209
+ end
210
+ end
211
+ end
212
+
213
+ describe "#read_segment" do
214
+ context "when the input is empty" do
215
+ it "returns a failure" do
216
+ reader = mkreader("")
217
+ result = reader.read_segment
218
+ result.should_not be_defined
219
+ result.should_not be_fatal
220
+ result.remainder.should == ""
221
+ result.reason.should =~ /reached end of input/
222
+ end
223
+ end
224
+
225
+ context "when the input does not start with a valid segment identifier" do
226
+ it "returns a failure" do
227
+ # Segment ID cannot start with element separator "*"
228
+ reader = mkreader("*ABC")
229
+ result = reader.read_segment
230
+ result.should be_fatal
231
+ result.should_not be_defined
232
+ result.remainder.should == "*ABC"
233
+ result.reason.should =~ /found "\*" instead of segment identifier/
234
+ end
235
+
236
+ it "returns a failure" do
237
+ # Segment ID cannot start with segment terminator "~"
238
+ reader = mkreader("~ABC")
239
+ result = reader.read_segment
240
+ result.should be_fatal
241
+ result.should_not be_defined
242
+ result.remainder.should == "~ABC"
243
+ result.reason.should =~ /found "~" instead of segment identifier/
244
+ end
245
+
246
+ it "returns a failure" do
247
+ # Segment ID cannot start with a number
248
+ reader = mkreader("0ABC")
249
+ result = reader.read_segment
250
+ result.should be_fatal
251
+ result.should_not be_defined
252
+ result.remainder.should == "0ABC"
253
+ result.reason.should =~ /found "0ABC" instead of segment identifier/
254
+ end
255
+
256
+ it "returns a failure" do
257
+ # Segment ID cannot be followed by component separator ":"
258
+ reader = mkreader("ABC:")
259
+ result = reader.read_segment
260
+ result.should be_fatal
261
+ result.should_not be_defined
262
+ result.remainder.should == "ABC:"
263
+ result.reason.should =~ /found ":" following segment identifier/
264
+ end
265
+
266
+ it "returns a failure" do
267
+ # Segment ID cannot be followed by repetition separator "^"
268
+ reader = mkreader("ABC^")
269
+ result = reader.read_segment
270
+ result.should be_fatal
271
+ result.should_not be_defined
272
+ result.remainder.should == "ABC^"
273
+ result.reason.should =~ /found "\^" following segment identifier/
274
+ end
275
+
276
+ it "returns a failure" do
277
+ # Segment ID must be followed by element delimiter "~" or segment terminator "*"
278
+ reader = mkreader("ABCD")
279
+ result = reader.read_segment
280
+ result.should be_fatal
281
+ result.should_not be_defined
282
+ result.remainder.should == "ABCD"
283
+ result.reason.should =~ /found "D" following segment identifier/
284
+ end
285
+ end
286
+
287
+ context "when the input does not have a segment terminator" do
288
+ it "returns a failure" do
289
+ reader = mkreader("XYZ*A*B")
290
+ result = reader.read_segment
291
+ result.should be_fatal
292
+ result.should_not be_defined
293
+ result.remainder.should == "B"
294
+ result.reason.should =~ /reached end of input/
295
+ end
296
+ end
297
+
298
+ context "when the input starts with an ise segment" do
299
+ it "the remainder is a StreamReader" do
300
+ reader = mkreader("IEA~...")
301
+ result = reader.read_segment
302
+ result.should be_defined
303
+ result.map do |value, remainder|
304
+ value.id.should == :IEA
305
+ value.should have(0).element_toks
306
+ remainder.input.should == "..."
307
+ remainder.should be_stream
308
+ end
309
+ end
310
+
311
+ it "the remainder is a StreamReader" do
312
+ reader = mkreader("IEA*A*B~...")
313
+ result = reader.read_segment
314
+ result.should be_defined
315
+ result.map do |value, remainder|
316
+ value.id.should == :IEA
317
+ value.should have(2).element_toks
318
+ remainder.input.should == "..."
319
+ remainder.should be_stream
320
+ end
321
+ end
322
+ end
323
+
324
+ context "when the input contains no elements" do
325
+ it "returns the empty segment token" do
326
+ reader = mkreader("ABC~...")
327
+ result = reader.read_segment
328
+ result.should be_defined
329
+ result.map do |value, remainder|
330
+ value.id.should == :ABC
331
+ value.should have(0).element_toks
332
+ remainder.input.should == "..."
333
+ end
334
+ end
335
+
336
+ it "returns the remaining input" do
337
+ reader = mkreader("ABC~...")
338
+ result = reader.read_segment
339
+ result.should be_defined
340
+ result.map{|value, remainder| remainder.input.should == "..." }
341
+ end
342
+ end
343
+
344
+ context "when the input contains one element" do
345
+ it "returns the segment token" do
346
+ reader = mkreader("ABC*O~...")
347
+ result = reader.read_segment
348
+ result.should be_defined
349
+ result.map do |value, remainder|
350
+ value.id.should == :ABC
351
+ value.should have(1).element_toks
352
+ value.element_toks.head.value.should == "O"
353
+ end
354
+ end
355
+
356
+ it "returns the segment token" do
357
+ reader = mkreader("ABC*~...")
358
+ result = reader.read_segment
359
+ result.should be_defined
360
+ result.map do |value, remainder|
361
+ value.id.should == :ABC
362
+ value.should have(1).element_toks
363
+ value.element_toks.head.value.should == ""
364
+ end
365
+ end
366
+
367
+ it "returns the remaining input" do
368
+ reader = mkreader("ABC*O~...")
369
+ result = reader.read_segment
370
+ result.should be_defined
371
+ result.map{|value, remainder| remainder.input.should == "..." }
372
+ end
373
+ end
374
+
375
+ context "when the input contains many elements" do
376
+ it "returns the segment token" do
377
+ reader = mkreader("ABC*M*N*O~...")
378
+ result = reader.read_segment
379
+ result.should be_defined
380
+ result.map do |value, remainder|
381
+ value.id.should == :ABC
382
+ value.should have(3).element_toks
383
+ value.element_toks.map(&:value).should == %w(M N O)
384
+ end
385
+ end
386
+
387
+ it "returns the segment token" do
388
+ reader = mkreader("ABC***~...")
389
+ result = reader.read_segment
390
+ result.should be_defined
391
+ result.map do |value, remainder|
392
+ value.id.should == :ABC
393
+ value.should have(3).element_toks
394
+ value.element_toks.map(&:value).should == ["", "", ""]
395
+ end
396
+ end
397
+
398
+ it "returns the segment token" do
399
+ reader = mkreader("ABC***O~...")
400
+ result = reader.read_segment
401
+ result.should be_defined
402
+ result.map do |value, remainder|
403
+ value.id.should == :ABC
404
+ value.should have(3).element_toks
405
+ value.element_toks.map(&:value).should == ["", "", "O"]
406
+ end
407
+ end
408
+
409
+ it "returns the remaining input" do
410
+ reader = mkreader("ABC*M*O~...")
411
+ result = reader.read_segment
412
+ result.should be_defined
413
+ result.map do |value, remainder|
414
+ remainder.input.should == "..."
415
+ end
416
+ end
417
+ end
418
+
419
+ context "when the input contains too many elements" do
420
+ let(:segment_def) do
421
+ s::SegmentDef.build(:SEG, "Dummy Segment", "",
422
+ id.simple_use(rq::Mandatory, s::RepeatCount.bounded(1)),
423
+ id.simple_use(rq::Mandatory, s::RepeatCount.bounded(1)))
424
+ end
425
+
426
+ let(:dictionary) do
427
+ Stupidedi::Reader::SegmentDict.build(:SEG => segment_def)
428
+ end
429
+
430
+ it "returns the segment token" do
431
+ reader = mkreader("SEG*W*X*Y*Z~...", separators, dictionary)
432
+ result = reader.read_segment
433
+ result.should be_defined
434
+ result.map do |value, remainder|
435
+ value.should have(4).element_toks
436
+ value.element_toks.map(&:value).should == %w(W X Y Z)
437
+ end
438
+ end
439
+
440
+ it "returns the remaining input" do
441
+ reader = mkreader("SEG*W*X*Y*Z~...", separators, dictionary)
442
+ result = reader.read_segment
443
+ result.should be_defined
444
+ result.map do |value, remainder|
445
+ remainder.input.should == "..."
446
+ end
447
+ end
448
+ end
449
+
450
+ context "when the input has a non-repeatable simple element" do
451
+ # let(:segment_def) do
452
+ # s::SegmentDef.build(:SEG, "Dummy Segment", "",
453
+ # id.simple_use(rq::Mandatory, s::RepeatCount.bounded(1)),
454
+ # id.simple_use(rq::Mandatory, s::RepeatCount.bounded(1)))
455
+ # end
456
+
457
+ # let(:dictionary) do
458
+ # Stupidedi::Reader::SegmentDict.build(:SEG => segment_def)
459
+ # end
460
+
461
+ context "with a repetition separator" do
462
+ it "reads the separator as data" do
463
+ reader = mkreader("SEG*W^X*Y^Z~...", separators, dictionary)
464
+ result = reader.read_segment
465
+ result.should be_defined
466
+ result.map do |value, remainder|
467
+ value.should have(2).element_toks
468
+ value.element_toks.head.value.should == "W^X"
469
+ value.element_toks.last.value.should == "Y^Z"
470
+ end
471
+ end
472
+
473
+ it "returns the remaining input" do
474
+ reader = mkreader("SEG*W^X*Y^Z~...", separators, dictionary)
475
+ result = reader.read_segment
476
+ result.should be_defined
477
+ result.map do |value, remainder|
478
+ remainder.input.should == "..."
479
+ end
480
+ end
481
+ end
482
+
483
+ context "with a component separator" do
484
+ it "reads the separator as data" do
485
+ reader = mkreader("SEG*W:X*Y:Z~...", separators, dictionary)
486
+ result = reader.read_segment
487
+ result.should be_defined
488
+ result.map do |value, remainder|
489
+ value.should have(2).element_toks
490
+ value.element_toks.head.value.should == "W:X"
491
+ value.element_toks.last.value.should == "Y:Z"
492
+ end
493
+ end
494
+
495
+ it "returns the remaining input" do
496
+ reader = mkreader("SEG*W:X*Y:Z~...", separators, dictionary)
497
+ result = reader.read_segment
498
+ result.should be_defined
499
+ result.map do |value, remainder|
500
+ remainder.input.should == "..."
501
+ end
502
+ end
503
+ end
504
+ end
505
+
506
+ context "when the input has a non-repeatable composite element" do
507
+ let(:segment_def) do
508
+ s::SegmentDef.build(:SEG, "Dummy Segment", "",
509
+ id.simple_use(rq::Mandatory, s::RepeatCount.bounded(1)),
510
+ s::CompositeElementDef.build(:C000, "Dummy Composite", "",
511
+ id.component_use(rq::Mandatory),
512
+ id.component_use(rq::Mandatory),
513
+ id.component_use(rq::Mandatory)).
514
+ simple_use(rq::Mandatory, s::RepeatCount.bounded(1)),
515
+ s::CompositeElementDef.build(:C000, "Dummy Composite", "",
516
+ id.component_use(rq::Mandatory),
517
+ id.component_use(rq::Mandatory)).
518
+ simple_use(rq::Mandatory, s::RepeatCount.bounded(1)))
519
+ end
520
+
521
+ let(:dictionary) do
522
+ Stupidedi::Reader::SegmentDict.build(:SEG => segment_def)
523
+ end
524
+
525
+ context "and one component" do
526
+ it "returns the segment token" do
527
+ reader = mkreader("SEG*W*X*Y~...", separators, dictionary)
528
+ result = reader.read_segment
529
+ result.should be_defined
530
+ result.map do |value, remainder|
531
+ value.should have(3).element_toks
532
+ value.element_toks.head.value.should == "W"
533
+
534
+ value.element_toks.at(1).should have(1).component_toks
535
+ value.element_toks.at(1).component_toks.head.value.should == "X"
536
+
537
+ value.element_toks.at(2).should have(1).component_toks
538
+ value.element_toks.at(2).component_toks.head.value.should == "Y"
539
+ end
540
+ end
541
+
542
+ it "returns the remaining input" do
543
+ reader = mkreader("SEG*W*X*Y~...", separators, dictionary)
544
+ result = reader.read_segment
545
+ result.should be_defined
546
+ result.map do |value, remainder|
547
+ remainder.input.should == "..."
548
+ end
549
+ end
550
+ end
551
+
552
+ context "and many components" do
553
+ it "returns the segment token" do
554
+ reader = mkreader("SEG*W*X:Y*M:N~...", separators, dictionary)
555
+ result = reader.read_segment
556
+ result.should be_defined
557
+ result.map do |value, remainder|
558
+ value.should have(3).element_toks
559
+ value.element_toks.head.value.should == "W"
560
+
561
+ value.element_toks.at(1).should have(2).component_toks
562
+ value.element_toks.at(1).component_toks.head.value.should == "X"
563
+ value.element_toks.at(1).component_toks.last.value.should == "Y"
564
+
565
+ value.element_toks.at(2).should have(2).component_toks
566
+ value.element_toks.at(2).component_toks.head.value.should == "M"
567
+ value.element_toks.at(2).component_toks.last.value.should == "N"
568
+ end
569
+ end
570
+
571
+ it "returns the remaining input" do
572
+ reader = mkreader("SEG*W*X:Y*M:N~...", separators, dictionary)
573
+ result = reader.read_segment
574
+ result.should be_defined
575
+ result.map do |value, remainder|
576
+ remainder.input.should == "..."
577
+ end
578
+ end
579
+ end
580
+
581
+ context "and too many components" do
582
+ it "returns the segment token" do
583
+ reader = mkreader("SEG*W*X::Z*M:N:O:P~...", separators, dictionary)
584
+ result = reader.read_segment
585
+ result.should be_defined
586
+ result.map do |value, remainder|
587
+ value.should have(3).element_toks
588
+ value.element_toks.head.value.should == "W"
589
+ value.element_toks.at(1).component_toks.map(&:value).should == ["X", "", "Z"]
590
+ value.element_toks.at(2).component_toks.map(&:value).should == %w(M N O P)
591
+ end
592
+ end
593
+
594
+ it "returns the remaining input" do
595
+ reader = mkreader("SEG*W*X:Y:Z*M:N:O:P~...", separators, dictionary)
596
+ result = reader.read_segment
597
+ result.should be_defined
598
+ result.map do |value, remainder|
599
+ remainder.input.should == "..."
600
+ end
601
+ end
602
+ end
603
+
604
+ context "and a component with a repetition separator" do
605
+ it "returns the segment token" do
606
+ reader = mkreader("SEG*W*X^Y:Z*M:N^O~...", separators, dictionary)
607
+ result = reader.read_segment
608
+ result.should be_defined
609
+ result.map do |value, remainder|
610
+ value.should have(3).element_toks
611
+ value.element_toks.head.value.should == "W"
612
+ value.element_toks.at(1).component_toks.map(&:value).should == %w(X^Y Z)
613
+ value.element_toks.at(2).component_toks.map(&:value).should == %w(M N^O)
614
+ end
615
+ end
616
+ end
617
+ end
618
+
619
+ context "" do
620
+ let(:segment_def) do
621
+ s::SegmentDef.build(:SEG, "Dummy Segment", "",
622
+ id.simple_use(rq::Mandatory, s::RepeatCount.bounded(1)),
623
+ id.simple_use(rq::Mandatory, s::RepeatCount.bounded(2)))
624
+ end
625
+
626
+ let(:dictionary) do
627
+ Stupidedi::Reader::SegmentDict.build(:SEG => segment_def)
628
+ end
629
+
630
+ context "when the input has no occurances of a repeatable simple element" do
631
+ it "returns the segment token" do
632
+ reader = mkreader("SEG**~...", separators, dictionary)
633
+ result = reader.read_segment
634
+ result.should be_defined
635
+ result.map do |value, remainder|
636
+ value.should have(2).element_toks
637
+ value.element_toks.head.value.should == ""
638
+ # value.element_toks.last.should have(0).element_toks
639
+ end
640
+ end
641
+
642
+ it "returns the remaining input" do
643
+ reader = mkreader("SEG**~...", separators, dictionary)
644
+ result = reader.read_segment
645
+ result.should be_defined
646
+ result.map do |value, remainder|
647
+ remainder.input.should == "..."
648
+ end
649
+ end
650
+ end
651
+
652
+ context "when the input has one occurance of a repeatable simple element" do
653
+ it "returns the segment token" do
654
+ reader = mkreader("SEG**X~...", separators, dictionary)
655
+ result = reader.read_segment
656
+ result.should be_defined
657
+ result.map do |value, remainder|
658
+ value.should have(2).element_toks
659
+ value.element_toks.last.should have(1).element_toks
660
+ value.element_toks.last.element_toks.head.value.should == "X"
661
+ end
662
+ end
663
+ end
664
+
665
+ context "when the input has many occurances of a repeatable simple element" do
666
+ it "returns the segment token" do
667
+ reader = mkreader("SEG**X^Y~...", separators, dictionary)
668
+ result = reader.read_segment
669
+ result.should be_defined
670
+ result.map do |value, remainder|
671
+ value.should have(2).element_toks
672
+ value.element_toks.last.should have(2).element_toks
673
+ value.element_toks.last.element_toks.head.value.should == "X"
674
+ value.element_toks.last.element_toks.last.value.should == "Y"
675
+ end
676
+ end
677
+ end
678
+
679
+ context "when the input has too many occurances of a repeatable simple element" do
680
+ it "returns the segment token" do
681
+ reader = mkreader("SEG**X^Y^Z~...", separators, dictionary)
682
+ result = reader.read_segment
683
+ result.should be_defined
684
+ result.map do |value, remainder|
685
+ value.should have(2).element_toks
686
+ value.element_toks.last.should have(3).element_toks
687
+ value.element_toks.last.element_toks.map(&:value).should == %w(X Y Z)
688
+ end
689
+ end
690
+ end
691
+ end
692
+
693
+ context "" do
694
+ let(:segment_def) do
695
+ s::SegmentDef.build(:SEG, "Dummy Segment", "",
696
+ id.simple_use(rq::Mandatory, s::RepeatCount.bounded(1)),
697
+ s::CompositeElementDef.build(:C000, "Dummy Composite", "",
698
+ id.component_use(rq::Mandatory),
699
+ id.component_use(rq::Mandatory),
700
+ id.component_use(rq::Mandatory)).
701
+ simple_use(rq::Mandatory, s::RepeatCount.bounded(2)),
702
+ s::CompositeElementDef.build(:C000, "Dummy Composite", "",
703
+ id.component_use(rq::Mandatory),
704
+ id.component_use(rq::Mandatory)).
705
+ simple_use(rq::Mandatory, s::RepeatCount.bounded(1)))
706
+ end
707
+
708
+ let(:dictionary) do
709
+ Stupidedi::Reader::SegmentDict.build(:SEG => segment_def)
710
+ end
711
+
712
+ context "when the input has no occurances of a repeatable composite element" do
713
+ it "returns the segment token" do
714
+ reader = mkreader("SEG***~...", separators, dictionary)
715
+ result = reader.read_segment
716
+ result.should be_defined
717
+ result.map do |value, remainder|
718
+ value.should have(3).element_toks
719
+ # value.element_toks.at(1).should have(0).element_toks
720
+ end
721
+ end
722
+ end
723
+
724
+ context "when the input has one occurance of a repeatable composite element" do
725
+ it "returns the segment token" do
726
+ reader = mkreader("SEG**A:B*~...", separators, dictionary)
727
+ result = reader.read_segment
728
+ result.should be_defined
729
+ result.map do |value, remainder|
730
+ value.should have(3).element_toks
731
+ value.element_toks.at(1).should have(1).element_toks
732
+ value.element_toks.at(1).element_toks.should have(1).element_toks
733
+ value.element_toks.at(1).element_toks.head.should have(2).component_toks
734
+ value.element_toks.at(1).element_toks.head.component_toks.head.value.should == "A"
735
+ value.element_toks.at(1).element_toks.head.component_toks.last.value.should == "B"
736
+ end
737
+ end
738
+ end
739
+
740
+ context "when the input has many occurances of a repeatable composite element" do
741
+ it "returns the segment token" do
742
+ reader = mkreader("SEG**A:B^C:D*~...", separators, dictionary)
743
+ result = reader.read_segment
744
+ result.should be_defined
745
+ result.map do |value, remainder|
746
+ value.should have(3).element_toks
747
+ value.element_toks.at(1).element_toks.head.should have(2).component_toks
748
+ value.element_toks.at(1).element_toks.head.component_toks.head.value.should == "A"
749
+ value.element_toks.at(1).element_toks.head.component_toks.last.value.should == "B"
750
+ value.element_toks.at(1).element_toks.last.component_toks.head.value.should == "C"
751
+ value.element_toks.at(1).element_toks.last.component_toks.last.value.should == "D"
752
+ end
753
+ end
754
+ end
755
+
756
+ context "when the input has too many occurances of a repeatable composite element" do
757
+ it "returns the segment token" do
758
+ reader = mkreader("SEG**A:B^C^D:E:F*~...", separators, dictionary)
759
+ result = reader.read_segment
760
+ result.should be_defined
761
+ result.map do |value, remainder|
762
+ value.should have(3).element_toks
763
+ value.element_toks.at(1).element_toks.head.should have(2).component_toks
764
+ value.element_toks.at(1).element_toks.at(0).component_toks.head.value.should == "A"
765
+ value.element_toks.at(1).element_toks.at(0).component_toks.last.value.should == "B"
766
+ value.element_toks.at(1).element_toks.at(1).component_toks.head.value.should == "C"
767
+ value.element_toks.at(1).element_toks.at(2).component_toks.head.value.should == "D"
768
+ value.element_toks.at(1).element_toks.at(2).component_toks.last.value.should == "F"
769
+ end
770
+ end
771
+ end
772
+ end
773
+ end
774
+
775
+ end