lookout 2.3.0 → 3.0.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 (328) hide show
  1. checksums.yaml +7 -0
  2. data/README +351 -181
  3. data/Rakefile +20 -5
  4. data/lib/lookout-3.0.rb +138 -0
  5. data/lib/lookout-3.0/actual.rb +30 -0
  6. data/lib/lookout-3.0/actual/method.rb +31 -0
  7. data/lib/lookout-3.0/actual/not.rb +13 -0
  8. data/lib/lookout-3.0/actual/not/method.rb +10 -0
  9. data/lib/lookout-3.0/aphonic.rb +44 -0
  10. data/lib/lookout-3.0/diff.rb +29 -0
  11. data/lib/{lookout → lookout-3.0}/diff/algorithms.rb +1 -1
  12. data/lib/lookout-3.0/diff/algorithms/difflib.rb +62 -0
  13. data/lib/lookout-3.0/diff/algorithms/difflib/position.rb +63 -0
  14. data/lib/{lookout/diff/algorithms/difflib/position/to.rb → lookout-3.0/diff/algorithms/difflib/position/new.rb} +8 -17
  15. data/lib/lookout-3.0/diff/formats.rb +5 -0
  16. data/lib/lookout-3.0/diff/formats/inline.rb +43 -0
  17. data/lib/lookout-3.0/diff/formats/set.rb +48 -0
  18. data/lib/lookout-3.0/diff/formats/unified.rb +56 -0
  19. data/lib/lookout-3.0/diff/group.rb +57 -0
  20. data/lib/lookout-3.0/diff/groups.rb +47 -0
  21. data/lib/lookout-3.0/diff/match.rb +31 -0
  22. data/lib/lookout-3.0/diff/operation.rb +41 -0
  23. data/lib/lookout-3.0/diff/operations.rb +35 -0
  24. data/lib/lookout-3.0/diff/operations/copy.rb +25 -0
  25. data/lib/lookout-3.0/diff/operations/delete.rb +5 -0
  26. data/lib/lookout-3.0/diff/operations/insert.rb +5 -0
  27. data/lib/lookout-3.0/diff/operations/replace.rb +6 -0
  28. data/lib/lookout-3.0/diff/slice.rb +97 -0
  29. data/lib/lookout-3.0/difference.rb +10 -0
  30. data/lib/lookout-3.0/difference/array.rb +22 -0
  31. data/lib/lookout-3.0/difference/exception.rb +40 -0
  32. data/lib/lookout-3.0/difference/hash.rb +31 -0
  33. data/lib/lookout-3.0/difference/lookout.rb +5 -0
  34. data/lib/lookout-3.0/difference/lookout/actual.rb +6 -0
  35. data/lib/lookout-3.0/difference/lookout/actual/method.rb +13 -0
  36. data/lib/lookout-3.0/difference/lookout/actual/not.rb +6 -0
  37. data/lib/lookout-3.0/difference/lookout/actual/not/method.rb +9 -0
  38. data/lib/lookout-3.0/difference/lookout/output.rb +8 -0
  39. data/lib/lookout-3.0/difference/lookout/reception.rb +21 -0
  40. data/lib/lookout-3.0/difference/lookout/warning.rb +9 -0
  41. data/lib/lookout-3.0/difference/module.rb +12 -0
  42. data/lib/lookout-3.0/difference/object.rb +73 -0
  43. data/lib/lookout-3.0/difference/range.rb +12 -0
  44. data/lib/lookout-3.0/difference/regexp.rb +12 -0
  45. data/lib/lookout-3.0/difference/string.rb +21 -0
  46. data/lib/lookout-3.0/difference/symbol.rb +21 -0
  47. data/lib/lookout-3.0/encode.rb +20 -0
  48. data/lib/lookout-3.0/exception.rb +79 -0
  49. data/lib/lookout-3.0/exception/backtrace.rb +65 -0
  50. data/lib/lookout-3.0/exception/unknown.rb +25 -0
  51. data/lib/lookout-3.0/expect.rb +32 -0
  52. data/lib/lookout-3.0/expect/classes.rb +6 -0
  53. data/lib/lookout-3.0/expect/classes/exception.rb +27 -0
  54. data/lib/lookout-3.0/expect/exception.rb +30 -0
  55. data/lib/lookout-3.0/expect/object.rb +54 -0
  56. data/lib/lookout-3.0/expect/object/context.rb +149 -0
  57. data/lib/lookout-3.0/expectations.rb +69 -0
  58. data/lib/lookout-3.0/expectations/context.rb +52 -0
  59. data/lib/lookout-3.0/expected.rb +10 -0
  60. data/lib/lookout-3.0/expected/array.rb +16 -0
  61. data/lib/lookout-3.0/expected/classes.rb +5 -0
  62. data/lib/lookout-3.0/expected/classes/exception.rb +14 -0
  63. data/lib/lookout-3.0/expected/exception.rb +46 -0
  64. data/lib/lookout-3.0/expected/falseclass.rb +9 -0
  65. data/lib/lookout-3.0/expected/hash.rb +14 -0
  66. data/lib/lookout-3.0/expected/lookout.rb +5 -0
  67. data/lib/lookout-3.0/expected/lookout/actual.rb +5 -0
  68. data/lib/lookout-3.0/expected/lookout/actual/method.rb +13 -0
  69. data/lib/lookout-3.0/expected/lookout/actual/not.rb +6 -0
  70. data/lib/lookout-3.0/expected/lookout/actual/not/method.rb +13 -0
  71. data/lib/lookout-3.0/expected/lookout/output.rb +26 -0
  72. data/lib/lookout-3.0/expected/lookout/reception.rb +24 -0
  73. data/lib/lookout-3.0/expected/lookout/warning.rb +29 -0
  74. data/lib/lookout-3.0/expected/module.rb +12 -0
  75. data/lib/lookout-3.0/expected/object.rb +30 -0
  76. data/lib/lookout-3.0/expected/range.rb +12 -0
  77. data/lib/lookout-3.0/expected/regexp.rb +12 -0
  78. data/lib/lookout-3.0/expected/string.rb +11 -0
  79. data/lib/lookout-3.0/expected/symbol.rb +21 -0
  80. data/lib/lookout-3.0/expected/trueclass.rb +9 -0
  81. data/lib/lookout-3.0/inspect.rb +45 -0
  82. data/lib/lookout-3.0/interfaces.rb +5 -0
  83. data/lib/lookout-3.0/interfaces/commandline.rb +109 -0
  84. data/lib/lookout-3.0/literal.rb +18 -0
  85. data/lib/lookout-3.0/mock.rb +24 -0
  86. data/lib/lookout-3.0/object.rb +6 -0
  87. data/lib/lookout-3.0/object/not.rb +16 -0
  88. data/lib/lookout-3.0/object/not/receive.rb +18 -0
  89. data/lib/lookout-3.0/object/to.rb +12 -0
  90. data/lib/lookout-3.0/object/to/receive.rb +18 -0
  91. data/lib/lookout-3.0/output.rb +20 -0
  92. data/lib/lookout-3.0/plugins.rb +7 -0
  93. data/lib/lookout-3.0/reception.rb +128 -0
  94. data/lib/lookout-3.0/reception/arguments.rb +20 -0
  95. data/lib/lookout-3.0/reception/arguments/any.rb +16 -0
  96. data/lib/lookout-3.0/reception/arguments/error.rb +5 -0
  97. data/lib/lookout-3.0/reception/arguments/list.rb +17 -0
  98. data/lib/lookout-3.0/reception/arguments/none.rb +6 -0
  99. data/lib/lookout-3.0/reception/error.rb +24 -0
  100. data/lib/lookout-3.0/result.rb +16 -0
  101. data/lib/lookout-3.0/results.rb +5 -0
  102. data/lib/lookout-3.0/results/error.rb +18 -0
  103. data/lib/lookout-3.0/results/failure.rb +15 -0
  104. data/lib/lookout-3.0/results/success.rb +7 -0
  105. data/lib/lookout-3.0/stub.rb +55 -0
  106. data/lib/lookout-3.0/version.rb +133 -0
  107. data/lib/lookout-3.0/warning.rb +40 -0
  108. data/test/unit/examples.rb +208 -83
  109. data/test/unit/{lookout.rb → lookout-3.0.rb} +0 -0
  110. data/test/unit/lookout-3.0/actual.rb +13 -0
  111. data/test/unit/lookout-3.0/actual/method.rb +31 -0
  112. data/test/unit/lookout-3.0/actual/not.rb +15 -0
  113. data/test/unit/lookout-3.0/actual/not/method.rb +7 -0
  114. data/test/unit/lookout-3.0/aphonic.rb +31 -0
  115. data/test/unit/{lookout → lookout-3.0}/diff.rb +0 -0
  116. data/test/unit/{lookout/diff/group.rb → lookout-3.0/diff/algorithms.rb} +0 -0
  117. data/test/unit/lookout-3.0/diff/algorithms/difflib.rb +56 -0
  118. data/test/unit/lookout-3.0/diff/algorithms/difflib/position.rb +92 -0
  119. data/test/unit/{lookout/diff/algorithms/difflib/position/to.rb → lookout-3.0/diff/algorithms/difflib/position/new.rb} +1 -2
  120. data/test/unit/{lookout/results.rb → lookout-3.0/diff/formats.rb} +0 -0
  121. data/test/unit/{lookout → lookout-3.0}/diff/formats/inline.rb +0 -0
  122. data/test/unit/lookout-3.0/diff/formats/set.rb +26 -0
  123. data/test/unit/{lookout → lookout-3.0}/diff/formats/unified.rb +0 -0
  124. data/test/unit/{lookout/results/error.rb → lookout-3.0/diff/group.rb} +0 -0
  125. data/test/unit/lookout-3.0/diff/groups.rb +102 -0
  126. data/test/unit/{lookout → lookout-3.0}/diff/match.rb +0 -0
  127. data/test/unit/lookout-3.0/diff/operation.rb +17 -0
  128. data/test/unit/lookout-3.0/diff/operations.rb +22 -0
  129. data/test/unit/lookout-3.0/diff/operations/copy.rb +50 -0
  130. data/test/unit/lookout-3.0/diff/operations/delete.rb +45 -0
  131. data/test/unit/lookout-3.0/diff/operations/insert.rb +45 -0
  132. data/test/unit/lookout-3.0/diff/operations/replace.rb +45 -0
  133. data/test/unit/lookout-3.0/diff/slice.rb +56 -0
  134. data/test/unit/{lookout/results/failures/behavior.rb → lookout-3.0/difference.rb} +0 -0
  135. data/test/unit/lookout-3.0/difference/array.rb +32 -0
  136. data/test/unit/lookout-3.0/difference/exception.rb +69 -0
  137. data/test/unit/lookout-3.0/difference/hash.rb +30 -0
  138. data/test/unit/{lookout/results/failures/state.rb → lookout-3.0/difference/lookout.rb} +0 -0
  139. data/test/unit/{lookout/results/fulfilled.rb → lookout-3.0/difference/lookout/actual.rb} +0 -0
  140. data/test/unit/lookout-3.0/difference/lookout/actual/method.rb +7 -0
  141. data/test/unit/{lookout/runners/console.rb → lookout-3.0/difference/lookout/actual/not.rb} +0 -0
  142. data/test/unit/lookout-3.0/difference/lookout/actual/not/method.rb +7 -0
  143. data/test/unit/lookout-3.0/difference/lookout/output.rb +11 -0
  144. data/test/unit/lookout-3.0/difference/lookout/reception.rb +11 -0
  145. data/test/unit/lookout-3.0/difference/lookout/warning.rb +11 -0
  146. data/test/unit/lookout-3.0/difference/module.rb +11 -0
  147. data/test/unit/lookout-3.0/difference/object.rb +31 -0
  148. data/test/unit/lookout-3.0/difference/range.rb +11 -0
  149. data/test/unit/lookout-3.0/difference/regexp.rb +11 -0
  150. data/test/unit/lookout-3.0/difference/string.rb +29 -0
  151. data/test/unit/lookout-3.0/difference/symbol.rb +11 -0
  152. data/test/unit/lookout-3.0/encode.rb +28 -0
  153. data/test/unit/lookout-3.0/exception.rb +107 -0
  154. data/test/unit/lookout-3.0/exception/backtrace.rb +75 -0
  155. data/test/unit/lookout-3.0/exception/unknown.rb +23 -0
  156. data/test/unit/lookout-3.0/expect.rb +15 -0
  157. data/test/unit/{lookout/ui/console.rb → lookout-3.0/expect/classes.rb} +0 -0
  158. data/test/unit/lookout-3.0/expect/classes/exception.rb +41 -0
  159. data/test/unit/lookout-3.0/expect/exception.rb +63 -0
  160. data/test/unit/lookout-3.0/expect/object.rb +55 -0
  161. data/test/unit/lookout-3.0/expect/object/context.rb +120 -0
  162. data/test/unit/lookout-3.0/expectations.rb +55 -0
  163. data/test/unit/lookout-3.0/expectations/context.rb +44 -0
  164. data/test/unit/lookout-3.0/expected.rb +4 -0
  165. data/test/unit/lookout-3.0/expected/array.rb +19 -0
  166. data/test/unit/lookout-3.0/expected/classes.rb +4 -0
  167. data/test/unit/lookout-3.0/expected/classes/exception.rb +7 -0
  168. data/test/unit/lookout-3.0/expected/exception.rb +24 -0
  169. data/test/unit/lookout-3.0/expected/falseclass.rb +23 -0
  170. data/test/unit/lookout-3.0/expected/hash.rb +23 -0
  171. data/test/unit/lookout-3.0/expected/lookout.rb +4 -0
  172. data/test/unit/lookout-3.0/expected/lookout/actual.rb +4 -0
  173. data/test/unit/lookout-3.0/expected/lookout/actual/method.rb +11 -0
  174. data/test/unit/lookout-3.0/expected/lookout/actual/not.rb +4 -0
  175. data/test/unit/lookout-3.0/expected/lookout/actual/not/method.rb +11 -0
  176. data/test/unit/lookout-3.0/expected/lookout/output.rb +27 -0
  177. data/test/unit/lookout-3.0/expected/lookout/reception.rb +25 -0
  178. data/test/unit/lookout-3.0/expected/lookout/warning.rb +48 -0
  179. data/test/unit/lookout-3.0/expected/module.rb +23 -0
  180. data/test/unit/lookout-3.0/expected/object.rb +24 -0
  181. data/test/unit/lookout-3.0/expected/range.rb +19 -0
  182. data/test/unit/lookout-3.0/expected/regexp.rb +19 -0
  183. data/test/unit/lookout-3.0/expected/string.rb +44 -0
  184. data/test/unit/lookout-3.0/expected/symbol.rb +35 -0
  185. data/test/unit/lookout-3.0/expected/trueclass.rb +23 -0
  186. data/test/unit/lookout-3.0/inspect.rb +39 -0
  187. data/test/unit/lookout-3.0/interfaces.rb +4 -0
  188. data/test/unit/lookout-3.0/interfaces/commandline.rb +4 -0
  189. data/test/unit/lookout-3.0/literal.rb +15 -0
  190. data/test/unit/lookout-3.0/mock.rb +22 -0
  191. data/test/unit/lookout-3.0/object.rb +4 -0
  192. data/test/unit/lookout-3.0/object/not.rb +7 -0
  193. data/test/unit/lookout-3.0/object/not/receive.rb +9 -0
  194. data/test/unit/lookout-3.0/object/to.rb +7 -0
  195. data/test/unit/lookout-3.0/object/to/receive.rb +9 -0
  196. data/test/unit/lookout-3.0/output.rb +31 -0
  197. data/test/unit/lookout-3.0/plugins.rb +4 -0
  198. data/test/unit/lookout-3.0/reception.rb +86 -0
  199. data/test/unit/lookout-3.0/reception/arguments.rb +23 -0
  200. data/test/unit/lookout-3.0/reception/arguments/any.rb +15 -0
  201. data/test/unit/lookout-3.0/reception/arguments/error.rb +4 -0
  202. data/test/unit/lookout-3.0/reception/arguments/list.rb +19 -0
  203. data/test/unit/lookout-3.0/reception/arguments/none.rb +15 -0
  204. data/test/unit/lookout-3.0/reception/error.rb +4 -0
  205. data/test/unit/lookout-3.0/result.rb +27 -0
  206. data/test/unit/lookout-3.0/results.rb +4 -0
  207. data/test/unit/lookout-3.0/results/error.rb +37 -0
  208. data/test/unit/lookout-3.0/results/failure.rb +21 -0
  209. data/test/unit/lookout-3.0/results/success.rb +4 -0
  210. data/test/unit/lookout-3.0/stub.rb +53 -0
  211. data/test/unit/lookout-3.0/version.rb +4 -0
  212. data/test/unit/lookout-3.0/warning.rb +47 -0
  213. metadata +1159 -456
  214. data/lib/lookout.rb +0 -30
  215. data/lib/lookout/aphonic.rb +0 -40
  216. data/lib/lookout/diff.rb +0 -10
  217. data/lib/lookout/diff/algorithms/difflib.rb +0 -38
  218. data/lib/lookout/diff/algorithms/difflib/position.rb +0 -92
  219. data/lib/lookout/diff/formats.rb +0 -7
  220. data/lib/lookout/diff/formats/hash.rb +0 -53
  221. data/lib/lookout/diff/formats/inline.rb +0 -39
  222. data/lib/lookout/diff/formats/unified.rb +0 -57
  223. data/lib/lookout/diff/group.rb +0 -61
  224. data/lib/lookout/diff/groups.rb +0 -34
  225. data/lib/lookout/diff/match.rb +0 -36
  226. data/lib/lookout/diff/operation.rb +0 -33
  227. data/lib/lookout/diff/operations.rb +0 -36
  228. data/lib/lookout/diff/operations/delete.rb +0 -9
  229. data/lib/lookout/diff/operations/equal.rb +0 -27
  230. data/lib/lookout/diff/operations/insert.rb +0 -9
  231. data/lib/lookout/diff/operations/replace.rb +0 -9
  232. data/lib/lookout/diff/range.rb +0 -91
  233. data/lib/lookout/equalities.rb +0 -13
  234. data/lib/lookout/equalities/array.rb +0 -22
  235. data/lib/lookout/equalities/boolean.rb +0 -9
  236. data/lib/lookout/equalities/hash.rb +0 -25
  237. data/lib/lookout/equalities/include.rb +0 -9
  238. data/lib/lookout/equalities/object.rb +0 -24
  239. data/lib/lookout/equalities/output.rb +0 -19
  240. data/lib/lookout/equalities/standarderror.rb +0 -32
  241. data/lib/lookout/equalities/string.rb +0 -19
  242. data/lib/lookout/equalities/warning.rb +0 -16
  243. data/lib/lookout/equality.rb +0 -36
  244. data/lib/lookout/expectation.rb +0 -69
  245. data/lib/lookout/expectations.rb +0 -49
  246. data/lib/lookout/expectations/behavior.rb +0 -20
  247. data/lib/lookout/expectations/line.rb +0 -29
  248. data/lib/lookout/expectations/state.rb +0 -31
  249. data/lib/lookout/expectations/state/warning.rb +0 -26
  250. data/lib/lookout/mock.rb +0 -20
  251. data/lib/lookout/mock/method.rb +0 -70
  252. data/lib/lookout/mock/method/arguments.rb +0 -33
  253. data/lib/lookout/mock/method/arguments/any.rb +0 -11
  254. data/lib/lookout/mock/method/arguments/anything.rb +0 -11
  255. data/lib/lookout/mock/method/arguments/list.rb +0 -15
  256. data/lib/lookout/mock/method/arguments/none.rb +0 -11
  257. data/lib/lookout/mock/method/arguments/one.rb +0 -11
  258. data/lib/lookout/mock/method/calls.rb +0 -11
  259. data/lib/lookout/mock/method/calls/class.rb +0 -21
  260. data/lib/lookout/mock/method/calls/exactly.rb +0 -28
  261. data/lib/lookout/mock/method/calls/instance.rb +0 -25
  262. data/lib/lookout/mock/method/calls/lower.rb +0 -22
  263. data/lib/lookout/mock/method/calls/upper.rb +0 -22
  264. data/lib/lookout/mock/methods.rb +0 -12
  265. data/lib/lookout/mock/object.rb +0 -12
  266. data/lib/lookout/object.rb +0 -11
  267. data/lib/lookout/output.rb +0 -21
  268. data/lib/lookout/rake/tasks.rb +0 -36
  269. data/lib/lookout/rake/tasks/gem.rb +0 -49
  270. data/lib/lookout/rake/tasks/tags.rb +0 -16
  271. data/lib/lookout/rake/tasks/test.rb +0 -46
  272. data/lib/lookout/rake/tasks/test/loader.rb +0 -22
  273. data/lib/lookout/recorder.rb +0 -45
  274. data/lib/lookout/recorder/not.rb +0 -11
  275. data/lib/lookout/recorder/tape.rb +0 -21
  276. data/lib/lookout/recorders.rb +0 -6
  277. data/lib/lookout/recorders/reception.rb +0 -47
  278. data/lib/lookout/recorders/state.rb +0 -35
  279. data/lib/lookout/result.rb +0 -13
  280. data/lib/lookout/results.rb +0 -25
  281. data/lib/lookout/results/error.rb +0 -18
  282. data/lib/lookout/results/error/exception.rb +0 -34
  283. data/lib/lookout/results/error/exception/backtrace.rb +0 -50
  284. data/lib/lookout/results/failure.rb +0 -16
  285. data/lib/lookout/results/failures.rb +0 -6
  286. data/lib/lookout/results/failures/behavior.rb +0 -5
  287. data/lib/lookout/results/failures/state.rb +0 -5
  288. data/lib/lookout/results/fulfilled.rb +0 -5
  289. data/lib/lookout/results/unsuccessful.rb +0 -31
  290. data/lib/lookout/runners.rb +0 -6
  291. data/lib/lookout/runners/console.rb +0 -49
  292. data/lib/lookout/runners/trackers.rb +0 -5
  293. data/lib/lookout/runners/trackers/failure.rb +0 -14
  294. data/lib/lookout/stub.rb +0 -18
  295. data/lib/lookout/stub/method.rb +0 -105
  296. data/lib/lookout/stub/methods.rb +0 -18
  297. data/lib/lookout/stub/object.rb +0 -11
  298. data/lib/lookout/ui.rb +0 -7
  299. data/lib/lookout/ui/console.rb +0 -19
  300. data/lib/lookout/ui/silent.rb +0 -9
  301. data/lib/lookout/version.rb +0 -5
  302. data/lib/lookout/warning.rb +0 -7
  303. data/lib/lookout/xml.rb +0 -17
  304. data/test/unit/lookout/diff/algorithms/difflib.rb +0 -56
  305. data/test/unit/lookout/diff/algorithms/difflib/position.rb +0 -92
  306. data/test/unit/lookout/diff/groups.rb +0 -102
  307. data/test/unit/lookout/diff/operations.rb +0 -22
  308. data/test/unit/lookout/diff/operations/delete.rb +0 -45
  309. data/test/unit/lookout/diff/operations/equal.rb +0 -45
  310. data/test/unit/lookout/diff/operations/insert.rb +0 -45
  311. data/test/unit/lookout/diff/operations/replace.rb +0 -45
  312. data/test/unit/lookout/diff/range.rb +0 -50
  313. data/test/unit/lookout/equality.rb +0 -113
  314. data/test/unit/lookout/expectation.rb +0 -47
  315. data/test/unit/lookout/expectations.rb +0 -36
  316. data/test/unit/lookout/expectations/behavior.rb +0 -35
  317. data/test/unit/lookout/expectations/line.rb +0 -29
  318. data/test/unit/lookout/expectations/state.rb +0 -29
  319. data/test/unit/lookout/mock/method.rb +0 -143
  320. data/test/unit/lookout/mock/method/arguments.rb +0 -57
  321. data/test/unit/lookout/mock/method/arguments/any.rb +0 -11
  322. data/test/unit/lookout/recorder.rb +0 -11
  323. data/test/unit/lookout/results/error/exception/backtrace.rb +0 -20
  324. data/test/unit/lookout/results/unsuccessful.rb +0 -9
  325. data/test/unit/lookout/runners/trackers/failure.rb +0 -30
  326. data/test/unit/lookout/stub/method.rb +0 -48
  327. data/test/unit/lookout/stub/methods.rb +0 -19
  328. data/test/unit/lookout/xml.rb +0 -55
@@ -0,0 +1,20 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Encodes objects as UTF-8-encoded Strings. This is done by calling String
4
+ # with the object as the argument and then calling #encode on the result, if
5
+ # the result responds to it. This is primarily useful for compatibility
6
+ # between Ruby 1.8 and 1.9.
7
+ class Lookout::Encode
8
+ # Encodes OBJECT as an UTF-8-encoded String.
9
+ # @param [#to_s] object
10
+ Value(:object)
11
+
12
+ # @return [String] An UTF-8-encoded String representation of the object
13
+ def call
14
+ string = String(object)
15
+ return string unless (string.respond_to?(:encode) rescue true)
16
+ string.encode('UTF-8')
17
+ end
18
+
19
+ alias to_s call
20
+ end
@@ -0,0 +1,79 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Provides non-failing access to some of {::Exception}’s methods. Used in
4
+ # subsystems where unhandled failure isn’t an option, such as {Inspect} and
5
+ # {Results::Error}. Also uses {Encode} so that all strings are ready for
6
+ # output.
7
+ class Lookout::Exception
8
+ # Provides non-failing access to EXCEPTION’s message, backtrace, and type.
9
+ # @param [::Exception] exception
10
+ Value(:exception)
11
+
12
+ # @return [String] The UTF-8-encoded exception message or the UTF-8-encoded
13
+ # exception message of any exception that was raised while trying to retrieve
14
+ # it
15
+ def message
16
+ @message ||= encode(begin
17
+ String(exception.message)
18
+ rescue => e
19
+ 'cannot retrieve error message: %s' %
20
+ encode((String(e) rescue
21
+ 'and cannot retrieve error message for error that generated that error either; giving up'))
22
+ end)
23
+ end
24
+
25
+ alias to_s message
26
+
27
+ # @return [String] A heuristically generated UTF-8-encoded exception message
28
+ # “header”, possibly containing the exception message and the exception’s
29
+ # class’ name
30
+ def header
31
+ # Chomping off a \n here isn’t 100 percent compatible with how Ruby 1.9
32
+ # does it, but it simplifies the code and also makes the output better if
33
+ # the message is a lone \n.
34
+ message = (Lookout::Encode.new(String(exception.message)).call rescue '').chomp("\n")
35
+ if RuntimeError == type and message.empty?
36
+ 'unhandled exception'
37
+ elsif message.empty?
38
+ type_name
39
+ elsif type_name.empty? or type_name.start_with? '#'
40
+ message
41
+ else
42
+ before, newline, after = message.partition("\n")
43
+ [before, ' (', type_name, ')', newline, after].join('')
44
+ end
45
+ end
46
+
47
+ # @return [Backtrace] A non-failing backtrace wrapper of the exception
48
+ # backtrace
49
+ def backtrace; @backtrace ||= Backtrace.from(exception) end
50
+
51
+ # @return [#name, #inspect] Either the exception’s class or an {Unknown}
52
+ # wrapper around the exception that was raised while trying to determine
53
+ # the class
54
+ def type; @type ||= begin exception.class; rescue => e; Unknown.new(e) end end
55
+
56
+ # @return [String] The UTF-8-encoded name of the exception’s class
57
+ def type_name
58
+ @type_name ||= begin
59
+ Lookout::Encode.new(type.name).call
60
+ rescue => e
61
+ 'cannot determine name of class of exception: %s' %
62
+ self.class.new(e)
63
+ end
64
+ end
65
+
66
+ # @return [String] The {#header} and {#backtrace} separated by a newline
67
+ def format; [header, "\n", backtrace].join('') end
68
+
69
+ private
70
+
71
+ def encode(message)
72
+ Lookout::Encode.new(message).call
73
+ rescue => e
74
+ 'cannot encode error message for output: %s%s' %
75
+ [(Lookout::Encode.new(String(e)).call rescue
76
+ 'and cannot encode error message for error that generated that error for output either; giving up'),
77
+ ('; dumping instead: %s' % [message.dump] rescue '')]
78
+ end
79
+ end
@@ -0,0 +1,65 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Provides non-failing access to an exception backtrace. The backtrace entries
4
+ # are {Encode}d for output and the backtrace may be filtered to not include
5
+ # entries from inside Lookout.
6
+ class Lookout::Exception::Backtrace
7
+ class << self
8
+ # @param [::Exception] exception
9
+ # @return [Backtrace] A backtrace wrapper of EXCEPTION’s backtrace,
10
+ # trimmed if EXCEPTION is a SystemStackError, and empty if the
11
+ # backtrace can’t be retrieved
12
+ def from(exception)
13
+ new(nil == exception ? nil : (exception.backtrace rescue nil),
14
+ SystemStackError === exception)
15
+ end
16
+ end
17
+
18
+ # Wraps BACKTRACE and optionally TRIM the backtrace to only contain a couple
19
+ # of leading and trailing entries and FILTER out entries from inside Lookout.
20
+ # @param [Array<String>] backtrace
21
+ # @param [Boolean] trim
22
+ # @param [Boolean] filter
23
+ Value(:backtrace, :trim, :filter)
24
+ def initialize(backtrace, trim, filter = ENV['LOOKOUT_DO_NOT_FILTER_BACKTRACE'].nil?)
25
+ super(if nil == backtrace
26
+ []
27
+ elsif String === backtrace or Array === backtrace
28
+ (String === backtrace ? [backtrace] : backtrace).map{ |line|
29
+ begin
30
+ Lookout::Encode.new(line).call
31
+ rescue => e
32
+ '(cannot retrieve backtrace entry: %s)' %
33
+ Lookout::Exception.new(e)
34
+ end
35
+ }
36
+ else
37
+ ['(backtrace is not an Array of String: %s)' %
38
+ Lookout::Inspect.new(backtrace, 'backtrace')]
39
+ end, trim, filter)
40
+ end
41
+
42
+ # @return The concatenation of the backtrace entries
43
+ def to_s
44
+ trimmed(filtered.map{ |location| ["\tfrom ", location].join('') }).join("\n")
45
+ end
46
+
47
+ private
48
+
49
+ def filtered; (filter and (before or outside)) or backtrace end
50
+ def before; nilify(backtrace.take_while{ |location| not reject? location }) end
51
+ def outside; nilify(backtrace.reject{ |location| reject? location }) end
52
+ def nilify(backtrace) backtrace.empty? ? nil : backtrace end
53
+ def reject?(location) location.start_with? Root end
54
+
55
+ def trimmed(locations)
56
+ return locations unless trim and locations.length > Head + Tail + 5
57
+ locations[0...Head] +
58
+ ["\t ... %d levels ..." % (locations.length - Head - Tail)] +
59
+ locations[-Tail..-1]
60
+ end
61
+
62
+ Root = File.expand_path('../../..', __FILE__)
63
+ Head = 8
64
+ Tail = 5
65
+ end
@@ -0,0 +1,25 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Wraps an exception that was raised while trying to determine an exception’s
4
+ # class to make it behave like an exception class.
5
+ class Lookout::Exception::Unknown
6
+ # Wraps the EXCEPTION that was raised while trying to determine an
7
+ # exception’s class.
8
+ # @param [::Exception] exception
9
+ Value(:exception)
10
+
11
+ # @raise [RuntimeError] Containing a message explaining that the exception’s
12
+ # class couldn’t be determined and why that is so
13
+ def name; raise message end
14
+
15
+ # @return The message explaining that the exception’s class couldn’t be
16
+ # determined and why that is so
17
+ def inspect; '(%s)' % message end
18
+
19
+ private
20
+
21
+ def message
22
+ @message ||= 'cannot determine class of exception: %s' %
23
+ Lookout::Exception.new(exception)
24
+ end
25
+ end
@@ -0,0 +1,32 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Function-like namespace for type-specific expect blocks. Represents the
4
+ # “expect” keyword in expectation files. Used by {Expectations::Context}.
5
+ #
6
+ # {Object} is the base class for all classes defined under this namespace, so
7
+ # look to it for guidance.
8
+ module Lookout::Expect
9
+ class << self
10
+ # Wraps the creation of an {Object} or one of its sub-classes by
11
+ # dispatching #to_lookout_expected on the _expected_ value and then calling
12
+ # #expect on the result, passing the expanded path to the FILE
13
+ # containing the expectation, the LINE in _file_ on which the expectation
14
+ # is defined, and the BLOCK to evaluate for the actual result.
15
+ #
16
+ # If #to_lookout_expected raises NoMethodError, the result will be an
17
+ # {Object}, so that at least something gets set up.
18
+ #
19
+ # @param [::Object] expected
20
+ # @param [::String] file
21
+ # @param [::Integer] line
22
+ # @return [Object] The result of calling
23
+ # _expected_#to_lookout_expected#expect(FILE, LINE, &BLOCK)
24
+ def expect(expected, file, line, &block)
25
+ begin
26
+ expected.to_lookout_expected
27
+ rescue ::NoMethodError
28
+ ::Lookout::Expected::Object.new(expected)
29
+ end.expect(file, line, &block)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,6 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Namespace for expect blocks for types under the {Expected::Classes}
4
+ # namespace.
5
+ module Lookout::Expect::Classes
6
+ end
@@ -0,0 +1,27 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Expect block of {Expected::Classes::Exception}s.
4
+ class Lookout::Expect::Classes::Exception < Lookout::Expect::Object
5
+ # Evaluates the expect block and checks the first raised Exception’s class
6
+ # against the expected Exception class. If no exception is raised, the
7
+ # actual result is checked against the expected value.
8
+ # @return [Results::Error] If the raised exception’s class isn’t equal to or
9
+ # a descendant of the expected result class
10
+ # @return [Results::Success] If the raised exception’s class is equal to or a
11
+ # descendant of the expected result class
12
+ # @return (see Object#check)
13
+ def call
14
+ begin
15
+ result = evaluate_block
16
+ rescue expected.expected
17
+ return Lookout::Results::Success.new(file, line)
18
+ rescue Exception => e
19
+ exception = Lookout::Exception.new(e)
20
+ return Lookout::Results::Error.
21
+ new(file, line, expected.difference(exception.type).message, exception)
22
+ end
23
+ check(result)
24
+ rescue Exception => e
25
+ Lookout::Results::Error.new(file, line, nil, Lookout::Exception.new(e))
26
+ end
27
+ end
@@ -0,0 +1,30 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Expect block of {Expected::Exception}s.
4
+ class Lookout::Expect::Exception < Lookout::Expect::Object
5
+ # Evaluates the expect block and checks the first raised Exception against
6
+ # the expected Exception. If no exception is raised, the actual result is
7
+ # checked against the expected value.
8
+ # @return [Results::Error] If the raised exception isn’t of the same class as
9
+ # that of the expected result
10
+ # @return (see Object#check)
11
+ def call
12
+ begin
13
+ result = evaluate_block
14
+ rescue Exception => actual
15
+ exception = Lookout::Exception.new(actual)
16
+ expected_class = expected.expected.class rescue Exception
17
+ actual_class = exception.type
18
+ return ((expected_class == actual_class) rescue false) ?
19
+ check(actual) :
20
+ Lookout::Results::Error.
21
+ new(file,
22
+ line,
23
+ expected_class.to_lookout_expected.difference(actual_class).message,
24
+ exception)
25
+ end
26
+ check(result)
27
+ rescue Exception => e
28
+ Lookout::Results::Error.new(file, line, nil, Lookout::Exception.new(e))
29
+ end
30
+ end
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Expect block of {Expected::Object}s. This is the base expect
4
+ # block class and may be subclassed if some special equality checking needs to
5
+ # be performed, if the execution environment needs to be set up in some way
6
+ # before the expect block is executed, or if the expect block should receive
7
+ # other arguments than the default (being the expected value).
8
+ class Lookout::Expect::Object
9
+ # Sets up the expect block on LINE in FILE (the expanded path) to expect the
10
+ # value that EXPECTED wraps, and using the block’s result as the actual
11
+ # result to pass to {Expected::Object#difference} when {#call}ed.
12
+ # @param [Expected::Object] expected The expected value wrapper
13
+ # @param [::String] file The expanded path to the file containing the expectation
14
+ # @param [::Integer] line The line in {#file} on which the expectation is defined
15
+ # @yieldparam [::Object] expected
16
+ # @yieldreturn [::Object]
17
+ Value(:expected, :file, :line, :'&block', :comparable => [:file, :line])
18
+ include Comparable
19
+
20
+ # Evaluates the expect block and checks for differences between its result
21
+ # and the expected value.
22
+ # @return [Results::Error] If an Exception is raised
23
+ # @return (see #check)
24
+ def call
25
+ check(evaluate_block)
26
+ rescue Exception => e
27
+ Lookout::Results::Error.new(file, line, nil, Lookout::Exception.new(e))
28
+ end
29
+
30
+ private
31
+
32
+ # @param [::Object, …] args
33
+ # @return [::Object] The actual result of evaluating the expect block in the
34
+ # proper context, passing ARGS, which defaults to the expected value, to it
35
+ # @see Context
36
+ def evaluate_block(*args)
37
+ (args.empty? ?
38
+ Context.new(expected.expected, &block) :
39
+ Context.new(*args, &block)).evaluate
40
+ end
41
+
42
+ # Checks for differences between the ACTUAL result of evaluating the expect
43
+ # block and the expected value.
44
+ # @param [::Object] actual
45
+ # @return [Results::Success] If there are no differences between the actual
46
+ # result and the expected value
47
+ # @return [Results::Failure] If there are differences between the actual
48
+ # result and the expected value
49
+ def check(actual)
50
+ (difference = expected.difference(actual)) ?
51
+ Lookout::Results::Failure.new(file, line, difference) :
52
+ Lookout::Results::Success.new(file, line)
53
+ end
54
+ end
@@ -0,0 +1,149 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Context in which expect blocks are evaluated. Plug-ins may add private
4
+ # methods to this class to make them available to expect blocks.
5
+ class Lookout::Expect::Object::Context
6
+ # Evaluates BLOCK inside this context, passing ARGS to it, when {#evaluate}d.
7
+ # @param [::Object, …] args
8
+ def initialize(*args, &block)
9
+ @args, @block = args, block
10
+ end
11
+
12
+ # @return [::Object, nil] The result of evaluating the block or nil if
13
+ # there’s no block
14
+ def evaluate
15
+ instance_exec(*@args, &@block) if @block
16
+ end
17
+
18
+ private
19
+
20
+ # @overload stub(object, methods)
21
+ # Sets up stubs on OBJECT for each method name key in METHODS to its value
22
+ # definition during the execution of the given block. If the value of the
23
+ # key is a Proc it’ll be used as the method definition. Otherwise, the
24
+ # method definition will be set up to return the value.
25
+ # @param [::Object] object
26
+ # @param [Hash<Symbol,Object>] methods
27
+ # @yieldparam [::Object] object
28
+ # @return [::Object] The result of the block
29
+ # @overload stub(methods = {})
30
+ # @param [Hash<Symbol,::Object>] methods
31
+ # @return [Lookout::Stub::Object] A stub object set up with METHODS
32
+ def stub(object = {}, methods = nil)
33
+ return Lookout::Stub.new(object) unless methods
34
+ recursion = proc{ |ms|
35
+ return yield(object) if ms.empty?
36
+ name, value = ms[0].first.to_sym, ms[0].last
37
+ (Kernel == object ? object : (class << object; self; end)).module_exec{
38
+ visibility, own =
39
+ private_method_defined?(name) ? [:private, private_instance_methods(false)] :
40
+ protected_method_defined?(name) ? [:protected, protected_instance_methods(false)] :
41
+ public_method_defined?(name) ? [nil, instance_methods(false)] : [nil, []]
42
+ unbound = own.include?(RUBY_VERSION < '1.9' ? name.to_s : name) ?
43
+ instance_method(name) : nil
44
+ Lookout::Stub.define self, name, value
45
+ send visibility, name if visibility
46
+ begin
47
+ recursion.call(ms[1..-1])
48
+ ensure
49
+ remove_method name
50
+ if unbound
51
+ define_method name, unbound
52
+ send visibility, name if visibility
53
+ end
54
+ end
55
+ }
56
+ }
57
+ recursion.call(methods.to_a)
58
+ end
59
+
60
+ # Sets GLOBAL to VALUE during the execution of the given block, yielding the
61
+ # OVERRIDDEN value.
62
+ # @param [Symbol] global
63
+ # @param [::Object] value
64
+ # @yieldparam [::Object] overridden
65
+ # @return [::Object] The result of the block
66
+ # @raise [ArgumentError] If GLOBAL isn’t the name of a global variable
67
+ def with_global(global, value)
68
+ symbol = global.to_sym
69
+ raise ArgumentError,
70
+ 'no such global variable: %s' % global unless
71
+ global_variables.include?(RUBY_VERSION < '1.9' ? symbol.to_s : symbol)
72
+ saved = eval(symbol.to_s)
73
+ eval '%s = value' % symbol
74
+ begin
75
+ yield saved
76
+ ensure
77
+ eval '%s = saved' % symbol
78
+ end
79
+ end
80
+
81
+ # Sets `$VERBOSE` to VERBOSE during the execution of the given block.
82
+ # @param [true, false, nil] verbose
83
+ # @yield
84
+ # @return [::Object] The result of the block
85
+ def with_verbose(verbose = true)
86
+ with_global :$VERBOSE, verbose do
87
+ yield
88
+ end
89
+ end
90
+
91
+ # Sets the constant identified by (the possibly qualified) NAME to VALUE
92
+ # during the execution of the given block. If NAME is qualified, any
93
+ # intermediate modules that aren’t defined will be set to new {Module}s.
94
+ # These modules will be removed once the block returns.
95
+ # @param [String] name
96
+ # @param [::Object] value
97
+ # @yield
98
+ # @return [::Object] The result of the block
99
+ def with_const(name, value)
100
+ missing = nil
101
+ parts = name.split('::', -1)
102
+ parts = parts[1..-1] if parts.first.empty?
103
+ raise NameError, 'illegal constant name: %s' % name if
104
+ parts.empty? or parts.first.empty? or parts.last.empty?
105
+ begin
106
+ parent = parts[0..-2].reduce(Object){ |o, e|
107
+ begin
108
+ if RUBY_VERSION < '1.9'
109
+ # This is racy, but unavoidable.
110
+ raise NameError unless o.const_defined? e
111
+ o.const_get(e)
112
+ else
113
+ o.const_get(e, false)
114
+ end
115
+ rescue NameError
116
+ missing = [o, e] unless missing
117
+ o.const_set(e, Module.new)
118
+ end
119
+ }
120
+ saved = parent.const_get(parts.last) unless missing
121
+ parent.const_set(parts.last, value)
122
+ begin
123
+ yield
124
+ ensure
125
+ parent.const_set(parts.last, saved) unless missing
126
+ end
127
+ ensure
128
+ missing.first.__send__(:remove_const, missing.last) if missing
129
+ end
130
+ end
131
+
132
+ # Sets environment variables defined in ENV during the execution of the given
133
+ # block.
134
+ # @param [Hash] env
135
+ # @yield
136
+ # @return [::Object] The result of the block
137
+ def with_env(env = {})
138
+ saved = ENV.select{ |key, _| env.include? key }
139
+ saved = Hash[*saved.flatten] if RUBY_VERSION < '1.9'
140
+ missing = env.reject{ |key, _| ENV.include? key }
141
+ begin
142
+ ENV.update env
143
+ yield
144
+ ensure
145
+ ENV.update saved
146
+ ENV.delete_if{ |key, _| missing.include? key }
147
+ end
148
+ end
149
+ end