merb_merchant 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (273) hide show
  1. data/CHANGELOG +421 -0
  2. data/CONTRIBUTERS +90 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README +131 -0
  5. data/Rakefile +129 -0
  6. data/init.rb +3 -0
  7. data/lib/certs/cacert.pem +7815 -0
  8. data/lib/core_ext/delegating_attributes.rb +76 -0
  9. data/lib/core_ext/hash_ext.rb +35 -0
  10. data/lib/core_ext/inheritable_attributes.rb +145 -0
  11. data/lib/core_ext/time_dsl.rb +59 -0
  12. data/lib/merb_merchant.rb +96 -0
  13. data/lib/merb_merchant/billing/avs_result.rb +95 -0
  14. data/lib/merb_merchant/billing/base.rb +71 -0
  15. data/lib/merb_merchant/billing/check.rb +68 -0
  16. data/lib/merb_merchant/billing/credit_card.rb +157 -0
  17. data/lib/merb_merchant/billing/credit_card_formatting.rb +21 -0
  18. data/lib/merb_merchant/billing/credit_card_methods.rb +125 -0
  19. data/lib/merb_merchant/billing/cvv_result.rb +38 -0
  20. data/lib/merb_merchant/billing/expiry_date.rb +28 -0
  21. data/lib/merb_merchant/billing/gateway.rb +162 -0
  22. data/lib/merb_merchant/billing/gateways.rb +3 -0
  23. data/lib/merb_merchant/billing/gateways/authorize_net.rb +646 -0
  24. data/lib/merb_merchant/billing/gateways/authorize_net_cim.rb +702 -0
  25. data/lib/merb_merchant/billing/gateways/beanstream.rb +102 -0
  26. data/lib/merb_merchant/billing/gateways/beanstream/beanstream_core.rb +233 -0
  27. data/lib/merb_merchant/billing/gateways/beanstream_interac.rb +54 -0
  28. data/lib/merb_merchant/billing/gateways/bogus.rb +98 -0
  29. data/lib/merb_merchant/billing/gateways/braintree.rb +222 -0
  30. data/lib/merb_merchant/billing/gateways/card_stream.rb +229 -0
  31. data/lib/merb_merchant/billing/gateways/cyber_source.rb +406 -0
  32. data/lib/merb_merchant/billing/gateways/data_cash.rb +595 -0
  33. data/lib/merb_merchant/billing/gateways/efsnet.rb +229 -0
  34. data/lib/merb_merchant/billing/gateways/eway.rb +272 -0
  35. data/lib/merb_merchant/billing/gateways/exact.rb +222 -0
  36. data/lib/merb_merchant/billing/gateways/linkpoint.rb +396 -0
  37. data/lib/merb_merchant/billing/gateways/modern_payments.rb +36 -0
  38. data/lib/merb_merchant/billing/gateways/modern_payments_cim.rb +214 -0
  39. data/lib/merb_merchant/billing/gateways/moneris.rb +205 -0
  40. data/lib/merb_merchant/billing/gateways/net_registry.rb +189 -0
  41. data/lib/merb_merchant/billing/gateways/netbilling.rb +168 -0
  42. data/lib/merb_merchant/billing/gateways/pay_junction.rb +392 -0
  43. data/lib/merb_merchant/billing/gateways/pay_secure.rb +120 -0
  44. data/lib/merb_merchant/billing/gateways/payflow.rb +236 -0
  45. data/lib/merb_merchant/billing/gateways/payflow/payflow_common_api.rb +207 -0
  46. data/lib/merb_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  47. data/lib/merb_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  48. data/lib/merb_merchant/billing/gateways/payflow_express.rb +138 -0
  49. data/lib/merb_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  50. data/lib/merb_merchant/billing/gateways/payflow_uk.rb +21 -0
  51. data/lib/merb_merchant/billing/gateways/payment_express.rb +241 -0
  52. data/lib/merb_merchant/billing/gateways/paypal.rb +108 -0
  53. data/lib/merb_merchant/billing/gateways/paypal/paypal_common_api.rb +325 -0
  54. data/lib/merb_merchant/billing/gateways/paypal/paypal_express_response.rb +38 -0
  55. data/lib/merb_merchant/billing/gateways/paypal_ca.rb +13 -0
  56. data/lib/merb_merchant/billing/gateways/paypal_express.rb +130 -0
  57. data/lib/merb_merchant/billing/gateways/paypal_express_common.rb +20 -0
  58. data/lib/merb_merchant/billing/gateways/plugnpay.rb +292 -0
  59. data/lib/merb_merchant/billing/gateways/protx.rb +284 -0
  60. data/lib/merb_merchant/billing/gateways/psigate.rb +214 -0
  61. data/lib/merb_merchant/billing/gateways/psl_card.rb +306 -0
  62. data/lib/merb_merchant/billing/gateways/quickpay.rb +213 -0
  63. data/lib/merb_merchant/billing/gateways/realex.rb +200 -0
  64. data/lib/merb_merchant/billing/gateways/sage.rb +146 -0
  65. data/lib/merb_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
  66. data/lib/merb_merchant/billing/gateways/sage/sage_core.rb +110 -0
  67. data/lib/merb_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  68. data/lib/merb_merchant/billing/gateways/secure_pay.rb +31 -0
  69. data/lib/merb_merchant/billing/gateways/secure_pay_au.rb +157 -0
  70. data/lib/merb_merchant/billing/gateways/secure_pay_tech.rb +113 -0
  71. data/lib/merb_merchant/billing/gateways/skip_jack.rb +439 -0
  72. data/lib/merb_merchant/billing/gateways/trans_first.rb +127 -0
  73. data/lib/merb_merchant/billing/gateways/trust_commerce.rb +418 -0
  74. data/lib/merb_merchant/billing/gateways/usa_epay.rb +194 -0
  75. data/lib/merb_merchant/billing/gateways/verifi.rb +228 -0
  76. data/lib/merb_merchant/billing/gateways/viaklix.rb +165 -0
  77. data/lib/merb_merchant/billing/gateways/wirecard.rb +305 -0
  78. data/lib/merb_merchant/billing/integrations.rb +22 -0
  79. data/lib/merb_merchant/billing/integrations/action_view_helper.rb +79 -0
  80. data/lib/merb_merchant/billing/integrations/bogus.rb +29 -0
  81. data/lib/merb_merchant/billing/integrations/bogus/helper.rb +17 -0
  82. data/lib/merb_merchant/billing/integrations/bogus/notification.rb +11 -0
  83. data/lib/merb_merchant/billing/integrations/bogus/return.rb +10 -0
  84. data/lib/merb_merchant/billing/integrations/chronopay.rb +29 -0
  85. data/lib/merb_merchant/billing/integrations/chronopay/helper.rb +81 -0
  86. data/lib/merb_merchant/billing/integrations/chronopay/notification.rb +156 -0
  87. data/lib/merb_merchant/billing/integrations/chronopay/return.rb +10 -0
  88. data/lib/merb_merchant/billing/integrations/gestpay.rb +32 -0
  89. data/lib/merb_merchant/billing/integrations/gestpay/common.rb +42 -0
  90. data/lib/merb_merchant/billing/integrations/gestpay/helper.rb +70 -0
  91. data/lib/merb_merchant/billing/integrations/gestpay/notification.rb +83 -0
  92. data/lib/merb_merchant/billing/integrations/gestpay/return.rb +10 -0
  93. data/lib/merb_merchant/billing/integrations/helper.rb +93 -0
  94. data/lib/merb_merchant/billing/integrations/hi_trust.rb +26 -0
  95. data/lib/merb_merchant/billing/integrations/hi_trust/helper.rb +58 -0
  96. data/lib/merb_merchant/billing/integrations/hi_trust/notification.rb +59 -0
  97. data/lib/merb_merchant/billing/integrations/hi_trust/return.rb +67 -0
  98. data/lib/merb_merchant/billing/integrations/nochex.rb +101 -0
  99. data/lib/merb_merchant/billing/integrations/nochex/helper.rb +68 -0
  100. data/lib/merb_merchant/billing/integrations/nochex/notification.rb +94 -0
  101. data/lib/merb_merchant/billing/integrations/nochex/return.rb +10 -0
  102. data/lib/merb_merchant/billing/integrations/notification.rb +62 -0
  103. data/lib/merb_merchant/billing/integrations/paypal.rb +54 -0
  104. data/lib/merb_merchant/billing/integrations/paypal/helper.rb +118 -0
  105. data/lib/merb_merchant/billing/integrations/paypal/notification.rb +154 -0
  106. data/lib/merb_merchant/billing/integrations/paypal/return.rb +10 -0
  107. data/lib/merb_merchant/billing/integrations/quickpay.rb +25 -0
  108. data/lib/merb_merchant/billing/integrations/quickpay/helper.rb +72 -0
  109. data/lib/merb_merchant/billing/integrations/quickpay/notification.rb +74 -0
  110. data/lib/merb_merchant/billing/integrations/return.rb +35 -0
  111. data/lib/merb_merchant/billing/integrations/two_checkout.rb +30 -0
  112. data/lib/merb_merchant/billing/integrations/two_checkout/helper.rb +59 -0
  113. data/lib/merb_merchant/billing/integrations/two_checkout/notification.rb +114 -0
  114. data/lib/merb_merchant/billing/integrations/two_checkout/return.rb +17 -0
  115. data/lib/merb_merchant/billing/response.rb +32 -0
  116. data/lib/merb_merchant/lib/country.rb +298 -0
  117. data/lib/merb_merchant/lib/error.rb +4 -0
  118. data/lib/merb_merchant/lib/inflector.rb +69 -0
  119. data/lib/merb_merchant/lib/post_data.rb +22 -0
  120. data/lib/merb_merchant/lib/posts_data.rb +109 -0
  121. data/lib/merb_merchant/lib/requires_parameters.rb +16 -0
  122. data/lib/merb_merchant/lib/utils.rb +18 -0
  123. data/lib/merb_merchant/lib/validateable.rb +76 -0
  124. data/lib/support/gateway_support.rb +57 -0
  125. data/lib/tasks/cia.rb +90 -0
  126. data/script/destroy +14 -0
  127. data/script/generate +14 -0
  128. data/test/extra/binding_of_caller.rb +80 -0
  129. data/test/extra/breakpoint.rb +547 -0
  130. data/test/fixtures.yml +317 -0
  131. data/test/remote/gateways/remote_authorize_net_cim_test.rb +459 -0
  132. data/test/remote/gateways/remote_authorize_net_test.rb +145 -0
  133. data/test/remote/gateways/remote_beanstream_interac_test.rb +53 -0
  134. data/test/remote/gateways/remote_beanstream_test.rb +150 -0
  135. data/test/remote/gateways/remote_braintree_test.rb +154 -0
  136. data/test/remote/gateways/remote_card_stream_test.rb +148 -0
  137. data/test/remote/gateways/remote_cyber_source_test.rb +144 -0
  138. data/test/remote/gateways/remote_data_cash_test.rb +357 -0
  139. data/test/remote/gateways/remote_efsnet_test.rb +81 -0
  140. data/test/remote/gateways/remote_eway_test.rb +74 -0
  141. data/test/remote/gateways/remote_exact_test.rb +60 -0
  142. data/test/remote/gateways/remote_linkpoint_test.rb +112 -0
  143. data/test/remote/gateways/remote_modern_payments_cim_test.rb +58 -0
  144. data/test/remote/gateways/remote_modern_payments_test.rb +43 -0
  145. data/test/remote/gateways/remote_moneris_test.rb +82 -0
  146. data/test/remote/gateways/remote_net_registry_test.rb +85 -0
  147. data/test/remote/gateways/remote_netbilling_test.rb +70 -0
  148. data/test/remote/gateways/remote_pay_junction_test.rb +143 -0
  149. data/test/remote/gateways/remote_pay_secure_test.rb +39 -0
  150. data/test/remote/gateways/remote_payflow_express_test.rb +50 -0
  151. data/test/remote/gateways/remote_payflow_test.rb +237 -0
  152. data/test/remote/gateways/remote_payflow_uk_test.rb +173 -0
  153. data/test/remote/gateways/remote_payment_express_test.rb +126 -0
  154. data/test/remote/gateways/remote_paypal_express_test.rb +49 -0
  155. data/test/remote/gateways/remote_paypal_test.rb +167 -0
  156. data/test/remote/gateways/remote_plugnpay_test.rb +72 -0
  157. data/test/remote/gateways/remote_protx_test.rb +184 -0
  158. data/test/remote/gateways/remote_psigate_test.rb +50 -0
  159. data/test/remote/gateways/remote_psl_card_test.rb +125 -0
  160. data/test/remote/gateways/remote_quickpay_test.rb +190 -0
  161. data/test/remote/gateways/remote_realex_test.rb +224 -0
  162. data/test/remote/gateways/remote_sage_bankcard_test.rb +109 -0
  163. data/test/remote/gateways/remote_sage_test.rb +87 -0
  164. data/test/remote/gateways/remote_sage_virtual_check_test.rb +62 -0
  165. data/test/remote/gateways/remote_secure_pay_au_test.rb +40 -0
  166. data/test/remote/gateways/remote_secure_pay_tech_test.rb +37 -0
  167. data/test/remote/gateways/remote_secure_pay_test.rb +28 -0
  168. data/test/remote/gateways/remote_skipjack_test.rb +105 -0
  169. data/test/remote/gateways/remote_trans_first_test.rb +34 -0
  170. data/test/remote/gateways/remote_trust_commerce_test.rb +152 -0
  171. data/test/remote/gateways/remote_usa_epay_test.rb +46 -0
  172. data/test/remote/gateways/remote_verifi_test.rb +107 -0
  173. data/test/remote/gateways/remote_viaklix_test.rb +43 -0
  174. data/test/remote/gateways/remote_wirecard_test.rb +77 -0
  175. data/test/remote/integrations/remote_gestpay_integration_test.rb +37 -0
  176. data/test/remote/integrations/remote_paypal_integration_test.rb +26 -0
  177. data/test/test_helper.rb +208 -0
  178. data/test/unit/avs_result_test.rb +59 -0
  179. data/test/unit/base_test.rb +55 -0
  180. data/test/unit/check_test.rb +88 -0
  181. data/test/unit/country_code_test.rb +33 -0
  182. data/test/unit/country_test.rb +64 -0
  183. data/test/unit/credit_card_formatting_test.rb +19 -0
  184. data/test/unit/credit_card_methods_test.rb +170 -0
  185. data/test/unit/credit_card_test.rb +311 -0
  186. data/test/unit/cvv_result_test.rb +33 -0
  187. data/test/unit/expiry_date_test.rb +21 -0
  188. data/test/unit/gateways/authorize_net_cim_test.rb +638 -0
  189. data/test/unit/gateways/authorize_net_test.rb +290 -0
  190. data/test/unit/gateways/beanstream_interac_test.rb +51 -0
  191. data/test/unit/gateways/beanstream_test.rb +108 -0
  192. data/test/unit/gateways/bogus_test.rb +46 -0
  193. data/test/unit/gateways/braintree_test.rb +116 -0
  194. data/test/unit/gateways/card_stream_test.rb +91 -0
  195. data/test/unit/gateways/cyber_source_test.rb +188 -0
  196. data/test/unit/gateways/data_cash_test.rb +132 -0
  197. data/test/unit/gateways/efsnet_test.rb +124 -0
  198. data/test/unit/gateways/eway_test.rb +118 -0
  199. data/test/unit/gateways/exact_test.rb +156 -0
  200. data/test/unit/gateways/gateway_test.rb +48 -0
  201. data/test/unit/gateways/linkpoint_test.rb +167 -0
  202. data/test/unit/gateways/modern_payments_cim_test.rb +171 -0
  203. data/test/unit/gateways/moneris_test.rb +158 -0
  204. data/test/unit/gateways/net_registry_test.rb +416 -0
  205. data/test/unit/gateways/netbilling_test.rb +54 -0
  206. data/test/unit/gateways/pay_junction_test.rb +123 -0
  207. data/test/unit/gateways/pay_secure_test.rb +71 -0
  208. data/test/unit/gateways/payflow_express_test.rb +173 -0
  209. data/test/unit/gateways/payflow_express_uk_test.rb +14 -0
  210. data/test/unit/gateways/payflow_test.rb +305 -0
  211. data/test/unit/gateways/payflow_uk_test.rb +30 -0
  212. data/test/unit/gateways/payment_express_test.rb +195 -0
  213. data/test/unit/gateways/paypal_express_test.rb +382 -0
  214. data/test/unit/gateways/paypal_test.rb +520 -0
  215. data/test/unit/gateways/plugnpay_test.rb +86 -0
  216. data/test/unit/gateways/protx_test.rb +122 -0
  217. data/test/unit/gateways/psigate_test.rb +169 -0
  218. data/test/unit/gateways/psl_card_test.rb +64 -0
  219. data/test/unit/gateways/quickpay_test.rb +112 -0
  220. data/test/unit/gateways/realex_test.rb +151 -0
  221. data/test/unit/gateways/sage_bankcard_test.rb +162 -0
  222. data/test/unit/gateways/sage_virtual_check_test.rb +71 -0
  223. data/test/unit/gateways/secure_pay_au_test.rb +207 -0
  224. data/test/unit/gateways/secure_pay_tech_test.rb +44 -0
  225. data/test/unit/gateways/secure_pay_test.rb +87 -0
  226. data/test/unit/gateways/skip_jack_test.rb +133 -0
  227. data/test/unit/gateways/trans_first_test.rb +112 -0
  228. data/test/unit/gateways/trust_commerce_test.rb +90 -0
  229. data/test/unit/gateways/usa_epay_test.rb +128 -0
  230. data/test/unit/gateways/verifi_test.rb +96 -0
  231. data/test/unit/gateways/viaklix_test.rb +78 -0
  232. data/test/unit/gateways/wirecard_test.rb +232 -0
  233. data/test/unit/generators/test_gateway_generator.rb +46 -0
  234. data/test/unit/generators/test_generator_helper.rb +20 -0
  235. data/test/unit/generators/test_integration_generator.rb +53 -0
  236. data/test/unit/integrations/action_view_helper_test.rb +50 -0
  237. data/test/unit/integrations/bogus_module_test.rb +20 -0
  238. data/test/unit/integrations/chronopay_module_test.rb +13 -0
  239. data/test/unit/integrations/gestpay_module_test.rb +14 -0
  240. data/test/unit/integrations/helpers/bogus_helper_test.rb +28 -0
  241. data/test/unit/integrations/helpers/chronopay_helper_test.rb +67 -0
  242. data/test/unit/integrations/helpers/gestpay_helper_test.rb +100 -0
  243. data/test/unit/integrations/helpers/hi_trust_helper_test.rb +16 -0
  244. data/test/unit/integrations/helpers/nochex_helper_test.rb +53 -0
  245. data/test/unit/integrations/helpers/paypal_helper_test.rb +162 -0
  246. data/test/unit/integrations/helpers/quickpay_helper_test.rb +40 -0
  247. data/test/unit/integrations/helpers/two_checkout_helper_test.rb +92 -0
  248. data/test/unit/integrations/hi_trust_module_test.rb +13 -0
  249. data/test/unit/integrations/nochex_module_test.rb +13 -0
  250. data/test/unit/integrations/notifications/chronopay_notification_test.rb +66 -0
  251. data/test/unit/integrations/notifications/gestpay_notification_test.rb +60 -0
  252. data/test/unit/integrations/notifications/hi_trust_notification_test.rb +59 -0
  253. data/test/unit/integrations/notifications/nochex_notification_test.rb +51 -0
  254. data/test/unit/integrations/notifications/notification_test.rb +54 -0
  255. data/test/unit/integrations/notifications/paypal_notification_test.rb +85 -0
  256. data/test/unit/integrations/notifications/quickpay_notification_test.rb +69 -0
  257. data/test/unit/integrations/notifications/two_checkout_notification_test.rb +55 -0
  258. data/test/unit/integrations/paypal_module_test.rb +28 -0
  259. data/test/unit/integrations/quickpay_module_test.rb +9 -0
  260. data/test/unit/integrations/returns/chronopay_return_test.rb +11 -0
  261. data/test/unit/integrations/returns/gestpay_return_test.rb +10 -0
  262. data/test/unit/integrations/returns/hi_trust_return_test.rb +24 -0
  263. data/test/unit/integrations/returns/nochex_return_test.rb +10 -0
  264. data/test/unit/integrations/returns/paypal_return_test.rb +10 -0
  265. data/test/unit/integrations/returns/return_test.rb +11 -0
  266. data/test/unit/integrations/returns/two_checkout_return_test.rb +24 -0
  267. data/test/unit/integrations/two_checkout_module_test.rb +13 -0
  268. data/test/unit/post_data_test.rb +55 -0
  269. data/test/unit/posts_data_test.rb +100 -0
  270. data/test/unit/response_test.rb +28 -0
  271. data/test/unit/utils_test.rb +7 -0
  272. data/test/unit/validateable_test.rb +60 -0
  273. metadata +379 -0
@@ -0,0 +1,16 @@
1
+ module MerbMerchant #:nodoc:
2
+ module RequiresParameters #:nodoc:
3
+ def requires!(hash, *params)
4
+ params.each do |param|
5
+ if param.is_a?(Array)
6
+ raise ArgumentError.new("Missing required parameter: #{param.first}") unless hash.has_key?(param.first)
7
+
8
+ valid_options = param[1..-1]
9
+ raise ArgumentError.new("Parameter: #{param.first} must be one of #{valid_options.to_sentence(:connector => 'or')}") unless valid_options.include?(hash[param.first])
10
+ else
11
+ raise ArgumentError.new("Missing required parameter: #{param}") unless hash.has_key?(param)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ require 'digest/md5'
2
+
3
+ module MerbMerchant #:nodoc:
4
+ module Utils #:nodoc:
5
+ def generate_unique_id
6
+ md5 = Digest::MD5.new
7
+ now = Time.now
8
+ md5 << now.to_s
9
+ md5 << String(now.usec)
10
+ md5 << String(rand(0))
11
+ md5 << String($$)
12
+ md5 << self.class.name
13
+ md5.hexdigest
14
+ end
15
+
16
+ module_function :generate_unique_id
17
+ end
18
+ end
@@ -0,0 +1,76 @@
1
+ module MerbMerchant #:nodoc:
2
+ module Validateable #:nodoc:
3
+ def valid?
4
+ errors.clear
5
+
6
+ before_validate if respond_to?(:before_validate, true)
7
+ validate if respond_to?(:validate, true)
8
+
9
+ errors.empty?
10
+ end
11
+
12
+ def initialize(attributes = {})
13
+ self.attributes = attributes
14
+ end
15
+
16
+ def errors
17
+ @errors ||= Errors.new(self)
18
+ end
19
+
20
+ private
21
+
22
+ def attributes=(attributes)
23
+ unless attributes.nil?
24
+ for key, value in attributes
25
+ send("#{key}=", value )
26
+ end
27
+ end
28
+ end
29
+
30
+ # This hash keeps the errors of the object
31
+ class Errors < Mash
32
+
33
+ def initialize(base)
34
+ @base = base
35
+ end
36
+
37
+ def count
38
+ size
39
+ end
40
+
41
+ # returns a specific fields error message.
42
+ # if more than one error is available we will only return the first. If no error is available
43
+ # we return an empty string
44
+ def on(field)
45
+ self[field].to_a.first
46
+ end
47
+
48
+ def add(field, error)
49
+ self[field] ||= []
50
+ self[field] << error
51
+ end
52
+
53
+ def add_to_base(error)
54
+ add(:base, error)
55
+ end
56
+
57
+ def each_full
58
+ full_messages.each { |msg| yield msg }
59
+ end
60
+
61
+ def full_messages
62
+ result = []
63
+
64
+ self.each do |key, messages|
65
+ if key == 'base'
66
+ result << "#{messages.first}"
67
+ else
68
+ result << "#{MerbMerchant::Inflector.humanize(key.to_s)} #{messages.first}"
69
+ end
70
+ end
71
+
72
+ result
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ require 'lib/merb_merchant'
3
+
4
+
5
+ class GatewaySupport #:nodoc:
6
+ ACTIONS = [:purchase, :authorize, :capture, :void, :credit, :recurring]
7
+
8
+ include MerbMerchant::Billing
9
+
10
+ attr_reader :gateways
11
+
12
+ def initialize
13
+ @gateways = Gateway.implementations.sort_by(&:name)
14
+ @gateways.delete(MerbMerchant::Billing::BogusGateway)
15
+ end
16
+
17
+ def each_gateway
18
+ @gateways.each{|g| yield g }
19
+ end
20
+
21
+ def features
22
+ width = 15
23
+
24
+ print "Name".center(width + 20)
25
+ ACTIONS.each{|f| print "#{f.to_s.capitalize.center(width)}" }
26
+ puts
27
+
28
+ each_gateway do |g|
29
+ print "#{g.display_name.ljust(width + 20)}"
30
+ ACTIONS.each do |f|
31
+ print "#{(g.instance_methods.include?(f.to_s) ? "Y" : "N").center(width)}"
32
+ end
33
+ puts
34
+ end
35
+ end
36
+
37
+ def to_rdoc
38
+ each_gateway do |g|
39
+ puts "* {#{g.display_name}}[#{g.homepage_url}] - #{g.supported_countries.join(', ')}"
40
+ end
41
+ end
42
+
43
+ def to_textile
44
+ each_gateway do |g|
45
+ puts %/ * "#{g.display_name}":#{g.homepage_url} [#{g.supported_countries.join(', ')}]/
46
+ end
47
+ end
48
+
49
+ def to_s
50
+ each_gateway do |g|
51
+ puts "#{g.display_name} - #{g.homepage_url} [#{g.supported_countries.join(', ')}]"
52
+ end
53
+ end
54
+ end
55
+
56
+
57
+
@@ -0,0 +1,90 @@
1
+ # Figure out the root path of this app. The default method will assume that
2
+ # its the same as the location of the running Rakefile
3
+ ROOT = File.expand_path(FileUtils.pwd) + '/'
4
+
5
+ # Standard settings, you can override each of them using the environment
6
+ # e.g. rake cia EMAIL_TO=your@email.com
7
+ #
8
+ RAKE_TASK = ENV['RAKE_TASK'] || ''
9
+ EMAIL_TO = ENV['EMAIL_TO'] || 'tobi@leetsoft.com'
10
+ EMAIL_FROM = ENV['EMAIL_FROM'] || 'CIA <cia@jadedpixel.com>'
11
+
12
+ # Get last segment of application's path and treat it as name.
13
+ NAME = ENV['NAME'] || ROOT.scan(/(\w+)\/$/).flatten.first.capitalize
14
+
15
+
16
+ class Build
17
+ attr_reader :status, :output, :success
18
+
19
+ def self.run
20
+ Build.new.run
21
+ end
22
+
23
+ def run
24
+ update if @status.nil?
25
+ make if @success.nil?
26
+ end
27
+
28
+ def revision
29
+ info['Revision'].to_i
30
+ end
31
+
32
+ def url
33
+ info['URL']
34
+ end
35
+
36
+ def commit_message
37
+ `svn log #{ROOT} -rHEAD`
38
+ end
39
+
40
+ def author
41
+ info['Last Changed Author']
42
+ end
43
+
44
+ def tests_ok?
45
+ run if @success.nil?
46
+ @success == true
47
+ end
48
+
49
+ def has_changes?
50
+ update if @status.nil?
51
+ @status =~ /[A-Z]\s+[\w\/]+/
52
+ end
53
+
54
+ private
55
+
56
+ def update
57
+ @status = `svn update #{ROOT}`
58
+ end
59
+
60
+ def info
61
+ @info ||= YAML.load(`svn info #{ROOT}`)
62
+ end
63
+
64
+ def make
65
+ @output, @success = `cd #{ROOT} && rake #{RAKE_TASK}`, ($?.exitstatus == 0)
66
+ end
67
+ end
68
+
69
+ task :cia do
70
+ build = Build.new
71
+
72
+ if build.has_changes? and not build.tests_ok?
73
+
74
+ require 'actionmailer'
75
+
76
+ ActionMailer::Base.delivery_method = :sendmail
77
+
78
+ class Notifier < ActionMailer::Base
79
+ def failure(build, sent_at = Time.now)
80
+ @subject = "[#{NAME}] Build Failure (##{build.revision})"
81
+ @recipients, @from, @sent_on = EMAIL_TO, EMAIL_FROM, sent_at
82
+ @body = ["#{build.author} broke the build!", build.commit_message, build.output].join("\n\n")
83
+ end
84
+ end
85
+
86
+ Notifier.deliver_failure(build)
87
+
88
+ end
89
+ end
90
+
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.join(File.dirname(__FILE__), '..')
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:merb_merchant, :rubygems, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.join(File.dirname(__FILE__), '..')
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:merb_merchant, :rubygems, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,80 @@
1
+ class Continuation # :nodoc:
2
+ def self.create(*args, &block) # :nodoc:
3
+ cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?}
4
+ result ||= args
5
+ return *[cc, *result]
6
+ end
7
+ end
8
+
9
+ class Binding; end # for RDoc
10
+ # This method returns the binding of the method that called your
11
+ # method. It will raise an Exception when you're not inside a method.
12
+ #
13
+ # It's used like this:
14
+ # def inc_counter(amount = 1)
15
+ # Binding.of_caller do |binding|
16
+ # # Create a lambda that will increase the variable 'counter'
17
+ # # in the caller of this method when called.
18
+ # inc = eval("lambda { |arg| counter += arg }", binding)
19
+ # # We can refer to amount from inside this block safely.
20
+ # inc.call(amount)
21
+ # end
22
+ # # No other statements can go here. Put them inside the block.
23
+ # end
24
+ # counter = 0
25
+ # 2.times { inc_counter }
26
+ # counter # => 2
27
+ #
28
+ # Binding.of_caller must be the last statement in the method.
29
+ # This means that you will have to put everything you want to
30
+ # do after the call to Binding.of_caller into the block of it.
31
+ # This should be no problem however, because Ruby has closures.
32
+ # If you don't do this an Exception will be raised. Because of
33
+ # the way that Binding.of_caller is implemented it has to be
34
+ # done this way.
35
+ def Binding.of_caller(&block)
36
+ old_critical = Thread.critical
37
+ Thread.critical = true
38
+ count = 0
39
+ cc, result, error, extra_data = Continuation.create(nil, nil)
40
+ error.call if error
41
+
42
+ tracer = lambda do |*args|
43
+ type, context, extra_data = args[0], args[4], args
44
+ if type == "return"
45
+ count += 1
46
+ # First this method and then calling one will return --
47
+ # the trace event of the second event gets the context
48
+ # of the method which called the method that called this
49
+ # method.
50
+ if count == 2
51
+ # It would be nice if we could restore the trace_func
52
+ # that was set before we swapped in our own one, but
53
+ # this is impossible without overloading set_trace_func
54
+ # in current Ruby.
55
+ set_trace_func(nil)
56
+ cc.call(eval("binding", context), nil, extra_data)
57
+ end
58
+ elsif type == "line" then
59
+ nil
60
+ elsif type == "c-return" and extra_data[3] == :set_trace_func then
61
+ nil
62
+ else
63
+ set_trace_func(nil)
64
+ error_msg = "Binding.of_caller used in non-method context or " +
65
+ "trailing statements of method using it aren't in the block."
66
+ cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil)
67
+ end
68
+ end
69
+
70
+ unless result
71
+ set_trace_func(tracer)
72
+ return nil
73
+ else
74
+ Thread.critical = old_critical
75
+ case block.arity
76
+ when 1 then yield(result)
77
+ else yield(result, extra_data)
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,547 @@
1
+ # The Breakpoint library provides the convenience of
2
+ # being able to inspect and modify state, diagnose
3
+ # bugs all via IRB by simply setting breakpoints in
4
+ # your applications by the call of a method.
5
+ #
6
+ # This library was written and is supported by me,
7
+ # Florian Gross. I can be reached at flgr@ccan.de
8
+ # and enjoy getting feedback about my libraries.
9
+ #
10
+ # The whole library (including breakpoint_client.rb
11
+ # and binding_of_caller.rb) is licensed under the
12
+ # same license that Ruby uses. (Which is currently
13
+ # either the GNU General Public License or a custom
14
+ # one that allows for commercial usage.) If you for
15
+ # some good reason need to use this under another
16
+ # license please contact me.
17
+
18
+ require 'irb'
19
+ require 'binding_of_caller'
20
+ require 'drb'
21
+ require 'drb/acl'
22
+ require 'thread'
23
+
24
+ module Breakpoint
25
+ id = %q$Id: breakpoint.rb 52 2005-02-26 19:43:19Z flgr $
26
+ current_version = id.split(" ")[2]
27
+ unless defined?(Version)
28
+ # The Version of ruby-breakpoint you are using as String of the
29
+ # 1.2.3 form where the digits stand for release, major and minor
30
+ # version respectively.
31
+ Version = "0.5.0"
32
+ end
33
+
34
+ extend self
35
+
36
+ # This will pop up an interactive ruby session at a
37
+ # pre-defined break point in a Ruby application. In
38
+ # this session you can examine the environment of
39
+ # the break point.
40
+ #
41
+ # You can get a list of variables in the context using
42
+ # local_variables via +local_variables+. You can then
43
+ # examine their values by typing their names.
44
+ #
45
+ # You can have a look at the call stack via +caller+.
46
+ #
47
+ # The source code around the location where the breakpoint
48
+ # was executed can be examined via +source_lines+. Its
49
+ # argument specifies how much lines of context to display.
50
+ # The default amount of context is 5 lines. Note that
51
+ # the call to +source_lines+ can raise an exception when
52
+ # it isn't able to read in the source code.
53
+ #
54
+ # breakpoints can also return a value. They will execute
55
+ # a supplied block for getting a default return value.
56
+ # A custom value can be returned from the session by doing
57
+ # +throw(:debug_return, value)+.
58
+ #
59
+ # You can also give names to break points which will be
60
+ # used in the message that is displayed upon execution
61
+ # of them.
62
+ #
63
+ # Here's a sample of how breakpoints should be placed:
64
+ #
65
+ # class Person
66
+ # def initialize(name, age)
67
+ # @name, @age = name, age
68
+ # breakpoint("Person#initialize")
69
+ # end
70
+ #
71
+ # attr_reader :age
72
+ # def name
73
+ # breakpoint("Person#name") { @name }
74
+ # end
75
+ # end
76
+ #
77
+ # person = Person.new("Random Person", 23)
78
+ # puts "Name: #{person.name}"
79
+ #
80
+ # And here is a sample debug session:
81
+ #
82
+ # Executing break point "Person#initialize" at file.rb:4 in `initialize'
83
+ # irb(#<Person:0x292fbe8>):001:0> local_variables
84
+ # => ["name", "age", "_", "__"]
85
+ # irb(#<Person:0x292fbe8>):002:0> [name, age]
86
+ # => ["Random Person", 23]
87
+ # irb(#<Person:0x292fbe8>):003:0> [@name, @age]
88
+ # => ["Random Person", 23]
89
+ # irb(#<Person:0x292fbe8>):004:0> self
90
+ # => #<Person:0x292fbe8 @age=23, @name="Random Person">
91
+ # irb(#<Person:0x292fbe8>):005:0> @age += 1; self
92
+ # => #<Person:0x292fbe8 @age=24, @name="Random Person">
93
+ # irb(#<Person:0x292fbe8>):006:0> exit
94
+ # Executing break point "Person#name" at file.rb:9 in `name'
95
+ # irb(#<Person:0x292fbe8>):001:0> throw(:debug_return, "Overriden name")
96
+ # Name: Overriden name
97
+ #
98
+ # Breakpoint sessions will automatically have a few
99
+ # convenience methods available. See Breakpoint::CommandBundle
100
+ # for a list of them.
101
+ #
102
+ # Breakpoints can also be used remotely over sockets.
103
+ # This is implemented by running part of the IRB session
104
+ # in the application and part of it in a special client.
105
+ # You have to call Breakpoint.activate_drb to enable
106
+ # support for remote breakpoints and then run
107
+ # breakpoint_client.rb which is distributed with this
108
+ # library. See the documentation of Breakpoint.activate_drb
109
+ # for details.
110
+ def breakpoint(id = nil, context = nil, &block)
111
+ callstack = caller
112
+ callstack.slice!(0, 3) if callstack.first["breakpoint"]
113
+ file, line, method = *callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures
114
+
115
+ message = "Executing break point " + (id ? "#{id.inspect} " : "") +
116
+ "at #{file}:#{line}" + (method ? " in `#{method}'" : "")
117
+
118
+ if context then
119
+ return handle_breakpoint(context, message, file, line, &block)
120
+ end
121
+
122
+ Binding.of_caller do |binding_context|
123
+ handle_breakpoint(binding_context, message, file, line, &block)
124
+ end
125
+ end
126
+
127
+ # These commands are automatically available in all breakpoint shells.
128
+ module CommandBundle
129
+ # Proxy to a Breakpoint client. Lets you directly execute code
130
+ # in the context of the client.
131
+ class Client
132
+ def initialize(eval_handler) # :nodoc:
133
+ eval_handler.untaint
134
+ @eval_handler = eval_handler
135
+ end
136
+
137
+ instance_methods.each do |method|
138
+ next if method[/^__.+__$/]
139
+ undef_method method
140
+ end
141
+
142
+ # Executes the specified code at the client.
143
+ def eval(code)
144
+ @eval_handler.call(code)
145
+ end
146
+
147
+ # Will execute the specified statement at the client.
148
+ def method_missing(method, *args, &block)
149
+ if args.empty? and not block
150
+ result = eval "#{method}"
151
+ else
152
+ # This is a bit ugly. The alternative would be using an
153
+ # eval context instead of an eval handler for executing
154
+ # the code at the client. The problem with that approach
155
+ # is that we would have to handle special expressions
156
+ # like "self", "nil" or constants ourself which is hard.
157
+ remote = eval %{
158
+ result = lambda { |block, *args| #{method}(*args, &block) }
159
+ def result.call_with_block(*args, &block)
160
+ call(block, *args)
161
+ end
162
+ result
163
+ }
164
+ remote.call_with_block(*args, &block)
165
+ end
166
+
167
+ return result
168
+ end
169
+ end
170
+
171
+ # Returns the source code surrounding the location where the
172
+ # breakpoint was issued.
173
+ def source_lines(context = 5, return_line_numbers = false)
174
+ lines = File.readlines(@__bp_file).map { |line| line.chomp }
175
+
176
+ break_line = @__bp_line
177
+ start_line = [break_line - context, 1].max
178
+ end_line = break_line + context
179
+
180
+ result = lines[(start_line - 1) .. (end_line - 1)]
181
+
182
+ if return_line_numbers then
183
+ return [start_line, break_line, result]
184
+ else
185
+ return result
186
+ end
187
+ end
188
+
189
+ # Lets an object that will forward method calls to the breakpoint
190
+ # client. This is useful for outputting longer things at the client
191
+ # and so on. You can for example do these things:
192
+ #
193
+ # client.puts "Hello" # outputs "Hello" at client console
194
+ # # outputs "Hello" into the file temp.txt at the client
195
+ # client.File.open("temp.txt", "w") { |f| f.puts "Hello" }
196
+ def client()
197
+ if Breakpoint.use_drb? then
198
+ sleep(0.5) until Breakpoint.drb_service.eval_handler
199
+ Client.new(Breakpoint.drb_service.eval_handler)
200
+ else
201
+ Client.new(lambda { |code| eval(code, TOPLEVEL_BINDING) })
202
+ end
203
+ end
204
+ end
205
+
206
+ def handle_breakpoint(context, message, file = "", line = "", &block) # :nodoc:
207
+ catch(:debug_return) do |value|
208
+ eval(%{
209
+ @__bp_file = #{file.inspect}
210
+ @__bp_line = #{line}
211
+ extend Breakpoint::CommandBundle
212
+ extend DRbUndumped if self
213
+ }, context) rescue nil
214
+
215
+ if not use_drb? then
216
+ puts message
217
+ IRB.start(nil, IRB::WorkSpace.new(context))
218
+ else
219
+ @drb_service.add_breakpoint(context, message)
220
+ end
221
+
222
+ block.call if block
223
+ end
224
+ end
225
+
226
+ # These exceptions will be raised on failed asserts
227
+ # if Breakpoint.asserts_cause_exceptions is set to
228
+ # true.
229
+ class FailedAssertError < RuntimeError
230
+ end
231
+
232
+ # This asserts that the block evaluates to true.
233
+ # If it doesn't evaluate to true a breakpoint will
234
+ # automatically be created at that execution point.
235
+ #
236
+ # You can disable assert checking in production
237
+ # code by setting Breakpoint.optimize_asserts to
238
+ # true. (It will still be enabled when Ruby is run
239
+ # via the -d argument.)
240
+ #
241
+ # Example:
242
+ # person_name = "Foobar"
243
+ # assert { not person_name.nil? }
244
+ #
245
+ # Note: If you want to use this method from an
246
+ # unit test, you will have to call it by its full
247
+ # name, Breakpoint.assert.
248
+ def assert(context = nil, &condition)
249
+ return if Breakpoint.optimize_asserts and not $DEBUG
250
+ return if yield
251
+
252
+ callstack = caller
253
+ callstack.slice!(0, 3) if callstack.first["assert"]
254
+ file, line, method = *callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures
255
+
256
+ message = "Assert failed at #{file}:#{line}#{" in `#{method}'" if method}."
257
+
258
+ if Breakpoint.asserts_cause_exceptions and not $DEBUG then
259
+ raise(Breakpoint::FailedAssertError, message)
260
+ end
261
+
262
+ message += " Executing implicit breakpoint."
263
+
264
+ if context then
265
+ return handle_breakpoint(context, message, file, line)
266
+ end
267
+
268
+ Binding.of_caller do |context|
269
+ handle_breakpoint(context, message, file, line)
270
+ end
271
+ end
272
+
273
+ # Whether asserts should be ignored if not in debug mode.
274
+ # Debug mode can be enabled by running ruby with the -d
275
+ # switch or by setting $DEBUG to true.
276
+ attr_accessor :optimize_asserts
277
+ self.optimize_asserts = false
278
+
279
+ # Whether an Exception should be raised on failed asserts
280
+ # in non-$DEBUG code or not. By default this is disabled.
281
+ attr_accessor :asserts_cause_exceptions
282
+ self.asserts_cause_exceptions = false
283
+ @use_drb = false
284
+
285
+ attr_reader :drb_service # :nodoc:
286
+
287
+ class DRbService # :nodoc:
288
+ include DRbUndumped
289
+
290
+ def initialize
291
+ @handler = @eval_handler = @collision_handler = nil
292
+
293
+ IRB.instance_eval { @CONF[:RC] = true }
294
+ IRB.run_config
295
+ end
296
+
297
+ def collision
298
+ sleep(0.5) until @collision_handler
299
+
300
+ @collision_handler.untaint
301
+
302
+ @collision_handler.call
303
+ end
304
+
305
+ def ping() end
306
+
307
+ def add_breakpoint(context, message)
308
+ workspace = IRB::WorkSpace.new(context)
309
+ workspace.extend(DRbUndumped)
310
+
311
+ sleep(0.5) until @handler
312
+
313
+ @handler.untaint
314
+ @handler.call(workspace, message)
315
+ rescue Errno::ECONNREFUSED, DRb::DRbConnError
316
+ raise if Breakpoint.use_drb?
317
+ end
318
+
319
+ attr_accessor :handler, :eval_handler, :collision_handler
320
+ end
321
+
322
+ # Will run Breakpoint in DRb mode. This will spawn a server
323
+ # that can be attached to via the breakpoint-client command
324
+ # whenever a breakpoint is executed. This is useful when you
325
+ # are debugging CGI applications or other applications where
326
+ # you can't access debug sessions via the standard input and
327
+ # output of your application.
328
+ #
329
+ # You can specify an URI where the DRb server will run at.
330
+ # This way you can specify the port the server runs on. The
331
+ # default URI is druby://localhost:42531.
332
+ #
333
+ # Please note that breakpoints will be skipped silently in
334
+ # case the DRb server can not spawned. (This can happen if
335
+ # the port is already used by another instance of your
336
+ # application on CGI or another application.)
337
+ #
338
+ # Also note that by default this will only allow access
339
+ # from localhost. You can however specify a list of
340
+ # allowed hosts or nil (to allow access from everywhere).
341
+ # But that will still not protect you from somebody
342
+ # reading the data as it goes through the net.
343
+ #
344
+ # A good approach for getting security and remote access
345
+ # is setting up an SSH tunnel between the DRb service
346
+ # and the client. This is usually done like this:
347
+ #
348
+ # $ ssh -L20000:127.0.0.1:20000 -R10000:127.0.0.1:10000 example.com
349
+ # (This will connect port 20000 at the client side to port
350
+ # 20000 at the server side, and port 10000 at the server
351
+ # side to port 10000 at the client side.)
352
+ #
353
+ # After that do this on the server side: (the code being debugged)
354
+ # Breakpoint.activate_drb("druby://127.0.0.1:20000", "localhost")
355
+ #
356
+ # And at the client side:
357
+ # ruby breakpoint_client.rb -c druby://127.0.0.1:10000 -s druby://127.0.0.1:20000
358
+ #
359
+ # Running through such a SSH proxy will also let you use
360
+ # breakpoint.rb in case you are behind a firewall.
361
+ #
362
+ # Detailed information about running DRb through firewalls is
363
+ # available at http://www.rubygarden.org/ruby?DrbTutorial
364
+ #
365
+ # == Security considerations
366
+ # Usually you will be fine when using the default druby:// URI and the default
367
+ # access control list. However, if you are sitting on a machine where there are
368
+ # local users that you likely can not trust (this is the case for example on
369
+ # most web hosts which have multiple users sitting on the same physical machine)
370
+ # you will be better off by doing client/server communication through a unix
371
+ # socket. This can be accomplished by calling with a drbunix:/ style URI, e.g.
372
+ # <code>Breakpoint.activate_drb('drbunix:/tmp/breakpoint_server')</code>. This
373
+ # will only work on Unix based platforms.
374
+ def activate_drb(uri = nil, allowed_hosts = ['localhost', '127.0.0.1', '::1'],
375
+ ignore_collisions = false)
376
+
377
+ return false if @use_drb
378
+
379
+ uri ||= 'druby://localhost:42531'
380
+
381
+ if allowed_hosts then
382
+ acl = ["deny", "all"]
383
+
384
+ Array(allowed_hosts).each do |host|
385
+ acl += ["allow", host]
386
+ end
387
+
388
+ DRb.install_acl(ACL.new(acl))
389
+ end
390
+
391
+ @use_drb = true
392
+ @drb_service = DRbService.new
393
+ did_collision = false
394
+ begin
395
+ @service = DRb.start_service(uri, @drb_service)
396
+ rescue Errno::EADDRINUSE
397
+ if ignore_collisions then
398
+ nil
399
+ else
400
+ # The port is already occupied by another
401
+ # Breakpoint service. We will try to tell
402
+ # the old service that we want its port.
403
+ # It will then forward that request to the
404
+ # user and retry.
405
+ unless did_collision then
406
+ DRbObject.new(nil, uri).collision
407
+ did_collision = true
408
+ end
409
+ sleep(10)
410
+ retry
411
+ end
412
+ end
413
+
414
+ return true
415
+ end
416
+
417
+ # Deactivates a running Breakpoint service.
418
+ def deactivate_drb
419
+ Thread.exclusive do
420
+ @service.stop_service unless @service.nil?
421
+ @service = nil
422
+ @use_drb = false
423
+ @drb_service = nil
424
+ end
425
+ end
426
+
427
+ # Returns true when Breakpoints are used over DRb.
428
+ # Breakpoint.activate_drb causes this to be true.
429
+ def use_drb?
430
+ @use_drb == true
431
+ end
432
+ end
433
+
434
+ module IRB # :nodoc:
435
+ class << self; remove_method :start; end
436
+ def self.start(ap_path = nil, main_context = nil, workspace = nil)
437
+ $0 = File::basename(ap_path, ".rb") if ap_path
438
+
439
+ # suppress some warnings about redefined constants
440
+ old_verbose, $VERBOSE = $VERBOSE, nil
441
+ IRB.setup(ap_path)
442
+ $VERBOSE = old_verbose
443
+
444
+ if @CONF[:SCRIPT] then
445
+ irb = Irb.new(main_context, @CONF[:SCRIPT])
446
+ else
447
+ irb = Irb.new(main_context)
448
+ end
449
+
450
+ if workspace then
451
+ irb.context.workspace = workspace
452
+ end
453
+
454
+ @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
455
+ @CONF[:MAIN_CONTEXT] = irb.context
456
+
457
+ old_sigint = trap("SIGINT") do
458
+ begin
459
+ irb.signal_handle
460
+ rescue RubyLex::TerminateLineInput
461
+ # ignored
462
+ end
463
+ end
464
+
465
+ catch(:IRB_EXIT) do
466
+ irb.eval_input
467
+ end
468
+ ensure
469
+ trap("SIGINT", old_sigint)
470
+ end
471
+
472
+ class << self
473
+ alias :old_CurrentContext :CurrentContext
474
+ remove_method :CurrentContext
475
+ remove_method :parse_opts
476
+ end
477
+
478
+ def IRB.CurrentContext
479
+ if old_CurrentContext.nil? and Breakpoint.use_drb? then
480
+ result = Object.new
481
+ def result.last_value; end
482
+ return result
483
+ else
484
+ old_CurrentContext
485
+ end
486
+ end
487
+ def IRB.parse_opts() end
488
+
489
+ class Context # :nodoc:
490
+ alias :old_evaluate :evaluate
491
+ def evaluate(line, line_no)
492
+ if line.chomp == "exit" then
493
+ exit
494
+ else
495
+ old_evaluate(line, line_no)
496
+ end
497
+ end
498
+ end
499
+
500
+ class WorkSpace # :nodoc:
501
+ alias :old_evaluate :evaluate
502
+
503
+ def evaluate(*args)
504
+ if Breakpoint.use_drb? then
505
+ result = old_evaluate(*args)
506
+ if args[0] != :no_proxy and
507
+ not [true, false, nil].include?(result)
508
+ then
509
+ result.extend(DRbUndumped) rescue nil
510
+ end
511
+ return result
512
+ else
513
+ old_evaluate(*args)
514
+ end
515
+ end
516
+ end
517
+
518
+ module InputCompletor # :nodoc:
519
+ def self.eval(code, context, *more)
520
+ # Big hack, this assumes that InputCompletor
521
+ # will only call eval() when it wants code
522
+ # to be executed in the IRB context.
523
+ IRB.conf[:MAIN_CONTEXT].workspace.evaluate(:no_proxy, code, *more)
524
+ end
525
+ end
526
+ end
527
+
528
+ module DRb # :nodoc:
529
+ class DRbObject # :nodoc:
530
+ undef :inspect if method_defined?(:inspect)
531
+ undef :clone if method_defined?(:clone)
532
+ end
533
+ end
534
+
535
+ # See Breakpoint.breakpoint
536
+ def breakpoint(id = nil, &block)
537
+ Binding.of_caller do |context|
538
+ Breakpoint.breakpoint(id, context, &block)
539
+ end
540
+ end
541
+
542
+ # See Breakpoint.assert
543
+ def assert(&block)
544
+ Binding.of_caller do |context|
545
+ Breakpoint.assert(context, &block)
546
+ end
547
+ end