facets 1.2.1 → 1.3.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 (488) hide show
  1. data/ProjectInfo +32 -25
  2. data/data/facets/index.yml +30 -6
  3. data/data/facets/units/binary/base.yaml +12 -0
  4. data/data/facets/units/binary/extra.yaml +8 -0
  5. data/data/facets/units/cex.yaml +7 -0
  6. data/data/facets/units/currency/base.yaml +268 -0
  7. data/data/facets/units/default.yaml +22 -0
  8. data/data/facets/units/dump_yaml.rb +309 -0
  9. data/data/facets/units/si/base.yaml +36 -0
  10. data/data/facets/units/si/derived.yaml +133 -0
  11. data/data/facets/units/si/extra.yaml +107 -0
  12. data/data/facets/units/standard.yaml +5 -0
  13. data/data/facets/units/uk.yaml +16 -0
  14. data/data/facets/units/uk/base.yaml +107 -0
  15. data/data/facets/units/us.yaml +16 -0
  16. data/data/facets/units/us/base.yaml +112 -0
  17. data/data/facets/units/xmethods/cached.yaml +83 -0
  18. data/data/facets/units/xmethods/mapping.yaml +85 -0
  19. data/lib/facet/array/join_sentence.rb +1 -0
  20. data/lib/facet/class/cattr.rb +1 -0
  21. data/lib/facet/class/cattr_accessor.rb +1 -0
  22. data/lib/facet/class/cattr_reader.rb +1 -0
  23. data/lib/facet/class/cattr_writer.rb +1 -0
  24. data/lib/facet/elementor.rb +1 -0
  25. data/lib/facet/enumerable/accumulate.rb +1 -0
  26. data/lib/facet/enumerable/collect_if.rb +1 -0
  27. data/lib/facet/enumerable/map_if.rb +1 -0
  28. data/lib/facet/file/self/append.rb +1 -0
  29. data/lib/facet/file/self/read_binary.rb +1 -0
  30. data/lib/facet/file/self/write.rb +1 -0
  31. data/lib/facet/json.rb +1 -0
  32. data/lib/facet/kernel/__self__.rb +1 -0
  33. data/lib/facet/kernel/methodname.rb +1 -0
  34. data/lib/facet/module/attr_query.rb +1 -0
  35. data/lib/facet/module/attr_validator.rb +1 -0
  36. data/lib/facet/module/inherit.rb +1 -0
  37. data/lib/facet/module/let.rb +1 -0
  38. data/lib/facet/module/mattr.rb +1 -0
  39. data/lib/facet/module/mattr_accessor.rb +1 -0
  40. data/lib/facet/module/mattr_reader.rb +1 -0
  41. data/lib/facet/module/mattr_writer.rb +1 -0
  42. data/lib/facet/module/singleton_to_module.rb +1 -0
  43. data/lib/facet/nilclass/op_cmp.rb +1 -0
  44. data/lib/facet/nilclass/succ.rb +1 -0
  45. data/lib/facet/recorder.rb +1 -0
  46. data/lib/facet/xoxo.rb +1 -0
  47. data/lib/facets/core/array.rb +1 -0
  48. data/lib/facets/core/array/join_sentence.rb +12 -0
  49. data/lib/facets/core/class.rb +4 -0
  50. data/lib/facets/core/{module → class}/cattr.rb +7 -9
  51. data/lib/facets/core/class/cattr_accessor.rb +2 -0
  52. data/lib/facets/core/class/cattr_reader.rb +3 -0
  53. data/lib/facets/core/class/cattr_writer.rb +2 -0
  54. data/lib/facets/core/dir/self/ls_r.rb +4 -9
  55. data/lib/facets/core/enumerable.rb +3 -0
  56. data/lib/facets/core/enumerable/accumulate.rb +25 -0
  57. data/lib/facets/core/enumerable/collect_if.rb +15 -0
  58. data/lib/facets/core/enumerable/ew.rb +1 -5
  59. data/lib/facets/core/enumerable/map_if.rb +3 -0
  60. data/lib/facets/core/file.rb +3 -0
  61. data/lib/facets/core/file/self/append.rb +8 -0
  62. data/lib/facets/core/file/self/create.rb +14 -8
  63. data/lib/facets/core/file/self/open_as_string.rb +31 -13
  64. data/lib/facets/core/file/self/read_binary.rb +8 -0
  65. data/lib/facets/core/file/self/read_list.rb +11 -7
  66. data/lib/facets/core/file/self/write.rb +8 -0
  67. data/lib/facets/core/fileutils/wc.rb +4 -9
  68. data/lib/facets/core/fileutils/which.rb +4 -9
  69. data/lib/facets/core/kernel.rb +2 -1
  70. data/lib/facets/core/kernel/__self__.rb +32 -0
  71. data/lib/facets/core/kernel/as.rb +1 -1
  72. data/lib/facets/core/kernel/assign_from.rb +3 -3
  73. data/lib/facets/core/kernel/assign_with.rb +2 -0
  74. data/lib/facets/core/kernel/me.rb +3 -2
  75. data/lib/facets/core/kernel/method_name.rb +2 -49
  76. data/lib/facets/core/kernel/methodname.rb +49 -0
  77. data/lib/facets/core/module.rb +9 -4
  78. data/lib/facets/core/module/attr_query.rb +56 -0
  79. data/lib/facets/core/module/attr_validator.rb +18 -0
  80. data/lib/facets/core/module/inherit.rb +70 -0
  81. data/lib/facets/core/module/integrate.rb +1 -1
  82. data/lib/facets/core/module/let.rb +55 -0
  83. data/lib/facets/core/module/mattr.rb +180 -0
  84. data/lib/facets/core/module/{cattr_accessor.rb → mattr_accessor.rb} +0 -0
  85. data/lib/facets/core/module/{cattr_reader.rb → mattr_reader.rb} +0 -0
  86. data/lib/facets/core/module/{cattr_writer.rb → mattr_writer.rb} +0 -0
  87. data/lib/facets/core/module/on_included.rb +3 -1
  88. data/lib/facets/core/module/singleton_to_module.rb +23 -0
  89. data/lib/facets/core/nilclass.rb +2 -0
  90. data/lib/facets/core/string/methodize.rb +4 -3
  91. data/lib/facets/core/string/modulize.rb +3 -3
  92. data/lib/facets/more/ansicode.rb +1 -1
  93. data/lib/facets/more/aspects.rb +1 -1
  94. data/lib/facets/more/basicobject.rb +67 -22
  95. data/lib/facets/more/classinherit.rb +2 -2
  96. data/lib/facets/more/cloneable.rb +1 -1
  97. data/lib/facets/more/consoleapp.rb +31 -20
  98. data/lib/facets/more/dictionary.rb +1 -1
  99. data/lib/facets/more/filelist.rb +2 -10
  100. data/lib/facets/more/functor.rb +6 -6
  101. data/lib/facets/more/json.rb +891 -0
  102. data/lib/facets/more/methodprobe.rb +1 -1
  103. data/lib/facets/more/multiton.rb +16 -8
  104. data/lib/facets/more/nilcomparable.rb +31 -49
  105. data/lib/facets/more/openobject.rb +50 -10
  106. data/lib/facets/more/recorder.rb +125 -0
  107. data/lib/facets/more/rtals.rb +199 -4
  108. data/lib/facets/more/typecast.rb +12 -12
  109. data/lib/facets/more/units.rb +20 -14
  110. data/lib/facets/more/xoxo.rb +519 -0
  111. data/setup.rb +283 -271
  112. data/test/lib/facets/core/array/test_at_rand.rb +1 -1
  113. data/test/lib/facets/core/array/test_delete_unless.rb +1 -1
  114. data/test/lib/facets/core/array/test_delete_values.rb +1 -1
  115. data/test/lib/facets/core/array/test_delete_values_at.rb +1 -1
  116. data/test/lib/facets/core/array/test_first.rb +1 -1
  117. data/test/lib/facets/core/array/test_head.rb +1 -1
  118. data/test/lib/facets/core/array/test_last_index.rb +1 -1
  119. data/test/lib/facets/core/array/test_merge.rb +1 -1
  120. data/test/lib/facets/core/array/test_mid.rb +1 -1
  121. data/test/lib/facets/core/array/test_middle.rb +1 -1
  122. data/test/lib/facets/core/array/test_op_fetch.rb +1 -1
  123. data/test/lib/facets/core/array/test_op_store.rb +1 -1
  124. data/test/lib/facets/core/array/test_pick.rb +1 -1
  125. data/test/lib/facets/core/array/test_pos.rb +1 -1
  126. data/test/lib/facets/core/array/test_pull.rb +1 -1
  127. data/test/lib/facets/core/array/test_rand_index.rb +1 -1
  128. data/test/lib/facets/core/array/test_rand_subset.rb +1 -1
  129. data/test/lib/facets/core/array/test_range.rb +1 -1
  130. data/test/lib/facets/core/array/test_rotate.rb +1 -1
  131. data/test/lib/facets/core/array/test_select.rb +1 -1
  132. data/test/lib/facets/core/array/test_shuffle.rb +1 -1
  133. data/test/lib/facets/core/array/test_slap.rb +1 -1
  134. data/test/lib/facets/core/array/test_thru.rb +1 -1
  135. data/test/lib/facets/core/array/test_to_b.rb +1 -1
  136. data/test/lib/facets/core/array/test_to_h.rb +1 -1
  137. data/test/lib/facets/core/array/test_to_hash.rb +1 -1
  138. data/test/lib/facets/core/binding/self/test_of_caller.rb +1 -1
  139. data/test/lib/facets/core/binding/test___LINE__.rb +1 -1
  140. data/test/lib/facets/core/binding/test_call_stack.rb +1 -1
  141. data/test/lib/facets/core/binding/test_called.rb +1 -1
  142. data/test/lib/facets/core/binding/test_caller.rb +1 -1
  143. data/test/lib/facets/core/binding/test_defined.rb +1 -1
  144. data/test/lib/facets/core/binding/test_eval.rb +1 -1
  145. data/test/lib/facets/core/binding/test_local_variables.rb +1 -1
  146. data/test/lib/facets/core/binding/test_method_name.rb +1 -1
  147. data/test/lib/facets/core/binding/test_op_fetch.rb +1 -1
  148. data/test/lib/facets/core/binding/test_op_store.rb +1 -1
  149. data/test/lib/facets/core/binding/test_self.rb +1 -1
  150. data/test/lib/facets/core/{module/test_cattr_accessor.rb → class/test_cattr.rb} +11 -3
  151. data/test/lib/facets/core/class/test_descendents.rb +1 -1
  152. data/test/lib/facets/core/class/test_method_name.rb +1 -1
  153. data/test/lib/facets/core/class/test_remove_descendents.rb +1 -1
  154. data/test/lib/facets/core/class/test_unix_path.rb +1 -1
  155. data/test/lib/facets/core/comparable/test_at_least.rb +1 -1
  156. data/test/lib/facets/core/comparable/test_clip.rb +1 -1
  157. data/test/lib/facets/core/comparable/test_cmp.rb +1 -1
  158. data/test/lib/facets/core/continuation/self/test_create.rb +1 -1
  159. data/test/lib/facets/core/date/test_days_in_month.rb +1 -1
  160. data/test/lib/facets/core/date/test_days_of_month.rb +1 -1
  161. data/test/lib/facets/core/date/test_stamp.rb +1 -1
  162. data/test/lib/facets/core/date/test_to_date.rb +1 -1
  163. data/test/lib/facets/core/date/test_to_s.rb +1 -1
  164. data/test/lib/facets/core/date/test_to_time.rb +1 -1
  165. data/test/lib/facets/core/dir/self/test_ancestor.rb +1 -1
  166. data/test/lib/facets/core/dir/self/test_ascend.rb +1 -1
  167. data/test/lib/facets/core/enumerable/self/test_combinations.rb +1 -1
  168. data/test/lib/facets/core/enumerable/self/test_cross.rb +1 -1
  169. data/test/lib/facets/core/enumerable/test_collect_with_index.rb +1 -1
  170. data/test/lib/facets/core/enumerable/test_commonality.rb +1 -1
  171. data/test/lib/facets/core/enumerable/test_compact_collect.rb +1 -1
  172. data/test/lib/facets/core/enumerable/test_cross.rb +1 -1
  173. data/test/lib/facets/core/enumerable/test_each_combination.rb +1 -1
  174. data/test/lib/facets/core/enumerable/test_each_pair.rb +1 -1
  175. data/test/lib/facets/core/enumerable/test_each_slice.rb +1 -1
  176. data/test/lib/facets/core/enumerable/test_each_unique_pair.rb +1 -1
  177. data/test/lib/facets/core/enumerable/test_entropy.rb +1 -1
  178. data/test/lib/facets/core/enumerable/test_every.rb +1 -1
  179. data/test/lib/facets/core/enumerable/test_ew.rb +1 -1
  180. data/test/lib/facets/core/enumerable/test_filter_collect.rb +1 -1
  181. data/test/lib/facets/core/enumerable/test_find_collisions.rb +1 -1
  182. data/test/lib/facets/core/enumerable/test_frequency.rb +1 -1
  183. data/test/lib/facets/core/enumerable/test_graph.rb +1 -1
  184. data/test/lib/facets/core/enumerable/test_ideal_entropy.rb +1 -1
  185. data/test/lib/facets/core/enumerable/test_none.rb +1 -1
  186. data/test/lib/facets/core/enumerable/test_occur.rb +1 -1
  187. data/test/lib/facets/core/enumerable/test_one.rb +1 -1
  188. data/test/lib/facets/core/enumerable/test_op_pow.rb +1 -1
  189. data/test/lib/facets/core/enumerable/test_partition_by.rb +1 -1
  190. data/test/lib/facets/core/enumerable/test_permute.rb +1 -1
  191. data/test/lib/facets/core/enumerable/test_probability.rb +1 -1
  192. data/test/lib/facets/core/enumerable/test_to_h.rb +1 -1
  193. data/test/lib/facets/core/enumerable/test_uniq_by.rb +1 -1
  194. data/test/lib/facets/core/file/self/test_create.rb +14 -9
  195. data/test/lib/facets/core/file/self/test_open_as_string.rb +21 -11
  196. data/test/lib/facets/core/file/self/test_read_list.rb +11 -8
  197. data/test/lib/facets/core/file/self/test_sanitize.rb +1 -1
  198. data/test/lib/facets/core/file/self/test_split_all.rb +1 -1
  199. data/test/lib/facets/core/float/test_round_at.rb +1 -1
  200. data/test/lib/facets/core/float/test_round_to.rb +1 -1
  201. data/test/lib/facets/core/hash/self/test_zipnew.rb +1 -1
  202. data/test/lib/facets/core/hash/test_alias.rb +1 -1
  203. data/test/lib/facets/core/hash/test_assert_has_keys.rb +1 -1
  204. data/test/lib/facets/core/hash/test_assert_has_only_keys.rb +1 -1
  205. data/test/lib/facets/core/hash/test_at.rb +1 -1
  206. data/test/lib/facets/core/hash/test_collate.rb +1 -1
  207. data/test/lib/facets/core/hash/test_each.rb +1 -1
  208. data/test/lib/facets/core/hash/test_each_with_index.rb +1 -1
  209. data/test/lib/facets/core/hash/test_each_with_key.rb +1 -1
  210. data/test/lib/facets/core/hash/test_graph.rb +1 -1
  211. data/test/lib/facets/core/hash/test_has_keys.rb +1 -1
  212. data/test/lib/facets/core/hash/test_has_only_keys.rb +1 -1
  213. data/test/lib/facets/core/hash/test_inverse.rb +1 -1
  214. data/test/lib/facets/core/hash/test_keys_to_s.rb +1 -1
  215. data/test/lib/facets/core/hash/test_keys_to_sym.rb +1 -1
  216. data/test/lib/facets/core/hash/test_op_fetch.rb +1 -1
  217. data/test/lib/facets/core/hash/test_op_lshift.rb +1 -1
  218. data/test/lib/facets/core/hash/test_rand_key.rb +1 -1
  219. data/test/lib/facets/core/hash/test_rand_pair.rb +1 -1
  220. data/test/lib/facets/core/hash/test_rand_value.rb +1 -1
  221. data/test/lib/facets/core/hash/test_replace_each.rb +1 -1
  222. data/test/lib/facets/core/hash/test_shuffle.rb +1 -1
  223. data/test/lib/facets/core/hash/test_slice.rb +1 -1
  224. data/test/lib/facets/core/hash/test_swap.rb +1 -1
  225. data/test/lib/facets/core/hash/test_swapkey.rb +1 -1
  226. data/test/lib/facets/core/hash/test_to_h.rb +1 -1
  227. data/test/lib/facets/core/hash/test_to_ostruct.rb +1 -1
  228. data/test/lib/facets/core/hash/test_to_ostruct_recurse.rb +1 -1
  229. data/test/lib/facets/core/hash/test_traverse.rb +1 -1
  230. data/test/lib/facets/core/hash/test_update_each.rb +1 -1
  231. data/test/lib/facets/core/hash/test_update_keys.rb +1 -1
  232. data/test/lib/facets/core/hash/test_update_values.rb +1 -1
  233. data/test/lib/facets/core/hash/test_weave.rb +1 -1
  234. data/test/lib/facets/core/integer/test_factorial.rb +1 -1
  235. data/test/lib/facets/core/integer/test_multiple.rb +1 -1
  236. data/test/lib/facets/core/integer/test_ordinal.rb +1 -1
  237. data/test/lib/facets/core/integer/test_times_collect.rb +1 -1
  238. data/test/lib/facets/core/kernel/test___class__.rb +1 -1
  239. data/test/lib/facets/core/kernel/test_as.rb +1 -1
  240. data/test/lib/facets/core/kernel/test_assign_from.rb +1 -1
  241. data/test/lib/facets/core/kernel/test_assign_with.rb +1 -1
  242. data/test/lib/facets/core/kernel/test_bool.rb +1 -1
  243. data/test/lib/facets/core/kernel/test_bug.rb +1 -1
  244. data/test/lib/facets/core/kernel/test_call_stack.rb +1 -1
  245. data/test/lib/facets/core/kernel/test_called.rb +1 -1
  246. data/test/lib/facets/core/kernel/test_constant.rb +1 -1
  247. data/test/lib/facets/core/kernel/test_copy.rb +1 -1
  248. data/test/lib/facets/core/kernel/test_deep_copy.rb +1 -1
  249. data/test/lib/facets/core/kernel/test_demo.rb +1 -1
  250. data/test/lib/facets/core/kernel/test_fn.rb +1 -1
  251. data/test/lib/facets/core/kernel/test_generate_method_name.rb +1 -1
  252. data/test/lib/facets/core/kernel/test_get_by_id.rb +1 -1
  253. data/test/lib/facets/core/kernel/test_here.rb +1 -1
  254. data/test/lib/facets/core/kernel/test_in.rb +1 -1
  255. data/test/lib/facets/core/kernel/test_maybe.rb +1 -1
  256. data/test/lib/facets/core/kernel/test_metaclass.rb +1 -1
  257. data/test/lib/facets/core/kernel/test_method.rb +1 -1
  258. data/test/lib/facets/core/kernel/{test_method_name.rb → test_methodname.rb} +3 -3
  259. data/test/lib/facets/core/kernel/test_methods.rb +1 -1
  260. data/test/lib/facets/core/kernel/test_new.rb +1 -1
  261. data/test/lib/facets/core/kernel/test_object_class.rb +1 -1
  262. data/test/lib/facets/core/kernel/test_object_hexid.rb +1 -1
  263. data/test/lib/facets/core/kernel/test_require_all.rb +1 -1
  264. data/test/lib/facets/core/kernel/test_require_esc.rb +1 -1
  265. data/test/lib/facets/core/kernel/test_require_facet.rb +1 -1
  266. data/test/lib/facets/core/kernel/test_resc.rb +1 -1
  267. data/test/lib/facets/core/kernel/test_returning.rb +1 -1
  268. data/test/lib/facets/core/kernel/test_send_as.rb +1 -1
  269. data/test/lib/facets/core/kernel/test_set_from.rb +1 -1
  270. data/test/lib/facets/core/kernel/test_set_with.rb +1 -1
  271. data/test/lib/facets/core/kernel/test_silently.rb +1 -1
  272. data/test/lib/facets/core/kernel/test_singleton.rb +1 -1
  273. data/test/lib/facets/core/kernel/test_superior.rb +1 -1
  274. data/test/lib/facets/core/kernel/test_supermethod.rb +1 -1
  275. data/test/lib/facets/core/kernel/test_this.rb +1 -1
  276. data/test/lib/facets/core/kernel/test_to_b.rb +1 -1
  277. data/test/lib/facets/core/kernel/test_to_bool.rb +1 -1
  278. data/test/lib/facets/core/kernel/test_uri.rb +1 -1
  279. data/test/lib/facets/core/kernel/test_val.rb +1 -1
  280. data/test/lib/facets/core/kernel/test_with_accessor.rb +1 -1
  281. data/test/lib/facets/core/matchdata/test_match.rb +1 -1
  282. data/test/lib/facets/core/matchdata/test_matchtree.rb +1 -1
  283. data/test/lib/facets/core/module/test_abstract.rb +1 -1
  284. data/test/lib/facets/core/module/test_alias_module_function.rb +1 -1
  285. data/test/lib/facets/core/module/test_ancestor.rb +1 -1
  286. data/test/lib/facets/core/module/test_basename.rb +1 -1
  287. data/test/lib/facets/core/module/test_by_name.rb +1 -1
  288. data/test/lib/facets/core/module/test_clone_using.rb +1 -1
  289. data/test/lib/facets/core/module/test_dirname.rb +1 -1
  290. data/test/lib/facets/core/module/test_equate_on.rb +1 -1
  291. data/test/lib/facets/core/module/test_generate_instance_method_name.rb +1 -1
  292. data/test/lib/facets/core/module/test_include_as.rb +1 -1
  293. data/test/lib/facets/core/module/test_inherit.rb +58 -0
  294. data/test/lib/facets/core/module/test_initializer.rb +1 -1
  295. data/test/lib/facets/core/module/test_instance_methods.rb +1 -1
  296. data/test/lib/facets/core/module/test_integrate.rb +1 -1
  297. data/test/lib/facets/core/module/test_let.rb +31 -0
  298. data/test/lib/facets/core/module/test_mattr.rb +71 -0
  299. data/test/lib/facets/core/module/test_memoize.rb +1 -1
  300. data/test/lib/facets/core/module/test_modspace.rb +1 -1
  301. data/test/lib/facets/core/module/test_namespace.rb +1 -1
  302. data/test/lib/facets/core/module/test_nesting.rb +1 -1
  303. data/test/lib/facets/core/module/test_on_included.rb +36 -0
  304. data/test/lib/facets/core/module/test_redef.rb +1 -1
  305. data/test/lib/facets/core/module/test_redefine_method.rb +1 -1
  306. data/test/lib/facets/core/module/test_redirect.rb +1 -1
  307. data/test/lib/facets/core/module/test_redirect_method.rb +1 -1
  308. data/test/lib/facets/core/module/test_remove.rb +1 -1
  309. data/test/lib/facets/core/module/test_rename.rb +1 -1
  310. data/test/lib/facets/core/module/test_rename_method.rb +1 -1
  311. data/test/lib/facets/core/module/test_revisal.rb +1 -1
  312. data/test/lib/facets/core/module/test_shadow_method.rb +1 -1
  313. data/test/lib/facets/core/module/test_sort_on.rb +1 -1
  314. data/test/lib/facets/core/module/test_undef.rb +1 -1
  315. data/test/lib/facets/core/module/test_wrap.rb +1 -1
  316. data/test/lib/facets/core/module/test_wrap_method.rb +1 -1
  317. data/test/lib/facets/core/nilclass/{test_to_f.rb → test_blank.rb} +5 -5
  318. data/test/lib/facets/core/nilclass/test_empty.rb +1 -1
  319. data/test/lib/facets/core/nilclass/test_include.rb +1 -1
  320. data/test/lib/facets/core/nilclass/test_op_fetch.rb +1 -1
  321. data/test/lib/facets/core/nilclass/test_size.rb +1 -1
  322. data/test/lib/facets/core/nilclass/test_to_h.rb +1 -1
  323. data/test/lib/facets/core/{float → numeric}/test_approx.rb +4 -3
  324. data/test/lib/facets/core/numeric/test_ceil_multiple.rb +1 -1
  325. data/test/lib/facets/core/numeric/test_succ.rb +1 -1
  326. data/test/lib/facets/core/numeric/test_to_b.rb +1 -1
  327. data/test/lib/facets/core/ostruct/test___merge__.rb +1 -1
  328. data/test/lib/facets/core/ostruct/test___update__.rb +1 -1
  329. data/test/lib/facets/core/ostruct/test_op_fetch.rb +1 -1
  330. data/test/lib/facets/core/ostruct/test_op_store.rb +1 -1
  331. data/test/lib/facets/core/proc/test_compose.rb +1 -1
  332. data/test/lib/facets/core/proc/test_to_method.rb +1 -1
  333. data/test/lib/facets/core/range/test_to_r.rb +1 -1
  334. data/test/lib/facets/core/range/test_to_range.rb +1 -1
  335. data/test/lib/facets/core/range/test_umbrella.rb +1 -1
  336. data/test/lib/facets/core/range/test_within.rb +1 -1
  337. data/test/lib/facets/core/regexp/test_arity.rb +1 -1
  338. data/test/lib/facets/core/regexp/test_to_re.rb +1 -1
  339. data/test/lib/facets/core/regexp/test_to_regexp.rb +1 -1
  340. data/test/lib/facets/core/string/self/test_interpolate.rb +1 -1
  341. data/test/lib/facets/core/string/self/test_patterns.rb +1 -1
  342. data/test/lib/facets/core/string/self/test_rand_letter.rb +1 -1
  343. data/test/lib/facets/core/string/test_align_center.rb +1 -1
  344. data/test/lib/facets/core/string/test_at_rand.rb +1 -1
  345. data/test/lib/facets/core/string/test_basename.rb +1 -1
  346. data/test/lib/facets/core/string/test_blank.rb +1 -1
  347. data/test/lib/facets/core/string/test_bracket.rb +1 -1
  348. data/test/lib/facets/core/string/test_camelcase.rb +1 -1
  349. data/test/lib/facets/core/string/test_camelize.rb +1 -1
  350. data/test/lib/facets/core/string/test_capitalized.rb +1 -1
  351. data/test/lib/facets/core/string/test_chars.rb +1 -1
  352. data/test/lib/facets/core/string/test_cmp.rb +1 -1
  353. data/test/lib/facets/core/string/test_demodulize.rb +1 -1
  354. data/test/lib/facets/core/string/test_downcase.rb +1 -1
  355. data/test/lib/facets/core/string/test_dresner.rb +1 -1
  356. data/test/lib/facets/core/string/test_each_char.rb +1 -1
  357. data/test/lib/facets/core/string/test_each_word.rb +1 -1
  358. data/test/lib/facets/core/string/test_first.rb +1 -1
  359. data/test/lib/facets/core/string/test_fold.rb +1 -1
  360. data/test/lib/facets/core/string/test_frequency.rb +1 -1
  361. data/test/lib/facets/core/string/test_humanize.rb +1 -1
  362. data/test/lib/facets/core/string/test_indent.rb +1 -1
  363. data/test/lib/facets/core/string/test_index_all.rb +1 -1
  364. data/test/lib/facets/core/string/test_last.rb +1 -1
  365. data/test/lib/facets/core/string/test_line_wrap.rb +1 -1
  366. data/test/lib/facets/core/string/test_lines.rb +1 -1
  367. data/test/lib/facets/core/string/test_lowercase.rb +1 -1
  368. data/test/lib/facets/core/string/test_margin.rb +1 -1
  369. data/test/lib/facets/core/string/test_methodize.rb +1 -1
  370. data/test/lib/facets/core/string/test_modulize.rb +1 -1
  371. data/test/lib/facets/core/string/test_mscan.rb +1 -1
  372. data/test/lib/facets/core/string/test_natcmp.rb +1 -1
  373. data/test/lib/facets/core/string/test_nchar.rb +1 -1
  374. data/test/lib/facets/core/string/test_pathize.rb +1 -1
  375. data/test/lib/facets/core/string/test_pop.rb +1 -1
  376. data/test/lib/facets/core/string/test_probability.rb +1 -1
  377. data/test/lib/facets/core/string/test_push.rb +1 -1
  378. data/test/lib/facets/core/string/test_quote.rb +1 -1
  379. data/test/lib/facets/core/string/test_rand_byte.rb +1 -1
  380. data/test/lib/facets/core/string/test_rand_index.rb +1 -1
  381. data/test/lib/facets/core/string/test_range.rb +1 -1
  382. data/test/lib/facets/core/string/test_range_all.rb +1 -1
  383. data/test/lib/facets/core/string/test_range_of_line.rb +1 -1
  384. data/test/lib/facets/core/string/test_regesc.rb +1 -1
  385. data/test/lib/facets/core/string/test_shatter.rb +1 -1
  386. data/test/lib/facets/core/string/test_shift.rb +1 -1
  387. data/test/lib/facets/core/string/test_shuffle.rb +1 -1
  388. data/test/lib/facets/core/string/test_similarity.rb +1 -1
  389. data/test/lib/facets/core/string/test_singular.rb +1 -1
  390. data/test/lib/facets/core/string/test_slap.rb +1 -1
  391. data/test/lib/facets/core/string/test_soundex.rb +1 -1
  392. data/test/lib/facets/core/string/test_succ.rb +1 -1
  393. data/test/lib/facets/core/string/test_to_a.rb +1 -1
  394. data/test/lib/facets/core/string/test_to_arr.rb +1 -1
  395. data/test/lib/facets/core/string/test_to_b.rb +1 -1
  396. data/test/lib/facets/core/string/test_to_const.rb +1 -1
  397. data/test/lib/facets/core/string/test_to_date.rb +1 -1
  398. data/test/lib/facets/core/string/test_to_proc.rb +1 -1
  399. data/test/lib/facets/core/string/test_to_re.rb +1 -1
  400. data/test/lib/facets/core/string/test_to_time.rb +1 -1
  401. data/test/lib/facets/core/string/test_unix_crypt.rb +1 -1
  402. data/test/lib/facets/core/string/test_unpack.rb +1 -1
  403. data/test/lib/facets/core/string/test_unshift.rb +1 -1
  404. data/test/lib/facets/core/string/test_upcase.rb +1 -1
  405. data/test/lib/facets/core/string/test_whitespace.rb +1 -1
  406. data/test/lib/facets/core/string/test_word_filter.rb +1 -1
  407. data/test/lib/facets/core/string/test_word_wrap.rb +1 -1
  408. data/test/lib/facets/core/string/test_words.rb +1 -1
  409. data/test/lib/facets/core/symbol/test_camelcase.rb +1 -1
  410. data/test/lib/facets/core/symbol/test_camelize.rb +1 -1
  411. data/test/lib/facets/core/symbol/test_capitalize.rb +1 -1
  412. data/test/lib/facets/core/symbol/test_capitalized.rb +1 -1
  413. data/test/lib/facets/core/symbol/test_downcase.rb +1 -1
  414. data/test/lib/facets/core/symbol/test_not.rb +1 -1
  415. data/test/lib/facets/core/symbol/test_pad.rb +1 -1
  416. data/test/lib/facets/core/symbol/test_succ.rb +1 -1
  417. data/test/lib/facets/core/symbol/test_to_const.rb +1 -1
  418. data/test/lib/facets/core/symbol/test_to_proc.rb +1 -1
  419. data/test/lib/facets/core/symbol/test_to_str.rb +1 -1
  420. data/test/lib/facets/core/symbol/test_underscore.rb +1 -1
  421. data/test/lib/facets/core/symbol/test_upcase.rb +1 -1
  422. data/test/lib/facets/core/time/test_change.rb +1 -1
  423. data/test/lib/facets/core/time/test_elapse.rb +1 -1
  424. data/test/lib/facets/core/time/test_stamp.rb +1 -1
  425. data/test/lib/facets/core/time/test_to_date.rb +1 -1
  426. data/test/lib/facets/core/time/test_to_s.rb +1 -1
  427. data/test/lib/facets/core/time/test_to_time.rb +1 -1
  428. data/test/lib/facets/more/test_annotation.rb +1 -1
  429. data/test/lib/facets/more/test_ansicode.rb +1 -1
  430. data/test/lib/facets/more/test_association.rb +1 -1
  431. data/test/lib/facets/more/test_basicobject.rb +58 -0
  432. data/test/lib/facets/more/test_bbcode.rb +1 -1
  433. data/test/lib/facets/more/test_bitmask.rb +1 -1
  434. data/test/lib/facets/more/test_bytes.rb +1 -1
  435. data/test/lib/facets/more/test_classinherit.rb +1 -1
  436. data/test/lib/facets/more/test_classmethods.rb +1 -1
  437. data/test/lib/facets/more/test_coroutine.rb +1 -1
  438. data/test/lib/facets/more/test_crypt.rb +1 -1
  439. data/test/lib/facets/more/test_dictionary.rb +1 -1
  440. data/test/lib/facets/more/test_elementor.rb +48 -0
  441. data/test/lib/facets/more/test_enumerablepass.rb +1 -1
  442. data/test/lib/facets/more/test_floatstring.rb +1 -1
  443. data/test/lib/facets/more/test_functor.rb +1 -1
  444. data/test/lib/facets/more/test_inheritor.rb +1 -1
  445. data/test/lib/facets/more/test_interval.rb +1 -1
  446. data/test/lib/facets/more/test_json.rb +232 -0
  447. data/test/lib/facets/more/test_lisp.rb +1 -1
  448. data/test/lib/facets/more/test_lisp_format.rb +1 -1
  449. data/test/lib/facets/more/test_lrucache.rb +1 -1
  450. data/test/lib/facets/more/test_mathconstants.rb +1 -1
  451. data/test/lib/facets/more/test_methodprobe.rb +1 -1
  452. data/test/lib/facets/more/test_multipliers.rb +1 -1
  453. data/test/lib/facets/more/test_multiton.rb +1 -1
  454. data/test/lib/facets/more/test_nackclass.rb +1 -1
  455. data/test/lib/facets/more/test_nilcomparable.rb +6 -2
  456. data/test/lib/facets/more/test_openobject.rb +1 -1
  457. data/test/lib/facets/more/test_overload.rb +1 -1
  458. data/test/lib/facets/more/test_paramix.rb +1 -1
  459. data/test/lib/facets/more/test_preinitialize.rb +1 -1
  460. data/test/lib/facets/more/test_promoteself.rb +1 -1
  461. data/test/lib/facets/more/test_recorder.rb +44 -0
  462. data/test/lib/facets/more/test_snapshot.rb +1 -1
  463. data/test/lib/facets/more/test_statichash.rb +1 -1
  464. data/test/lib/facets/more/test_syncarray.rb +1 -1
  465. data/test/lib/facets/more/test_synchash.rb +1 -1
  466. data/test/lib/facets/more/test_tagiterator.rb +1 -1
  467. data/test/lib/facets/more/test_timer.rb +1 -1
  468. data/test/lib/facets/more/test_times.rb +1 -1
  469. data/test/lib/facets/more/test_tuple.rb +1 -1
  470. data/test/lib/facets/more/test_typecast.rb +2 -2
  471. data/test/lib/facets/more/test_uninheritable.rb +1 -1
  472. data/test/lib/facets/more/test_units.rb +16 -10
  473. data/test/lib/facets/more/test_xoxo.rb +288 -0
  474. data/test/lib/facets/more/test_yamlstruct.rb +1 -1
  475. metadata +92 -25
  476. data/lib/facet/kernel/instance.rb +0 -1
  477. data/lib/facet/module/cattr.rb +0 -1
  478. data/lib/facet/module/cattr_accessor.rb +0 -1
  479. data/lib/facet/module/cattr_reader.rb +0 -1
  480. data/lib/facet/module/cattr_writer.rb +0 -1
  481. data/lib/facets/core/kernel/instance.rb +0 -29
  482. data/test/FIXTURE/create_file +0 -1
  483. data/test/FIXTURE/open_as_string_file +0 -1
  484. data/test/FIXTURE/read_list_file +0 -6
  485. data/test/lib/facets/core/dir/self/test_ls_r.rb +0 -52
  486. data/test/lib/facets/core/fileutils/test_wc.rb +0 -68
  487. data/test/lib/facets/core/fileutils/test_which.rb +0 -61
  488. data/test/testdir.rb +0 -8
@@ -38,7 +38,7 @@
38
38
  # the behavior of classes themselves when they are subclassed.
39
39
  # To achieve the same behavior with modules requires some clever
40
40
  # Ruby karate. ClassInherit provides a nice solution.
41
- # Simply place the class inheritable methods in the block
41
+ # Simply place the class inheritable methods in the block
42
42
  # parameter of the special module method ClassInherit.
43
43
  #
44
44
  # module Mix
@@ -64,7 +64,7 @@
64
64
  # the given block is evaluated, then the ClassInherit module
65
65
  # is extended against the current module.
66
66
  #
67
- # The above is actually equivalent to putting the class/module
67
+ # The above is actually equivalent to putting the class/module
68
68
  # methods in a nested ClassInherit module and extending the
69
69
  # module _manually_, eg.
70
70
  #
@@ -28,7 +28,7 @@
28
28
  # Stadard basis for adding #dup and #clone methods to a class.
29
29
  #
30
30
  #--
31
- # TODO #clone should copy ad-hoc methods in contrast to #dup.
31
+ # TODO #clone should copy '<<'-methods in contrast to #dup.
32
32
  #++
33
33
 
34
34
  module Cloneable
@@ -25,22 +25,22 @@
25
25
 
26
26
  module Console ; end
27
27
 
28
- #:title: Console Application
28
+ #:title: Console Command
29
29
  #
30
- # Console::Application provides a clean and easy way
30
+ # Console::Command provides a clean and easy way
31
31
  # to create a command line interface for your program.
32
- # The unique technique utlizes Commandline to Object
32
+ # The unique technique utlizes a Commandline to Object
33
33
  # Mapping (COM) to make it quick and easy.
34
34
  #
35
35
  # == Synopsis
36
36
  #
37
- # Given an excutable 'myapp':
37
+ # Let's make an executable called 'mycmd'.
38
38
  #
39
39
  # #!/usr/bin/env ruby
40
40
  #
41
- # require 'facet/consoleapp'
41
+ # require 'facet/console_command'
42
42
  #
43
- # MyApp << Console::Application
43
+ # MyCmd << Console::Command
44
44
  #
45
45
  # def _v
46
46
  # $VERBOSE = true
@@ -56,27 +56,30 @@ module Console ; end
56
56
  #
57
57
  # end
58
58
  #
59
- # MyApp.run
59
+ # MyCmd.execute
60
60
  #
61
61
  # Then on the command line:
62
62
  #
63
- # > myapp jump
63
+ # > mycmd jump
64
64
  # Jump
65
65
  #
66
- # > myapp -v jump
66
+ # > mycmd -v jump
67
67
  # JUMP! JUMP! JUMP!
68
68
  #
69
69
 
70
- class Console::Application
70
+ class Console::Command
71
+
72
+ def execute( argv=nil )
71
73
 
72
- def go
74
+ argv ||= ARGV # argv remains unchanged
75
+ args = argv.dup # args is manipulated
73
76
 
74
- i = 0; args = ARGV.dup
77
+ # process options
75
78
 
76
- while i < ARGV.size
77
- # options
78
- if md = %r{^[-]}.match( ARGV[i] )
79
- opt = ARGV[i].gsub('-','_')
79
+ i = 0;
80
+ while i < argv.size
81
+ if md = %r{^[-]}.match( argv[i] )
82
+ opt = argv[i].gsub('-','_')
80
83
  if self.respond_to?( opt )
81
84
  m = method( opt )
82
85
  c = m.arity
@@ -96,13 +99,12 @@ class Console::Application
96
99
  i += 1
97
100
  end
98
101
 
99
- # Non-secondary command type of application
102
+ # no secondary commands
100
103
 
101
104
  if self.respond_to?(:main)
102
105
  main( *args )
103
- #exit 0
104
106
 
105
- # secondary command type of application
107
+ # secondary commands
106
108
 
107
109
  elsif not args.empty?
108
110
  if self.respond_to?( args.first )
@@ -116,9 +118,13 @@ class Console::Application
116
118
  end
117
119
  end
118
120
 
121
+ # default secondary command
122
+
119
123
  elsif self.respond_to?( :default )
120
124
  default(*args)
121
125
 
126
+ # error
127
+
122
128
  else
123
129
  if self.private_methods.include?( "no_action_error" )
124
130
  no_action_error( *args )
@@ -129,6 +135,11 @@ class Console::Application
129
135
 
130
136
  end
131
137
 
132
- end #def go
138
+ end
133
139
 
140
+ alias_method :go, :execute
141
+
134
142
  end
143
+
144
+ # temporary backward compatability
145
+ Console::Application = Console::Command
@@ -28,7 +28,7 @@
28
28
  # * added #dup and #insert
29
29
  #
30
30
  # 2055-02-01 trans
31
- # * ported to calibre from jan molic's OrderHash
31
+ # * ported from jan molic's OrderHash
32
32
  # ==========================================================================
33
33
  #++
34
34
 
@@ -449,7 +449,7 @@ end # FileList
449
449
  # |_|\___||___/\__|
450
450
  #
451
451
 
452
- # TODO
452
+ # TODO This test needs a mock File class.
453
453
 
454
454
  # FileList can't be tested without a FIXTURE setup.
455
455
  # So don't bother running it directly from here, but
@@ -457,18 +457,10 @@ end # FileList
457
457
  # Need a better solution, is there a way to fake the
458
458
  # filesystem?
459
459
 
460
- =begin #test
460
+ =begin #no test yet
461
461
 
462
462
  require 'test/unit'
463
463
 
464
- # FIND TEST DIRECTORY
465
- paths = File.expand_path(File.dirname(__FILE__)).split('/')
466
- paths.size.downto(1) do |i|
467
- f = (paths.slice(0..i)+['test']).join('/')
468
- $TESTDIR = File.join(f,'FIXTURE') if File.directory?(f)
469
- end
470
- raise unless $TESTDIR
471
-
472
464
  class TC_FileList < Test::Unit::TestCase
473
465
 
474
466
  def test_filelist
@@ -18,7 +18,7 @@
18
18
  # Made a subclass of BasicObject.
19
19
  #
20
20
  # 05-01-10 trans
21
- # Ported to Mega Modules.
21
+ # Ported to Facets.
22
22
  # ==========================================================================
23
23
  #++
24
24
 
@@ -55,12 +55,12 @@ class Functor < BasicObject
55
55
  @func = func
56
56
  end
57
57
 
58
- def method_missing(op, *args)
59
- #if @obj.empty?
60
- # @func.call(op, *args)
61
- #else
58
+ def method_missing(op, *args, &blk)
59
+ if block_given?
60
+ @func.call(op, *(@obj + args + [blk]))
61
+ else
62
62
  @func.call(op, *(@obj + args))
63
- #end
63
+ end
64
64
  end
65
65
 
66
66
  def instance_objects
@@ -0,0 +1,891 @@
1
+ #--
2
+ # JSON library for Ruby
3
+ #
4
+ # Copyright (c) 2006, Florian Frank
5
+ #
6
+ # This is free software; you can redistribute it and/or modify it under the
7
+ # terms of the GNU General Public License Version 2 as published by the Free
8
+ # Software Foundation: www.gnu.org/copyleft/gpl.html
9
+ #
10
+ # Original Version (0.4.1) Download
11
+ #
12
+ # The latest version of this library can be downloaded at
13
+ #
14
+ # * http://rubyforge.org/frs?group_id=953
15
+ #
16
+ # Online Documentation should be located at
17
+ #
18
+ # * http://json.rubyforge.org
19
+ #++
20
+
21
+ ($VERSION ||= {})['json'] = '0.4.1'
22
+
23
+ # :title: JSON
24
+ #
25
+ # Ruby support of Javascript Object Notation.
26
+ #
27
+ # == Examples
28
+ #
29
+ # To create a JSON string from a ruby data structure, you
30
+ # can call JSON.unparse like that:
31
+ #
32
+ # json = JSON.unparse [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
33
+ # # => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]"
34
+ #
35
+ # It's also possible to call the #to_json method directly.
36
+ #
37
+ # json = [1, 2, {"a"=>3.141}, false, true, nil, 4..10].to_json
38
+ # # => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]"
39
+ #
40
+ # To get back a ruby data structure, you have to call
41
+ # JSON.parse on the JSON string:
42
+ #
43
+ # JSON.parse json
44
+ # # => [1, 2, {"a"=>3.141}, false, true, nil, "4..10"]
45
+ #
46
+ # Note, that the range from the original data structure is a simple
47
+ # string now. The reason for this is, that JSON doesn't support ranges
48
+ # or arbitrary classes. In this case the json library falls back to call
49
+ # Object#to_json, which is the same as #to_s.to_json.
50
+ #
51
+ # It's possible to extend JSON to support serialization of arbitray classes by
52
+ # simply implementing a more specialized version of the #to_json method, that
53
+ # should return a JSON object (a hash converted to JSON with #to_json)
54
+ # like this (don't forget the *a for all the arguments):
55
+ #
56
+ # class Range
57
+ # def to_json(*a)
58
+ # {
59
+ # 'json_class' => self.class.name,
60
+ # 'data' => [ first, last, exclude_end? ]
61
+ # }.to_json(*a)
62
+ # end
63
+ # end
64
+ #
65
+ # The hash key 'json_class' is the class, that will be asked to deserialize the
66
+ # JSON representation later. In this case it's 'Range', but any namespace of
67
+ # the form 'A::B' or '::A::B' will do. All other keys are arbitrary and can be
68
+ # used to store the necessary data to configure the object to be deserialized.
69
+ #
70
+ # If a the key 'json_class' is found in a JSON object, the JSON parser checks
71
+ # if the given class responds to the json_create class method. If so, it is
72
+ # called with the JSON object converted to a Ruby hash. So a range can
73
+ # be deserialized by implementing Range.json_create like this:
74
+ #
75
+ # class Range
76
+ # def self.json_create(o)
77
+ # new(*o['data'])
78
+ # end
79
+ # end
80
+ #
81
+ # Now it possible to serialize/deserialize ranges as well:
82
+ #
83
+ # json = JSON.unparse [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
84
+ # # => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]"
85
+ # JSON.parse json
86
+ # # => [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
87
+ #
88
+ # JSON.unparse always creates the shortes possible string representation of a
89
+ # ruby data structure in one line. This good for data storage or network
90
+ # protocols, but not so good for humans to read. Fortunately there's
91
+ # also JSON.pretty_unparse that creates a more readable output:
92
+ #
93
+ # puts JSON.pretty_unparse([1, 2, {"a"=>3.141}, false, true, nil, 4..10])
94
+ # [
95
+ # 1,
96
+ # 2,
97
+ # {
98
+ # "a": 3.141
99
+ # },
100
+ # false,
101
+ # true,
102
+ # null,
103
+ # {
104
+ # "json_class": "Range",
105
+ # "data": [
106
+ # 4,
107
+ # 10,
108
+ # false
109
+ # ]
110
+ # }
111
+ # ]
112
+ #
113
+ # There are also the methods Kernel#j for unparse, and Kernel#jj for
114
+ # pretty_unparse output to the console, that work analogous to Kernel#p and
115
+ # Kernel#pp.
116
+ #
117
+ # == Author(s)
118
+ #
119
+ # Florian Frank <mailto:flori@ping.de>
120
+ #
121
+
122
+ require 'strscan'
123
+
124
+ # This module is the namespace for all the JSON related classes. It also
125
+ # defines some module functions to expose a nicer API to users, instead
126
+ # of using the parser and other classes directly.
127
+
128
+ module JSON
129
+
130
+ # The base exception for JSON errors.
131
+ JSONError = Class.new StandardError
132
+
133
+ # This exception is raise, if a parser error occurs.
134
+ ParserError = Class.new JSONError
135
+
136
+ # This exception is raise, if a unparser error occurs.
137
+ UnparserError = Class.new JSONError
138
+
139
+ # If a circular data structure is encountered while unparsing
140
+ # this exception is raised.
141
+ CircularDatastructure = Class.new UnparserError
142
+
143
+ class << self
144
+ # Switches on Unicode support, if _enable_ is _true_. Otherwise switches
145
+ # Unicode support off.
146
+ def support_unicode=(enable)
147
+ @support_unicode = enable
148
+ end
149
+
150
+ # Returns _true_ if JSON supports unicode, otherwise _false_ is returned.
151
+ def support_unicode?
152
+ !!@support_unicode
153
+ end
154
+ end
155
+ JSON.support_unicode = true # default, hower it's possible to switch off full
156
+ # unicode support, if non-ascii bytes should be
157
+ # just passed through.
158
+
159
+ begin
160
+ require 'iconv'
161
+ # An iconv instance to convert from UTF8 to UTF16 Big Endian.
162
+ UTF16toUTF8 = Iconv.new('utf-8', 'utf-16be')
163
+ # An iconv instance to convert from UTF16 Big Endian to UTF8.
164
+ UTF8toUTF16 = Iconv.new('utf-16be', 'utf-8'); UTF8toUTF16.iconv('no bom')
165
+ rescue LoadError
166
+ JSON.support_unicode = false # enforce disabling of unicode support
167
+ end
168
+
169
+ # This class implements the JSON parser that is used to parse a JSON string
170
+ # into a Ruby data structure.
171
+ class Parser < StringScanner
172
+ STRING = /"((?:[^"\\]|\\.)*)"/
173
+ INTEGER = /-?\d+/
174
+ FLOAT = /-?\d+\.(\d*)(?i:e[+-]?\d+)?/
175
+ OBJECT_OPEN = /\{/
176
+ OBJECT_CLOSE = /\}/
177
+ ARRAY_OPEN = /\[/
178
+ ARRAY_CLOSE = /\]/
179
+ PAIR_DELIMITER = /:/
180
+ COLLECTION_DELIMITER = /,/
181
+ TRUE = /true/
182
+ FALSE = /false/
183
+ NULL = /null/
184
+ IGNORE = %r(
185
+ (?:
186
+ //[^\n\r]*[\n\r]| # line comments
187
+ /\* # c-style comments
188
+ (?:
189
+ [^*/]| # normal chars
190
+ /[^*]| # slashes that do not start a nested comment
191
+ \*[^/]| # asterisks that do not end this comment
192
+ /(?=\*/) # single slash before this comment's end
193
+ )*
194
+ \*/ # the end of this comment
195
+ |\s+ # whitespaces
196
+ )+
197
+ )mx
198
+
199
+ UNPARSED = Object.new
200
+
201
+ # Parses the current JSON string and returns the complete data structure
202
+ # as a result.
203
+ def parse
204
+ reset
205
+ until eos?
206
+ case
207
+ when scan(ARRAY_OPEN)
208
+ return parse_array
209
+ when scan(OBJECT_OPEN)
210
+ return parse_object
211
+ when skip(IGNORE)
212
+ ;
213
+ when !((value = parse_value).equal? UNPARSED)
214
+ return value
215
+ else
216
+ raise ParserError, "source '#{peek(20)}' not in JSON!"
217
+ end
218
+ end
219
+ end
220
+
221
+ private
222
+
223
+ def parse_string
224
+ if scan(STRING)
225
+ return '' if self[1].empty?
226
+ self[1].gsub(/\\(?:[\\bfnrt"]|u([A-Fa-f\d]{4}))/) do
227
+ case $~[0]
228
+ when '\\\\' then '\\'
229
+ when '\\b' then "\b"
230
+ when '\\f' then "\f"
231
+ when '\\n' then "\n"
232
+ when '\\r' then "\r"
233
+ when '\\t' then "\t"
234
+ when '\\"' then '"'
235
+ else
236
+ if JSON.support_unicode? and $KCODE == 'UTF8'
237
+ JSON.utf16_to_utf8($~[1])
238
+ else
239
+ # if utf8 mode is switched off or unicode not supported, try to
240
+ # transform unicode \u-notation to bytes directly:
241
+ $~[1].to_i(16).chr
242
+ end
243
+ end
244
+ end
245
+ else
246
+ UNPARSED
247
+ end
248
+ end
249
+
250
+ def parse_value
251
+ case
252
+ when scan(FLOAT)
253
+ Float(self[0])
254
+ when scan(INTEGER)
255
+ Integer(self[0])
256
+ when scan(TRUE)
257
+ true
258
+ when scan(FALSE)
259
+ false
260
+ when scan(NULL)
261
+ nil
262
+ when (string = parse_string) != UNPARSED
263
+ string
264
+ when scan(ARRAY_OPEN)
265
+ parse_array
266
+ when scan(OBJECT_OPEN)
267
+ parse_object
268
+ else
269
+ UNPARSED
270
+ end
271
+ end
272
+
273
+ def parse_array
274
+ result = []
275
+ until eos?
276
+ case
277
+ when (value = parse_value) != UNPARSED
278
+ result << value
279
+ skip(IGNORE)
280
+ unless scan(COLLECTION_DELIMITER) or match?(ARRAY_CLOSE)
281
+ raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
282
+ end
283
+ when scan(ARRAY_CLOSE)
284
+ break
285
+ when skip(IGNORE)
286
+ ;
287
+ else
288
+ raise ParserError, "unexpected token in array at '#{peek(20)}'!"
289
+ end
290
+ end
291
+ result
292
+ end
293
+
294
+ def parse_object
295
+ result = {}
296
+ until eos?
297
+ case
298
+ when (string = parse_string) != UNPARSED
299
+ skip(IGNORE)
300
+ unless scan(PAIR_DELIMITER)
301
+ raise ParserError, "expected ':' in object at '#{peek(20)}'!"
302
+ end
303
+ skip(IGNORE)
304
+ unless (value = parse_value).equal? UNPARSED
305
+ result[string] = value
306
+ skip(IGNORE)
307
+ unless scan(COLLECTION_DELIMITER) or match?(OBJECT_CLOSE)
308
+ raise ParserError,
309
+ "expected ',' or '}' in object at '#{peek(20)}'!"
310
+ end
311
+ else
312
+ raise ParserError, "expected value in object at '#{peek(20)}'!"
313
+ end
314
+ when scan(OBJECT_CLOSE)
315
+ if klassname = result['json_class']
316
+ klass = klassname.sub(/^:+/, '').split(/::/).inject(Object) do |p,k|
317
+ p.const_get(k) rescue nil
318
+ end
319
+ break unless klass and klass.json_creatable?
320
+ result = klass.json_create(result)
321
+ end
322
+ break
323
+ when skip(IGNORE)
324
+ ;
325
+ else
326
+ raise ParserError, "unexpected token in object at '#{peek(20)}'!"
327
+ end
328
+ end
329
+ result
330
+ end
331
+ end
332
+
333
+ # This class is used to create State instances, that are use to hold data
334
+ # while unparsing a Ruby data structure into a JSON string.
335
+ class State
336
+ # Creates a State object from _opts_, which ought to be Hash to create a
337
+ # new State instance configured by opts, something else to create an
338
+ # unconfigured instance. If _opts_ is a State object, it is just returned.
339
+ def self.from_state(opts)
340
+ case opts
341
+ when self
342
+ opts
343
+ when Hash
344
+ new(opts)
345
+ else
346
+ new
347
+ end
348
+ end
349
+
350
+ # Instantiates a new State object, configured by _opts_.
351
+ def initialize(opts = {})
352
+ @indent = opts[:indent] || ''
353
+ @space = opts[:space] || ''
354
+ @object_nl = opts[:object_nl] || ''
355
+ @array_nl = opts[:array_nl] || ''
356
+ @seen = {}
357
+ end
358
+
359
+ # This string is used to indent levels in the JSON string.
360
+ attr_accessor :indent
361
+
362
+ # This string is used to include a space between the tokens in a JSON
363
+ # string.
364
+ attr_accessor :space
365
+
366
+ # This string is put at the end of a line that holds a JSON object (or
367
+ # Hash).
368
+ attr_accessor :object_nl
369
+
370
+ # This string is put at the end of a line that holds a JSON array.
371
+ attr_accessor :array_nl
372
+
373
+ # Returns _true_, if _object_ was already seen during this Unparsing run.
374
+ def seen?(object)
375
+ @seen.key?(object.__id__)
376
+ end
377
+
378
+ # Remember _object_, to find out if it was already encountered (to find out
379
+ # if a cyclic data structure is unparsed).
380
+ def remember(object)
381
+ @seen[object.__id__] = true
382
+ end
383
+
384
+ # Forget _object_ for this Unparsing run.
385
+ def forget(object)
386
+ @seen.delete object.__id__
387
+ end
388
+ end
389
+
390
+ module_function
391
+
392
+ # Convert _string_ from UTF8 encoding to UTF16 (big endian) encoding and
393
+ # return it.
394
+ def utf8_to_utf16(string)
395
+ JSON::UTF8toUTF16.iconv(string).unpack('H*')[0]
396
+ end
397
+
398
+ # Convert _string_ from UTF16 (big endian) encoding to UTF8 encoding and
399
+ # return it.
400
+ def utf16_to_utf8(string)
401
+ bytes = '' << string[0, 2].to_i(16) << string[2, 2].to_i(16)
402
+ JSON::UTF16toUTF8.iconv(bytes)
403
+ end
404
+
405
+ # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
406
+ # UTF16 big endian characters as \u????, and return it.
407
+ def utf8_to_json(string)
408
+ i, n, result = 0, string.size, ''
409
+ while i < n
410
+ char = string[i]
411
+ case
412
+ when char == ?\b then result << '\b'
413
+ when char == ?\t then result << '\t'
414
+ when char == ?\n then result << '\n'
415
+ when char == ?\f then result << '\f'
416
+ when char == ?\r then result << '\r'
417
+ when char == ?" then result << '\"'
418
+ when char == ?\\ then result << '\\\\'
419
+ when char.between?(0x0, 0x1f) then result << "\\u%04x" % char
420
+ when char.between?(0x20, 0x7f) then result << char
421
+ when !(JSON.support_unicode? && $KCODE == 'UTF8')
422
+ # if utf8 mode is switched off or unicode not supported, just pass
423
+ # bytes through:
424
+ result << char
425
+ when char & 0xe0 == 0xc0
426
+ result << '\u' << utf8_to_utf16(string[i, 2])
427
+ i += 1
428
+ when char & 0xf0 == 0xe0
429
+ result << '\u' << utf8_to_utf16(string[i, 3])
430
+ i += 2
431
+ when char & 0xf8 == 0xf0
432
+ result << '\u' << utf8_to_utf16(string[i, 4])
433
+ i += 3
434
+ when char & 0xfc == 0xf8
435
+ result << '\u' << utf8_to_utf16(string[i, 5])
436
+ i += 4
437
+ when char & 0xfe == 0xfc
438
+ result << '\u' << utf8_to_utf16(string[i, 6])
439
+ i += 5
440
+ else
441
+ raise JSON::UnparserError, "Encountered unknown UTF-8 byte: %x!" % char
442
+ end
443
+ i += 1
444
+ end
445
+ result
446
+ end
447
+
448
+ # Parse the JSON string _source_ into a Ruby data structure and return it.
449
+ def parse(source)
450
+ Parser.new(source).parse
451
+ end
452
+
453
+ # Unparse the Ruby data structure _obj_ into a single line JSON string and
454
+ # return it. _state_ is a JSON::State object, that can be used to configure
455
+ # the output further.
456
+ def unparse(obj, state = nil)
457
+ obj.to_json(JSON::State.from_state(state))
458
+ end
459
+
460
+ # Unparse the Ruby data structure _obj_ into a JSON string and return it.
461
+ # The returned string is a prettier form of the string returned by #unparse.
462
+ def pretty_unparse(obj)
463
+ state = JSON::State.new(
464
+ :indent => ' ',
465
+ :space => ' ',
466
+ :object_nl => "\n",
467
+ :array_nl => "\n"
468
+ )
469
+ obj.to_json(state)
470
+ end
471
+ end
472
+
473
+ class Object
474
+ # Converts this object to a string (calling #to_s), converts
475
+ # it to a JSON string, and returns the result. This is a fallback, if no
476
+ # special method #to_json was defined for some object.
477
+ # _state_ is a JSON::State object, that can also be used
478
+ # to configure the produced JSON string output further.
479
+
480
+ def to_json(*) to_s.to_json end
481
+ end
482
+
483
+ class Hash
484
+ # Returns a JSON string containing a JSON object, that is unparsed from
485
+ # this Hash instance.
486
+ # _state_ is a JSON::State object, that can also be used to configure the
487
+ # produced JSON string output further.
488
+ # _depth_ is used to find out nesting depth, to indent accordingly.
489
+ def to_json(state = nil, depth = 0)
490
+ state = JSON::State.from_state(state)
491
+ json_check_circular(state) { json_transform(state, depth) }
492
+ end
493
+
494
+ private
495
+
496
+ def json_check_circular(state)
497
+ if state
498
+ state.seen?(self) and raise JSON::CircularDatastructure,
499
+ "circular data structures not supported!"
500
+ state.remember self
501
+ end
502
+ yield
503
+ ensure
504
+ state and state.forget self
505
+ end
506
+
507
+ def json_shift(state, depth)
508
+ state and not state.object_nl.empty? or return ''
509
+ state.indent * depth
510
+ end
511
+
512
+ def json_transform(state, depth)
513
+ delim = ','
514
+ delim << state.object_nl if state
515
+ result = '{'
516
+ result << state.object_nl if state
517
+ result << map { |key,value|
518
+ json_shift(state, depth + 1) <<
519
+ key.to_s.to_json(state, depth + 1) <<
520
+ ':' << state.space << value.to_json(state, depth + 1)
521
+ }.join(delim)
522
+ result << state.object_nl if state
523
+ result << json_shift(state, depth)
524
+ result << '}'
525
+ result
526
+ end
527
+ end
528
+
529
+ class Array
530
+ # Returns a JSON string containing a JSON array, that is unparsed from
531
+ # this Array instance.
532
+ # _state_ is a JSON::State object, that can also be used to configure the
533
+ # produced JSON string output further.
534
+ # _depth_ is used to find out nesting depth, to indent accordingly.
535
+ def to_json(state = nil, depth = 0)
536
+ state = JSON::State.from_state(state)
537
+ json_check_circular(state) { json_transform(state, depth) }
538
+ end
539
+
540
+ private
541
+
542
+ def json_check_circular(state)
543
+ if state
544
+ state.seen?(self) and raise JSON::CircularDatastructure,
545
+ "circular data structures not supported!"
546
+ state.remember self
547
+ end
548
+ yield
549
+ ensure
550
+ state and state.forget self
551
+ end
552
+
553
+ def json_shift(state, depth)
554
+ state and not state.array_nl.empty? or return ''
555
+ state.indent * depth
556
+ end
557
+
558
+ def json_transform(state, depth)
559
+ delim = ','
560
+ delim << state.array_nl if state
561
+ result = '['
562
+ result << state.array_nl if state
563
+ result << map { |value|
564
+ json_shift(state, depth + 1) << value.to_json(state, depth + 1)
565
+ }.join(delim)
566
+ result << state.array_nl if state
567
+ result << json_shift(state, depth)
568
+ result << ']'
569
+ result
570
+ end
571
+ end
572
+
573
+ class Integer
574
+ # Returns a JSON string representation for this Integer number.
575
+ def to_json(*) to_s end
576
+ end
577
+
578
+ class Float
579
+ # Returns a JSON string representation for this Float number.
580
+ def to_json(*) to_s end
581
+ end
582
+
583
+ class String
584
+ # This string should be encoded with UTF-8 (if JSON unicode support is
585
+ # enabled). A call to this method returns a JSON string
586
+ # encoded with UTF16 big endian characters as \u????. If
587
+ # JSON.support_unicode? is false only control characters are encoded this
588
+ # way, all 8-bit bytes are just passed through.
589
+ def to_json(*)
590
+ '"' << JSON::utf8_to_json(self) << '"'
591
+ end
592
+
593
+ # Raw Strings are JSON Objects (the raw bytes are stored in an array for the
594
+ # key "raw"). The Ruby String can be created by this class method.
595
+ def self.json_create(o)
596
+ o['raw'].pack('C*')
597
+ end
598
+
599
+ # This method creates a raw object, that can be nested into other data
600
+ # structures and will be unparsed as a raw string.
601
+ def to_json_raw_object
602
+ {
603
+ 'json_class' => self.class.name,
604
+ 'raw' => self.unpack('C*'),
605
+ }
606
+ end
607
+
608
+ # This method should be used, if you want to convert raw strings to JSON
609
+ # instead of UTF-8 strings, e. g. binary data (and JSON Unicode support is
610
+ # enabled).
611
+ def to_json_raw(*args)
612
+ to_json_raw_object.to_json(*args)
613
+ end
614
+ end
615
+
616
+ class TrueClass
617
+ # Returns a JSON string for true: 'true'.
618
+ def to_json(*) to_s end
619
+ end
620
+
621
+ class FalseClass
622
+ # Returns a JSON string for false: 'false'.
623
+ def to_json(*) to_s end
624
+ end
625
+
626
+ class NilClass
627
+ # Returns a JSON string for nil: 'null'.
628
+ def to_json(*) 'null' end
629
+ end
630
+
631
+ module Kernel
632
+ # Outputs _objs_ to STDOUT as JSON strings in the shortest form, that is in
633
+ # one line.
634
+ def j(*objs)
635
+ objs.each do |obj|
636
+ puts JSON::unparse(obj)
637
+ end
638
+ nil
639
+ end
640
+
641
+ # Ouputs _objs_ to STDOUT as JSON strings in a pretty format, with
642
+ # indentation and over many lines.
643
+ def jj(*objs)
644
+ objs.each do |obj|
645
+ puts JSON::pretty_unparse(obj)
646
+ end
647
+ nil
648
+ end
649
+ end
650
+
651
+ class Class
652
+ # Returns true, if this class can be used to create an instance
653
+ # from a serialised JSON string. The class has to implement a class
654
+ # method _json_create_ that expects a hash as first parameter, which includes
655
+ # the required data.
656
+ def json_creatable?
657
+ respond_to?(:json_create)
658
+ end
659
+ end
660
+ # vim: set et sw=2 ts=2:
661
+
662
+
663
+
664
+
665
+ # _____ _
666
+ # |_ _|__ ___| |_
667
+ # | |/ _ \/ __| __|
668
+ # | | __/\__ \ |_
669
+ # |_|\___||___/\__|
670
+ #
671
+ =begin test
672
+
673
+ require 'test/unit'
674
+
675
+ class TC_JSON < Test::Unit::TestCase
676
+
677
+ include JSON
678
+
679
+ class A
680
+ def initialize(a)
681
+ @a = a
682
+ end
683
+
684
+ attr_reader :a
685
+
686
+ def ==(other)
687
+ a == other.a
688
+ end
689
+
690
+ def self.json_create(object)
691
+ new(*object['args'])
692
+ end
693
+
694
+ def to_json(*args)
695
+ {
696
+ 'json_class' => self.class,
697
+ 'args' => [ @a ],
698
+ }.to_json(*args)
699
+ end
700
+ end
701
+
702
+ def setup
703
+ $KCODE = 'UTF8'
704
+ @ary = [1, "foo", 3.14, 4711.0, 2.718, nil, [1,-2,3], false, true]
705
+ @ary_to_parse = ["1", '"foo"', "3.14", "4711.0", "2.718", "null",
706
+ "[1,-2,3]", "false", "true"]
707
+ @hash = {
708
+ 'a' => 2,
709
+ 'b' => 3.141,
710
+ 'c' => 'c',
711
+ 'd' => [ 1, "b", 3.14 ],
712
+ 'e' => { 'foo' => 'bar' },
713
+ 'g' => "\"\0\037",
714
+ 'h' => 1000.0,
715
+ 'i' => 0.001
716
+ }
717
+ @json = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},' +
718
+ '"g":"\\"\\u0000\\u001f","h":1.0E3,"i":1.0E-3}'
719
+ @json2 = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},' +
720
+ '"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}'
721
+ end
722
+
723
+ def test_parse_value
724
+ assert_equal("", parse('""'))
725
+ assert_equal("\\", parse('"\\\\"'))
726
+ assert_equal('"', parse('"\""'))
727
+ assert_equal('\\"\\', parse('"\\\\\\"\\\\"'))
728
+ assert_equal("\\a\"\b\f\n\r\t\0\037",
729
+ parse('"\\a\"\b\f\n\r\t\u0000\u001f"'))
730
+ for i in 0 ... @ary.size
731
+ assert_equal(@ary[i], parse(@ary_to_parse[i]))
732
+ end
733
+ end
734
+
735
+ def test_parse_array
736
+ assert_equal([], parse('[]'))
737
+ assert_equal([], parse(' [ ] '))
738
+ assert_equal([1], parse('[1]'))
739
+ assert_equal([1], parse(' [ 1 ] '))
740
+ assert_equal(@ary,
741
+ parse('[1,"foo",3.14,47.11e+2,2718.E-3,null,[1,-2,3],false,true]'))
742
+ assert_equal(@ary, parse(%Q{ [ 1 , "foo" , 3.14 \t , 47.11e+2
743
+ , 2718.E-3 ,\n null , [1, -2, 3 ], false , true\n ] }))
744
+ end
745
+
746
+ def test_parse_object
747
+ assert_equal({}, parse('{}'))
748
+ assert_equal({}, parse(' { } '))
749
+ assert_equal({'foo'=>'bar'}, parse('{"foo":"bar"}'))
750
+ assert_equal({'foo'=>'bar'}, parse(' { "foo" : "bar" } '))
751
+ end
752
+
753
+ def test_unparse
754
+ json = unparse(@hash)
755
+ assert_equal(@json2, json)
756
+ parsed_json = parse(json)
757
+ assert_equal(@hash, parsed_json)
758
+ json = unparse({1=>2})
759
+ assert_equal('{"1":2}', json)
760
+ parsed_json = parse(json)
761
+ assert_equal({"1"=>2}, parsed_json)
762
+ end
763
+
764
+ def test_parser_reset
765
+ parser = Parser.new(@json)
766
+ assert_equal(@hash, parser.parse)
767
+ assert_equal(@hash, parser.parse)
768
+ end
769
+
770
+ def test_unicode
771
+ assert_equal '""', ''.to_json
772
+ assert_equal '"\\b"', "\b".to_json
773
+ assert_equal '"\u0001"', 0x1.chr.to_json
774
+ assert_equal '"\u001f"', 0x1f.chr.to_json
775
+ assert_equal '" "', ' '.to_json
776
+ assert_equal "\"#{0x7f.chr}\"", 0x7f.chr.to_json
777
+ utf8 = '© ≠ €!'
778
+ json = '"\u00a9 \u2260 \u20ac!"'
779
+ assert_equal json, utf8.to_json
780
+ assert_equal utf8, parse(json)
781
+ utf8 = "\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"
782
+ json = '"\u3042\u3044\u3046\u3048\u304a"'
783
+ assert_equal json, utf8.to_json
784
+ assert_equal utf8, parse(json)
785
+ utf8 = 'საქართველო'
786
+ json = '"\u10e1\u10d0\u10e5\u10d0\u10e0\u10d7\u10d5\u10d4\u10da\u10dd"'
787
+ assert_equal json, utf8.to_json
788
+ assert_equal utf8, parse(json)
789
+ end
790
+
791
+ def test_comments
792
+ json = <<EOT
793
+ {
794
+ "key1":"value1", // eol comment
795
+ "key2":"value2" /* multi line
796
+ * comment */,
797
+ "key3":"value3" /* multi line
798
+ // nested eol comment
799
+ * comment */
800
+ }
801
+ EOT
802
+ assert_equal(
803
+ { "key1" => "value1", "key2" => "value2", "key3" => "value3" },
804
+ parse(json))
805
+ json = <<EOT
806
+ {
807
+ "key1":"value1" /* multi line
808
+ // nested eol comment
809
+ /* illegal nested multi line comment */
810
+ * comment */
811
+ }
812
+ EOT
813
+ assert_raises(ParserError) { parse(json) }
814
+ json = <<EOT
815
+ {
816
+ "key1":"value1" /* multi line
817
+ // nested eol comment
818
+ closed multi comment */
819
+ and again, throw an Error */
820
+ }
821
+ EOT
822
+ assert_raises(ParserError) { parse(json) }
823
+ json = <<EOT
824
+ {
825
+ "key1":"value1" /*/*/
826
+ }
827
+ EOT
828
+ assert_equal({ "key1" => "value1" }, parse(json))
829
+ end
830
+
831
+ def test_extended_json
832
+ a = A.new(666)
833
+ json = a.to_json
834
+ a_again = JSON.parse(json)
835
+ assert_kind_of a.class, a_again
836
+ assert_equal a, a_again
837
+ end
838
+
839
+ def test_raw_strings
840
+ raw = ''
841
+ raw_array = []
842
+ for i in 0..255
843
+ raw << i
844
+ raw_array << i
845
+ end
846
+ json = raw.to_json_raw
847
+ json_raw_object = raw.to_json_raw_object
848
+ hash = { 'json_class' => 'String', 'raw'=> raw_array }
849
+ assert_equal hash, json_raw_object
850
+ json_raw = <<EOT.chomp
851
+ {\"json_class\":\"String\",\"raw\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255]}
852
+ EOT
853
+ # "
854
+ assert_equal json_raw, json
855
+ raw_again = JSON.parse(json)
856
+ assert_equal raw, raw_again
857
+ end
858
+
859
+ def test_utf8_mode
860
+ $KCODE = 'NONE'
861
+ utf8 = "© ≠ €! - \001"
862
+ json = "\"© ≠ €! - \\u0001\""
863
+ assert_equal json, utf8.to_json
864
+ assert_equal utf8, parse(json)
865
+ assert JSON.support_unicode?
866
+ $KCODE = 'UTF8'
867
+ utf8 = '© ≠ €!'
868
+ json = '"\u00a9 \u2260 \u20ac!"'
869
+ assert_equal json, utf8.to_json
870
+ assert_equal utf8, parse(json)
871
+ JSON.support_unicode = false
872
+ assert !JSON.support_unicode?
873
+ utf8 = "© ≠ €! - \001"
874
+ json = "\"© ≠ €! - \\u0001\""
875
+ assert_equal json, utf8.to_json
876
+ assert_equal utf8, parse(json)
877
+ end
878
+
879
+ def test_backslash
880
+ json = '"\\\\.(?i:gif|jpe?g|png)$"'
881
+ data = JSON.parse(json)
882
+ assert_equal json, JSON.unparse(data)
883
+ json = '"\\""'
884
+ data = JSON.parse(json)
885
+ assert_equal json, JSON.unparse(data)
886
+ end
887
+ end
888
+
889
+ =end
890
+
891
+ # vim: set et sw=2 ts=2: