waw 0.2.2

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 (199) hide show
  1. data/LICENCE.rdoc +25 -0
  2. data/README.rdoc +32 -0
  3. data/bin/waw +32 -0
  4. data/bin/waw-profile +26 -0
  5. data/bin/waw-start +26 -0
  6. data/bin/wspec +33 -0
  7. data/layouts/empty/Rakefile +14 -0
  8. data/layouts/empty/config.ru +5 -0
  9. data/layouts/empty/config/commons.cfg +31 -0
  10. data/layouts/empty/config/devel.cfg +21 -0
  11. data/layouts/empty/ignore +7 -0
  12. data/layouts/empty/logs/dontforgetme +0 -0
  13. data/layouts/empty/resources/messages.rs +1 -0
  14. data/layouts/empty/test/wspec/site_respond.wspec +3 -0
  15. data/layouts/empty/test/wspec/test_all.rb +13 -0
  16. data/layouts/empty/waw.deploy +1 -0
  17. data/layouts/empty/waw.routing +6 -0
  18. data/layouts/static/dependencies +1 -0
  19. data/layouts/static/public/.wawaccess +18 -0
  20. data/layouts/static/public/css/style.css +0 -0
  21. data/layouts/static/public/images/dontforgetme +0 -0
  22. data/layouts/static/public/js/project.js +0 -0
  23. data/layouts/static/public/pages/.wawaccess +30 -0
  24. data/layouts/static/public/pages/404.wtpl +1 -0
  25. data/layouts/static/public/pages/index.wtpl +5 -0
  26. data/layouts/static/public/templates/.wawaccess +9 -0
  27. data/layouts/static/public/templates/layout.wtpl +17 -0
  28. data/layouts/static/test/wspec/static_pages_are_served.wspec +21 -0
  29. data/layouts/static/waw.routing +8 -0
  30. data/lib/waw.rb +99 -0
  31. data/lib/waw/commands/command.rb +115 -0
  32. data/lib/waw/commands/profile_command.rb +66 -0
  33. data/lib/waw/commands/start_command.rb +59 -0
  34. data/lib/waw/config.rb +110 -0
  35. data/lib/waw/controller.rb +25 -0
  36. data/lib/waw/controllers/action/action.rb +91 -0
  37. data/lib/waw/controllers/action/action_utils.rb +30 -0
  38. data/lib/waw/controllers/action/js_generation.rb +116 -0
  39. data/lib/waw/controllers/action_controller.rb +133 -0
  40. data/lib/waw/controllers/error/backtrace.rb +54 -0
  41. data/lib/waw/controllers/error_handler.rb +62 -0
  42. data/lib/waw/controllers/json_controller.rb +31 -0
  43. data/lib/waw/controllers/no_cache.rb +22 -0
  44. data/lib/waw/controllers/static/match.rb +80 -0
  45. data/lib/waw/controllers/static/waw_access.rb +235 -0
  46. data/lib/waw/controllers/static/waw_access_dsl.rb +48 -0
  47. data/lib/waw/controllers/static_controller.rb +37 -0
  48. data/lib/waw/default_config.cfg +14 -0
  49. data/lib/waw/environment_utils.rb +57 -0
  50. data/lib/waw/errors.rb +4 -0
  51. data/lib/waw/ext.rb +3 -0
  52. data/lib/waw/ext/core.rb +4 -0
  53. data/lib/waw/ext/core/hash.rb +47 -0
  54. data/lib/waw/ext/core/logger.rb +10 -0
  55. data/lib/waw/ext/core/module.rb +20 -0
  56. data/lib/waw/ext/core/object.rb +29 -0
  57. data/lib/waw/ext/rack.rb +19 -0
  58. data/lib/waw/ext/rack/builder.rb +43 -0
  59. data/lib/waw/ext/rack/delegator.rb +51 -0
  60. data/lib/waw/ext/rack/urlmap.rb +55 -0
  61. data/lib/waw/ext/wlang.rb +1 -0
  62. data/lib/waw/ext/wlang/hosted_language.rb +21 -0
  63. data/lib/waw/fullstate.rb +8 -0
  64. data/lib/waw/fullstate/on_class.rb +37 -0
  65. data/lib/waw/fullstate/on_instance.rb +27 -0
  66. data/lib/waw/fullstate/variable.rb +36 -0
  67. data/lib/waw/kern.rb +6 -0
  68. data/lib/waw/kern/app.rb +48 -0
  69. data/lib/waw/kern/empty/waw.deploy +0 -0
  70. data/lib/waw/kern/empty/waw.routing +1 -0
  71. data/lib/waw/kern/freezed_state.rb +32 -0
  72. data/lib/waw/kern/hooks.rb +53 -0
  73. data/lib/waw/kern/lifecycle.rb +248 -0
  74. data/lib/waw/kern/living_state.rb +87 -0
  75. data/lib/waw/kern/utils.rb +27 -0
  76. data/lib/waw/resource_collection.rb +100 -0
  77. data/lib/waw/restart.rb +32 -0
  78. data/lib/waw/routing.rb +43 -0
  79. data/lib/waw/routing/action_routing.rb +78 -0
  80. data/lib/waw/routing/dsl.rb +45 -0
  81. data/lib/waw/routing/feedback.rb +23 -0
  82. data/lib/waw/routing/form_validation_feedback.rb +36 -0
  83. data/lib/waw/routing/javascript.rb +17 -0
  84. data/lib/waw/routing/redirect.rb +26 -0
  85. data/lib/waw/routing/refresh.rb +17 -0
  86. data/lib/waw/routing/routing_rule.rb +16 -0
  87. data/lib/waw/scope_utils.rb +69 -0
  88. data/lib/waw/session.rb +51 -0
  89. data/lib/waw/testing.rb +1 -0
  90. data/lib/waw/tools/mail.rb +4 -0
  91. data/lib/waw/tools/mail/mail.rb +119 -0
  92. data/lib/waw/tools/mail/mail_agent.rb +123 -0
  93. data/lib/waw/tools/mail/mailbox.rb +62 -0
  94. data/lib/waw/tools/mail/template.rb +38 -0
  95. data/lib/waw/utils/dsl_helper.rb +116 -0
  96. data/lib/waw/validation.rb +175 -0
  97. data/lib/waw/validation/and_validator.rb +27 -0
  98. data/lib/waw/validation/array_validations.rb +38 -0
  99. data/lib/waw/validation/boolean_validator.rb +32 -0
  100. data/lib/waw/validation/comparison_validations.rb +45 -0
  101. data/lib/waw/validation/date_validator.rb +31 -0
  102. data/lib/waw/validation/default_validator.rb +30 -0
  103. data/lib/waw/validation/dsl_ruby_extensions.rb +11 -0
  104. data/lib/waw/validation/errors.rb +17 -0
  105. data/lib/waw/validation/ext.rb +3 -0
  106. data/lib/waw/validation/file_validator.rb +30 -0
  107. data/lib/waw/validation/float_validator.rb +19 -0
  108. data/lib/waw/validation/helpers.rb +67 -0
  109. data/lib/waw/validation/integer_validator.rb +16 -0
  110. data/lib/waw/validation/isin_validator.rb +24 -0
  111. data/lib/waw/validation/mandatory_validator.rb +17 -0
  112. data/lib/waw/validation/missing_validator.rb +17 -0
  113. data/lib/waw/validation/not_validator.rb +20 -0
  114. data/lib/waw/validation/or_validator.rb +34 -0
  115. data/lib/waw/validation/regexp_validator.rb +29 -0
  116. data/lib/waw/validation/same_validator.rb +16 -0
  117. data/lib/waw/validation/signature.rb +157 -0
  118. data/lib/waw/validation/size_validations.rb +44 -0
  119. data/lib/waw/validation/string_validator.rb +15 -0
  120. data/lib/waw/validation/validator.rb +48 -0
  121. data/lib/waw/wawgen.rb +2 -0
  122. data/lib/waw/wawgen/create.rb +166 -0
  123. data/lib/waw/wawgen/project.rb +25 -0
  124. data/lib/waw/wspec.rb +5 -0
  125. data/lib/waw/wspec/browser.rb +240 -0
  126. data/lib/waw/wspec/dsl.rb +201 -0
  127. data/lib/waw/wspec/html_analysis.rb +136 -0
  128. data/lib/waw/wspec/html_analysis/tag.rb +56 -0
  129. data/lib/waw/wspec/runner.rb +70 -0
  130. data/lib/waw/wspec/scenario.rb +35 -0
  131. data/lib/waw/wspec/suite.rb +54 -0
  132. data/test/bricks/error_handler/config/test.cfg +2 -0
  133. data/test/bricks/error_handler/logs/webapp.log +1411 -0
  134. data/test/bricks/error_handler/test/error_handler.wspec +16 -0
  135. data/test/bricks/error_handler/waw.deploy +1 -0
  136. data/test/bricks/error_handler/waw.routing +27 -0
  137. data/test/integration/waw_create_integration_test.rb +24 -0
  138. data/test/spec/assumptions_spec.rb +30 -0
  139. data/test/spec/controllers/action_controller_spec.rb +14 -0
  140. data/test/spec/controllers/static/waw_access_spec.rb +112 -0
  141. data/test/spec/environment_utils_spec.rb +15 -0
  142. data/test/spec/ext/core/hash_spec.rb +58 -0
  143. data/test/spec/fixtures.rb +41 -0
  144. data/test/spec/fixtures/action/config/default.cfg +2 -0
  145. data/test/spec/fixtures/action/lib/action_controller_test.rb +12 -0
  146. data/test/spec/fixtures/action/waw.deploy +1 -0
  147. data/test/spec/fixtures/action/waw.routing +6 -0
  148. data/test/spec/fixtures/empty/waw.deploy +0 -0
  149. data/test/spec/fixtures/empty/waw.routing +0 -0
  150. data/test/spec/fullstate/on_class_spec.rb +59 -0
  151. data/test/spec/fullstate/on_instance_spec.rb +59 -0
  152. data/test/spec/fullstate/session_spec.rb +43 -0
  153. data/test/spec/fullstate/variable_spec.rb +55 -0
  154. data/test/spec/resource_collection_spec.rb +50 -0
  155. data/test/spec/test_all.rb +9 -0
  156. data/test/spec/tools/mail/mail_agent_spec.rb +116 -0
  157. data/test/spec/tools/mail/mail_spec.rb +56 -0
  158. data/test/spec/tools/mail/mailbox_spec.rb +57 -0
  159. data/test/spec/tools/mail/template_spec.rb +47 -0
  160. data/test/spec/validation/array_validation_spec.rb +63 -0
  161. data/test/spec/validation/array_validator_spec.rb +17 -0
  162. data/test/spec/validation/date_validation_spec.rb +35 -0
  163. data/test/spec/validation/default_validation_spec.rb +37 -0
  164. data/test/spec/validation/disjuctive_validation_spec.rb +33 -0
  165. data/test/spec/validation/errors_spec.rb +37 -0
  166. data/test/spec/validation/file_validator_spec.rb +34 -0
  167. data/test/spec/validation/mail_validation_spec.rb +51 -0
  168. data/test/spec/validation/missing_validation_spec.rb +43 -0
  169. data/test/spec/validation/same_validation_spec.rb +24 -0
  170. data/test/spec/validation/signature_intuition_spec.rb +37 -0
  171. data/test/spec/validation/signature_spec.rb +164 -0
  172. data/test/spec/validation/validation_spec.rb +28 -0
  173. data/test/spec/wspec/html_analysis/tag_spec.rb +38 -0
  174. data/test/spec/wspec/html_analysis_spec.rb +170 -0
  175. data/test/unit/test_all.rb +8 -0
  176. data/test/unit/waw/app_test.rb +126 -0
  177. data/test/unit/waw/app_test/config/commons.cfg +2 -0
  178. data/test/unit/waw/app_test/config/devel.cfg +1 -0
  179. data/test/unit/waw/config_test.rb +54 -0
  180. data/test/unit/waw/controllers/action_controller_test.rb +76 -0
  181. data/test/unit/waw/controllers/action_test.rb +35 -0
  182. data/test/unit/waw/controllers/example_action_controller_test.rb +24 -0
  183. data/test/unit/waw/controllers/multiple_action_controller_test.rb +78 -0
  184. data/test/unit/waw/controllers/static/example/css/example.css +1 -0
  185. data/test/unit/waw/controllers/static/example/index.html +1 -0
  186. data/test/unit/waw/controllers/static/example/js/example.js +1 -0
  187. data/test/unit/waw/controllers/static/example/pages/hello.wtpl +1 -0
  188. data/test/unit/waw/controllers/static/waw_access_test.rb +76 -0
  189. data/test/unit/waw/ext/rack_test.rb +74 -0
  190. data/test/unit/waw/resource_collection_test.rb +49 -0
  191. data/test/unit/waw/resources.txt +4 -0
  192. data/test/unit/waw/routing/routing_test.rb +26 -0
  193. data/test/unit/waw/utils/dsl_helper_test.rb +79 -0
  194. data/test/unit/waw/utils/dsl_helper_test_extensions1.rb +4 -0
  195. data/test/unit/waw/validation/signature_test.rb +193 -0
  196. data/test/unit/waw/validation_test.rb +319 -0
  197. data/test/unit/waw/wspec/html_analysis_test.html +81 -0
  198. data/test/unit/waw/wspec/html_analysis_test.rb +26 -0
  199. metadata +272 -0
@@ -0,0 +1,16 @@
1
+ module Waw
2
+ module Routing
3
+ class RoutingRule
4
+
5
+ # Applies this routing rule on a Waw::WSpec::Browser instance.
6
+ # By default, does nothing at all.
7
+ def apply_on_browser(result, browser)
8
+ end
9
+
10
+ def generate_js_code(result, align=0)
11
+ raise "RoutingRule #{self.class} does not support javascript code generation"
12
+ end
13
+
14
+ end # RoutingRule
15
+ end # module Routing
16
+ end # module Waw
@@ -0,0 +1,69 @@
1
+ module Waw
2
+ module ScopeUtils
3
+
4
+ # Find the kernel context whose call must be delegated to.
5
+ def find_kernel_context
6
+ return self.waw_kernel if self.respond_to?(:waw_kernel)
7
+ return Waw.kernel if Waw.kernel
8
+ Waw.logger.warn("Using a empty kernel because no one has been found")
9
+ Waw::Kern::App.new("Empty autoloaded kernel").autoload(File.join(File.dirname(__FILE__), 'kern', 'empty'))
10
+ end
11
+
12
+ ################################################################# About waw application
13
+
14
+ # Returns the root folder
15
+ def root_folder
16
+ find_kernel_context.root_folder
17
+ end
18
+
19
+ # Returns waw resources
20
+ def config
21
+ find_kernel_context.config
22
+ end
23
+
24
+ # Logger to use
25
+ def logger
26
+ find_kernel_context.logger
27
+ end
28
+
29
+ # Returns waw resources
30
+ def resources
31
+ find_kernel_context.resources
32
+ end
33
+
34
+ ################################################################# About current request
35
+
36
+ # Returns the current Rack env instance
37
+ def rack_env
38
+ find_kernel_context.rack_env
39
+ end
40
+
41
+ # Returns the current Rack request instance
42
+ def request
43
+ find_kernel_context.request
44
+ end
45
+
46
+ # Returns the current Rack request instance
47
+ def response
48
+ find_kernel_context.response
49
+ end
50
+
51
+ # Request parameters
52
+ def params
53
+ find_kernel_context.params
54
+ end
55
+
56
+ ################################################################# About current session
57
+
58
+ # Returns the current Rack session
59
+ def real_session
60
+ find_kernel_context.real_session
61
+ end
62
+
63
+ # Returns the waw session decorator
64
+ def session
65
+ find_kernel_context.session
66
+ end
67
+
68
+ end # module ScopeUtils
69
+ end # module Waw
@@ -0,0 +1,51 @@
1
+ require 'singleton'
2
+ module Waw
3
+ class Session
4
+ extend FullState::OnInstance
5
+
6
+ # Creates a session instance
7
+ def initialize(rack_session)
8
+ @rack_session = rack_session
9
+ end
10
+
11
+ # Returns Rack's underlying session Hash
12
+ def rack_session
13
+ @rack_session
14
+ end
15
+
16
+ # Clears the session
17
+ def clear
18
+ rack_session.clear
19
+ end
20
+
21
+ # Checks if a given key exists in the session
22
+ def has_key?(name)
23
+ rack_session.has_key?(name)
24
+ end
25
+
26
+ # Returns the value of a given variable
27
+ def [](name)
28
+ rack_session[name]
29
+ end
30
+ alias :get :[]
31
+
32
+ # Returns the value of a given variable
33
+ def []=(name, value)
34
+ rack_session[name] = value
35
+ end
36
+ alias :set :[]=
37
+
38
+ # Resets a given variable whose name is provided
39
+ def reset(name)
40
+ rack_session.delete(name)
41
+ end
42
+ alias :delete :reset
43
+ alias :unset :reset
44
+
45
+ # Inspects the session
46
+ def inspect
47
+ rack_session.inspect
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1 @@
1
+ require 'waw/wspec'
@@ -0,0 +1,4 @@
1
+ require 'waw/tools/mail/mail_agent'
2
+ require 'waw/tools/mail/mail'
3
+ require 'waw/tools/mail/template'
4
+ require 'waw/tools/mail/mailbox'
@@ -0,0 +1,119 @@
1
+ module Waw
2
+ module Tools
3
+ class MailAgent
4
+ # A helper to respect the mail protocol
5
+ class Mail
6
+
7
+ # Source address
8
+ attr_accessor :from
9
+
10
+ # Target addresses
11
+ attr_accessor :to
12
+
13
+ # Target carbon copy addresses
14
+ attr_accessor :cc
15
+
16
+ # Target b carbon copy addresses
17
+ attr_accessor :bcc
18
+
19
+ # Mail subject
20
+ attr_accessor :subject
21
+
22
+ # Mail date
23
+ attr_accessor :date
24
+
25
+ # MIME version
26
+ attr_accessor :mime_version
27
+
28
+ # Content-type
29
+ attr_accessor :content_type
30
+
31
+ # Content-type
32
+ attr_accessor :charset
33
+
34
+ # Mail body
35
+ attr_accessor :body
36
+
37
+ # Creates an empty mail
38
+ def initialize(subject = nil, body = nil, from = nil, *to)
39
+ @from = from
40
+ @to = to.empty? ? [] : to
41
+ @cc, @bcc = [], []
42
+ @subject = subject
43
+ @date = Time.now
44
+ @mime_version = "1.0"
45
+ @content_type = "text/plain"
46
+ @charset = "UTF-8"
47
+ @body = body
48
+ end
49
+
50
+ # Class methods
51
+ class << self
52
+
53
+ # Decodes a mail from a given string
54
+ def decode(str)
55
+ mail = Mail.new
56
+ lines = str.split("\n")
57
+ until false
58
+ case line = lines.shift.strip
59
+ when /^From: (.*)$/
60
+ mail.from = $1
61
+ when /^To: (.*)$/
62
+ mail.to = $1.split(',').collect{|s| s.strip}
63
+ when /^Cc: (.*)$/
64
+ mail.cc = $1.split(',').collect{|s| s.strip}
65
+ when /^Bcc: (.*)$/
66
+ mail.bcc = $1.split(',').collect{|s| s.strip}
67
+ when /^Subject: (.*)$/
68
+ mail.subject = $1
69
+ when /^Date: (.*)$/
70
+ mail.date = Time.rfc2822($1)
71
+ when /^MIME-Version: (.*)$/
72
+ mail.mime_version = $1
73
+ when /^Content-type: (.*); charset=(.*)$/
74
+ mail.content_type = $1
75
+ mail.charset = $2
76
+ when /^$/
77
+ break
78
+ end
79
+ end
80
+ mail.body = lines.join("\n")
81
+ mail
82
+ end
83
+
84
+ alias :parse :decode
85
+ end
86
+
87
+ # Returns a valid mail string instantiation
88
+ def to_s
89
+ str = <<-MAIL_END
90
+ From: #{from}
91
+ To: #{to.nil? ? '' : to.join(", ")}
92
+ Cc: #{cc.nil? ? '' : cc.join(", ")}
93
+ Bcc: #{bcc.nil? ? '' : bcc.join(", ")}
94
+ Subject: #{subject}
95
+ Date: #{date.rfc2822}
96
+ MIME-Version: #{mime_version}
97
+ Content-type: #{content_type}; charset=#{charset}
98
+
99
+ #{body}
100
+ MAIL_END
101
+ str.gsub(/^[ \t]*/, '')
102
+ end
103
+ alias :encode :to_s
104
+ alias :dump :to_s
105
+
106
+ # Makes a deep copy of this mail. Changing the list of receivers
107
+ # in particular does not affect the original mail
108
+ def dup
109
+ mail = super
110
+ mail.to = to.nil? ? nil : to.dup
111
+ mail.cc = cc.nil? ? nil : cc.dup
112
+ mail.bcc = bcc.nil? ? nil : bcc.dup
113
+ mail
114
+ end
115
+
116
+ end # class Mail
117
+ end # class MailAgent
118
+ end # module Tools
119
+ end # module Waw
@@ -0,0 +1,123 @@
1
+ module Waw
2
+ module Tools
3
+ # Provides a tool to send mails simply
4
+ class MailAgent
5
+
6
+ # Creates a default mail agent
7
+ def initialize(opts = {}, force_real = false)
8
+ @force_real = force_real
9
+ if do_it_really?
10
+ @smtp_host = opts[:host]
11
+ @smtp_port = opts[:port]
12
+ @smtp_timeout = opts[:timeout]
13
+ raise ArgumentError, "Opts should include :host, :port and :timeout parameters\n#{opts.inspect} received"\
14
+ if @smtp_host.nil? or @smtp_port.nil? or @smtp_timeout.nil?
15
+ end
16
+ @templates = {}
17
+ end
18
+
19
+ # Builds a mail instance. This method should always be used preferably
20
+ # to an explicit Mail.new invocation.
21
+ def mail(*args)
22
+ Mail.new(*args)
23
+ end
24
+
25
+ # Builds a template instance. This method should always be used preferably
26
+ # to an explicit Template.new invocation.
27
+ def template(*args)
28
+ Template.new(*args)
29
+ end
30
+
31
+ # Adds a mail template under a given name
32
+ def add_template(name, *args)
33
+ if args.size == 1 and Template===args[0]
34
+ @templates[name] = args[0]
35
+ else
36
+ @templates[name] = template(*args)
37
+ end
38
+ end
39
+
40
+ # Converts a named template to a mail
41
+ def to_mail(template_name, wlang_context)
42
+ raise ArgumentError, "No such template #{template_name}" unless @templates.has_key?(template_name)
43
+ @templates[template_name].to_mail(wlang_context)
44
+ end
45
+
46
+ # Send mails, really?
47
+ def do_it_really?
48
+ @force_real or (Waw.config and ['production', 'acceptation'].include?(Waw.config.deploy_mode))
49
+ end
50
+
51
+ # Returns installed mailboxes
52
+ def mailboxes
53
+ @mailboxes ||= Hash.new{|h, k| h[k] = Mailbox.new(k)}
54
+ end
55
+
56
+ # Returns the mailbox of a given receiver, creating
57
+ # a new one if it cannot be found
58
+ def mailbox(receiver)
59
+ mailboxes[receiver]
60
+ end
61
+
62
+ #
63
+ # Sends an email. If Waw.config.deploy_mode is set to 'production'
64
+ # or 'acceptation', the mail is really sent. Otherwise it is pushed
65
+ # in the receiver mailbox.
66
+ #
67
+ # This method accepts the following invocation signatures:
68
+ #
69
+ # # sending a real Mail instance (and only one)
70
+ # agent.send_mail(mail)
71
+ #
72
+ # # sending from a template for which receivers have been already set
73
+ # agent.send_mail(:my_template, {:title => "Hello"})
74
+ #
75
+ # # sending from a template, with explicit receivers as varargs
76
+ # agent.send_mail(:my_template, {:title => "Hello"}, "receiver@example.com", ..., "receiver_N@example.com")
77
+ #
78
+ # # sending from a template, with explicit receivers as an array
79
+ # agent.send_mail(:my_template, {:title => "Hello"}, [...])
80
+ #
81
+ def send_mail(*args)
82
+ # Let try to match the signature
83
+ if args.size == 1 and Mail===args[0]
84
+ # first one
85
+ mail = args[0]
86
+ elsif Symbol===args[0] and Hash===args[1]
87
+ # the others
88
+ mail = to_mail(args.shift, args.shift)
89
+ unless args.empty?
90
+ if args.size == 1 and Array===args[0]
91
+ # third one
92
+ mail.to = args[0]
93
+ else
94
+ # fourth one
95
+ mail.to = args
96
+ end
97
+ else
98
+ # second one
99
+ end
100
+ else
101
+ raise ArgumentError, "Unable to find the send_mail sigature you want with #{args.inspect}"
102
+ end
103
+
104
+ if do_it_really?
105
+ require 'net/smtp'
106
+ smtp_conn = Net::SMTP.new(@smtp_host, @smtp_port)
107
+ smtp_conn.open_timeout = @smtp_timeout
108
+ smtp_conn.start
109
+ smtp_conn.send_message(mail.dump, mail.from, *mail.to)
110
+ smtp_conn.finish
111
+ else
112
+ Waw.logger.debug mail.dump
113
+ sent = Mail.parse(mail.dump)
114
+ mail.to.each {|who| mailbox(who) << sent.dup}
115
+ mail.cc.each {|who| mailbox(who) << sent.dup}
116
+ mail.bcc.each {|who| mailbox(who) << sent.dup}
117
+ end
118
+ end
119
+ alias :<< :send_mail
120
+
121
+ end # class MailAgent
122
+ end # module Tools
123
+ end # module Waw
@@ -0,0 +1,62 @@
1
+ module Waw
2
+ module Tools
3
+ class MailAgent
4
+ # Helper for testing purposes only.
5
+ class Mailbox
6
+
7
+ # Creates an empty mailbox for a given adress
8
+ def initialize(mail_address)
9
+ @mail_address = mail_address
10
+ @mails = []
11
+ end
12
+
13
+ # Returns the number of mails in this mailbox
14
+ def size
15
+ @mails.size
16
+ end
17
+
18
+ # Checks if the mailbox is empty or not
19
+ def empty?
20
+ @mails.empty?
21
+ end
22
+
23
+ # Pushes a mail inside the mailbox, returns an id
24
+ def push(mail)
25
+ @mails << [mail, false]
26
+ @mails.size-1
27
+ end
28
+ alias :<< :push
29
+
30
+ # Returns the id-th mail in the mailbox. Returns nil
31
+ # if no such mail can be found
32
+ def [](id)
33
+ mail = @mails[id]
34
+ return nil unless mail
35
+ mail[0]
36
+ end
37
+
38
+ # Checks if a mail is marked as read. Returns nil
39
+ # if no such mail can be found
40
+ def is_read?(id)
41
+ mail = @mails[id]
42
+ return nil unless mail
43
+ mail[1]
44
+ end
45
+
46
+ # Marks a mail as read and returns it
47
+ def read(id)
48
+ mail = @mails[id]
49
+ return nil unless mail
50
+ mail[1] = true
51
+ mail[0]
52
+ end
53
+
54
+ # Removes all mails
55
+ def clear
56
+ @mails.clear
57
+ end
58
+
59
+ end # class Mailbox
60
+ end # class MailAgent
61
+ end # module Tools
62
+ end # module Waw