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.
- data/LICENCE.rdoc +25 -0
- data/README.rdoc +32 -0
- data/bin/waw +32 -0
- data/bin/waw-profile +26 -0
- data/bin/waw-start +26 -0
- data/bin/wspec +33 -0
- data/layouts/empty/Rakefile +14 -0
- data/layouts/empty/config.ru +5 -0
- data/layouts/empty/config/commons.cfg +31 -0
- data/layouts/empty/config/devel.cfg +21 -0
- data/layouts/empty/ignore +7 -0
- data/layouts/empty/logs/dontforgetme +0 -0
- data/layouts/empty/resources/messages.rs +1 -0
- data/layouts/empty/test/wspec/site_respond.wspec +3 -0
- data/layouts/empty/test/wspec/test_all.rb +13 -0
- data/layouts/empty/waw.deploy +1 -0
- data/layouts/empty/waw.routing +6 -0
- data/layouts/static/dependencies +1 -0
- data/layouts/static/public/.wawaccess +18 -0
- data/layouts/static/public/css/style.css +0 -0
- data/layouts/static/public/images/dontforgetme +0 -0
- data/layouts/static/public/js/project.js +0 -0
- data/layouts/static/public/pages/.wawaccess +30 -0
- data/layouts/static/public/pages/404.wtpl +1 -0
- data/layouts/static/public/pages/index.wtpl +5 -0
- data/layouts/static/public/templates/.wawaccess +9 -0
- data/layouts/static/public/templates/layout.wtpl +17 -0
- data/layouts/static/test/wspec/static_pages_are_served.wspec +21 -0
- data/layouts/static/waw.routing +8 -0
- data/lib/waw.rb +99 -0
- data/lib/waw/commands/command.rb +115 -0
- data/lib/waw/commands/profile_command.rb +66 -0
- data/lib/waw/commands/start_command.rb +59 -0
- data/lib/waw/config.rb +110 -0
- data/lib/waw/controller.rb +25 -0
- data/lib/waw/controllers/action/action.rb +91 -0
- data/lib/waw/controllers/action/action_utils.rb +30 -0
- data/lib/waw/controllers/action/js_generation.rb +116 -0
- data/lib/waw/controllers/action_controller.rb +133 -0
- data/lib/waw/controllers/error/backtrace.rb +54 -0
- data/lib/waw/controllers/error_handler.rb +62 -0
- data/lib/waw/controllers/json_controller.rb +31 -0
- data/lib/waw/controllers/no_cache.rb +22 -0
- data/lib/waw/controllers/static/match.rb +80 -0
- data/lib/waw/controllers/static/waw_access.rb +235 -0
- data/lib/waw/controllers/static/waw_access_dsl.rb +48 -0
- data/lib/waw/controllers/static_controller.rb +37 -0
- data/lib/waw/default_config.cfg +14 -0
- data/lib/waw/environment_utils.rb +57 -0
- data/lib/waw/errors.rb +4 -0
- data/lib/waw/ext.rb +3 -0
- data/lib/waw/ext/core.rb +4 -0
- data/lib/waw/ext/core/hash.rb +47 -0
- data/lib/waw/ext/core/logger.rb +10 -0
- data/lib/waw/ext/core/module.rb +20 -0
- data/lib/waw/ext/core/object.rb +29 -0
- data/lib/waw/ext/rack.rb +19 -0
- data/lib/waw/ext/rack/builder.rb +43 -0
- data/lib/waw/ext/rack/delegator.rb +51 -0
- data/lib/waw/ext/rack/urlmap.rb +55 -0
- data/lib/waw/ext/wlang.rb +1 -0
- data/lib/waw/ext/wlang/hosted_language.rb +21 -0
- data/lib/waw/fullstate.rb +8 -0
- data/lib/waw/fullstate/on_class.rb +37 -0
- data/lib/waw/fullstate/on_instance.rb +27 -0
- data/lib/waw/fullstate/variable.rb +36 -0
- data/lib/waw/kern.rb +6 -0
- data/lib/waw/kern/app.rb +48 -0
- data/lib/waw/kern/empty/waw.deploy +0 -0
- data/lib/waw/kern/empty/waw.routing +1 -0
- data/lib/waw/kern/freezed_state.rb +32 -0
- data/lib/waw/kern/hooks.rb +53 -0
- data/lib/waw/kern/lifecycle.rb +248 -0
- data/lib/waw/kern/living_state.rb +87 -0
- data/lib/waw/kern/utils.rb +27 -0
- data/lib/waw/resource_collection.rb +100 -0
- data/lib/waw/restart.rb +32 -0
- data/lib/waw/routing.rb +43 -0
- data/lib/waw/routing/action_routing.rb +78 -0
- data/lib/waw/routing/dsl.rb +45 -0
- data/lib/waw/routing/feedback.rb +23 -0
- data/lib/waw/routing/form_validation_feedback.rb +36 -0
- data/lib/waw/routing/javascript.rb +17 -0
- data/lib/waw/routing/redirect.rb +26 -0
- data/lib/waw/routing/refresh.rb +17 -0
- data/lib/waw/routing/routing_rule.rb +16 -0
- data/lib/waw/scope_utils.rb +69 -0
- data/lib/waw/session.rb +51 -0
- data/lib/waw/testing.rb +1 -0
- data/lib/waw/tools/mail.rb +4 -0
- data/lib/waw/tools/mail/mail.rb +119 -0
- data/lib/waw/tools/mail/mail_agent.rb +123 -0
- data/lib/waw/tools/mail/mailbox.rb +62 -0
- data/lib/waw/tools/mail/template.rb +38 -0
- data/lib/waw/utils/dsl_helper.rb +116 -0
- data/lib/waw/validation.rb +175 -0
- data/lib/waw/validation/and_validator.rb +27 -0
- data/lib/waw/validation/array_validations.rb +38 -0
- data/lib/waw/validation/boolean_validator.rb +32 -0
- data/lib/waw/validation/comparison_validations.rb +45 -0
- data/lib/waw/validation/date_validator.rb +31 -0
- data/lib/waw/validation/default_validator.rb +30 -0
- data/lib/waw/validation/dsl_ruby_extensions.rb +11 -0
- data/lib/waw/validation/errors.rb +17 -0
- data/lib/waw/validation/ext.rb +3 -0
- data/lib/waw/validation/file_validator.rb +30 -0
- data/lib/waw/validation/float_validator.rb +19 -0
- data/lib/waw/validation/helpers.rb +67 -0
- data/lib/waw/validation/integer_validator.rb +16 -0
- data/lib/waw/validation/isin_validator.rb +24 -0
- data/lib/waw/validation/mandatory_validator.rb +17 -0
- data/lib/waw/validation/missing_validator.rb +17 -0
- data/lib/waw/validation/not_validator.rb +20 -0
- data/lib/waw/validation/or_validator.rb +34 -0
- data/lib/waw/validation/regexp_validator.rb +29 -0
- data/lib/waw/validation/same_validator.rb +16 -0
- data/lib/waw/validation/signature.rb +157 -0
- data/lib/waw/validation/size_validations.rb +44 -0
- data/lib/waw/validation/string_validator.rb +15 -0
- data/lib/waw/validation/validator.rb +48 -0
- data/lib/waw/wawgen.rb +2 -0
- data/lib/waw/wawgen/create.rb +166 -0
- data/lib/waw/wawgen/project.rb +25 -0
- data/lib/waw/wspec.rb +5 -0
- data/lib/waw/wspec/browser.rb +240 -0
- data/lib/waw/wspec/dsl.rb +201 -0
- data/lib/waw/wspec/html_analysis.rb +136 -0
- data/lib/waw/wspec/html_analysis/tag.rb +56 -0
- data/lib/waw/wspec/runner.rb +70 -0
- data/lib/waw/wspec/scenario.rb +35 -0
- data/lib/waw/wspec/suite.rb +54 -0
- data/test/bricks/error_handler/config/test.cfg +2 -0
- data/test/bricks/error_handler/logs/webapp.log +1411 -0
- data/test/bricks/error_handler/test/error_handler.wspec +16 -0
- data/test/bricks/error_handler/waw.deploy +1 -0
- data/test/bricks/error_handler/waw.routing +27 -0
- data/test/integration/waw_create_integration_test.rb +24 -0
- data/test/spec/assumptions_spec.rb +30 -0
- data/test/spec/controllers/action_controller_spec.rb +14 -0
- data/test/spec/controllers/static/waw_access_spec.rb +112 -0
- data/test/spec/environment_utils_spec.rb +15 -0
- data/test/spec/ext/core/hash_spec.rb +58 -0
- data/test/spec/fixtures.rb +41 -0
- data/test/spec/fixtures/action/config/default.cfg +2 -0
- data/test/spec/fixtures/action/lib/action_controller_test.rb +12 -0
- data/test/spec/fixtures/action/waw.deploy +1 -0
- data/test/spec/fixtures/action/waw.routing +6 -0
- data/test/spec/fixtures/empty/waw.deploy +0 -0
- data/test/spec/fixtures/empty/waw.routing +0 -0
- data/test/spec/fullstate/on_class_spec.rb +59 -0
- data/test/spec/fullstate/on_instance_spec.rb +59 -0
- data/test/spec/fullstate/session_spec.rb +43 -0
- data/test/spec/fullstate/variable_spec.rb +55 -0
- data/test/spec/resource_collection_spec.rb +50 -0
- data/test/spec/test_all.rb +9 -0
- data/test/spec/tools/mail/mail_agent_spec.rb +116 -0
- data/test/spec/tools/mail/mail_spec.rb +56 -0
- data/test/spec/tools/mail/mailbox_spec.rb +57 -0
- data/test/spec/tools/mail/template_spec.rb +47 -0
- data/test/spec/validation/array_validation_spec.rb +63 -0
- data/test/spec/validation/array_validator_spec.rb +17 -0
- data/test/spec/validation/date_validation_spec.rb +35 -0
- data/test/spec/validation/default_validation_spec.rb +37 -0
- data/test/spec/validation/disjuctive_validation_spec.rb +33 -0
- data/test/spec/validation/errors_spec.rb +37 -0
- data/test/spec/validation/file_validator_spec.rb +34 -0
- data/test/spec/validation/mail_validation_spec.rb +51 -0
- data/test/spec/validation/missing_validation_spec.rb +43 -0
- data/test/spec/validation/same_validation_spec.rb +24 -0
- data/test/spec/validation/signature_intuition_spec.rb +37 -0
- data/test/spec/validation/signature_spec.rb +164 -0
- data/test/spec/validation/validation_spec.rb +28 -0
- data/test/spec/wspec/html_analysis/tag_spec.rb +38 -0
- data/test/spec/wspec/html_analysis_spec.rb +170 -0
- data/test/unit/test_all.rb +8 -0
- data/test/unit/waw/app_test.rb +126 -0
- data/test/unit/waw/app_test/config/commons.cfg +2 -0
- data/test/unit/waw/app_test/config/devel.cfg +1 -0
- data/test/unit/waw/config_test.rb +54 -0
- data/test/unit/waw/controllers/action_controller_test.rb +76 -0
- data/test/unit/waw/controllers/action_test.rb +35 -0
- data/test/unit/waw/controllers/example_action_controller_test.rb +24 -0
- data/test/unit/waw/controllers/multiple_action_controller_test.rb +78 -0
- data/test/unit/waw/controllers/static/example/css/example.css +1 -0
- data/test/unit/waw/controllers/static/example/index.html +1 -0
- data/test/unit/waw/controllers/static/example/js/example.js +1 -0
- data/test/unit/waw/controllers/static/example/pages/hello.wtpl +1 -0
- data/test/unit/waw/controllers/static/waw_access_test.rb +76 -0
- data/test/unit/waw/ext/rack_test.rb +74 -0
- data/test/unit/waw/resource_collection_test.rb +49 -0
- data/test/unit/waw/resources.txt +4 -0
- data/test/unit/waw/routing/routing_test.rb +26 -0
- data/test/unit/waw/utils/dsl_helper_test.rb +79 -0
- data/test/unit/waw/utils/dsl_helper_test_extensions1.rb +4 -0
- data/test/unit/waw/validation/signature_test.rb +193 -0
- data/test/unit/waw/validation_test.rb +319 -0
- data/test/unit/waw/wspec/html_analysis_test.html +81 -0
- data/test/unit/waw/wspec/html_analysis_test.rb +26 -0
- metadata +272 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'date'
|
|
2
|
+
module Waw
|
|
3
|
+
module Validation
|
|
4
|
+
class DateValidator < Validator
|
|
5
|
+
|
|
6
|
+
# Returns a Date object if value seems a date,
|
|
7
|
+
# nil otherwise
|
|
8
|
+
def seems_a_date?(value)
|
|
9
|
+
if /^\d{4}\/\d{2}\/\d{2}$/ =~ value.to_s
|
|
10
|
+
Date.strptime(value.to_s, "%Y/%m/%d")
|
|
11
|
+
elsif /^\d{2}\/\d{2}\/\d{4}$/ =~ value.to_s
|
|
12
|
+
Date.strptime(value.to_s, "%d/%m/%Y")
|
|
13
|
+
else
|
|
14
|
+
nil
|
|
15
|
+
end
|
|
16
|
+
rescue ArgumentError => ex
|
|
17
|
+
nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def validate(*values)
|
|
21
|
+
values.all?{|val| seems_a_date?(val)}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def convert_and_validate(*values)
|
|
25
|
+
dates = values.collect{|v| seems_a_date?(v)}
|
|
26
|
+
dates.include?(nil) ? [false, values] : [true, dates]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end # class IntegerValidator
|
|
30
|
+
end # module Validation
|
|
31
|
+
end # module Waw
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Validation
|
|
3
|
+
class DefaultValidator < Validator
|
|
4
|
+
|
|
5
|
+
# Creates a validator instance
|
|
6
|
+
def initialize(*args, &block)
|
|
7
|
+
error("Validator default expects one argument or a block: default(19) or default{Time.now} for example", caller)\
|
|
8
|
+
unless (args.size==1 and block.nil?) or (args.empty? and not(block.nil?))
|
|
9
|
+
@which = args.empty? ? :block : :arg
|
|
10
|
+
@default_value = args.empty? ? block : args[0]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Always returns true
|
|
14
|
+
def validate(*values)
|
|
15
|
+
all_missing?(values)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Computes the default value from a missing one
|
|
19
|
+
def compute_default(value)
|
|
20
|
+
@which == :block ? @default_value.call(value) : @default_value
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Converts missing values by the default one
|
|
24
|
+
def convert_and_validate(*values)
|
|
25
|
+
validate(*values) ? [true, values.collect{|v| compute_default(v)}] : [false, values]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end # class DefaultValidator
|
|
29
|
+
end # module Validation
|
|
30
|
+
end # module Waw
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Validation
|
|
3
|
+
class Error < StandardError
|
|
4
|
+
|
|
5
|
+
# The list of failures
|
|
6
|
+
attr_accessor :failed
|
|
7
|
+
|
|
8
|
+
# Creates a validation error instance
|
|
9
|
+
def initialize(failed, msg = "Validation has failed #{failed.inspect}")
|
|
10
|
+
super(msg)
|
|
11
|
+
@failed = failed
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
class KO < Error; end
|
|
16
|
+
end
|
|
17
|
+
end # module Waw
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Validation
|
|
3
|
+
class FileValidator < Validator
|
|
4
|
+
|
|
5
|
+
def initialize(opts = {})
|
|
6
|
+
@options = opts
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Seems a valid file
|
|
10
|
+
def seems_a_file?(f)
|
|
11
|
+
return false unless File.file?(f)
|
|
12
|
+
return true unless @options
|
|
13
|
+
@options.each_pair do |key, value|
|
|
14
|
+
case key
|
|
15
|
+
when :extension
|
|
16
|
+
return false unless value==File.extname(f)
|
|
17
|
+
else
|
|
18
|
+
raise Waw::Error, "Unexpected FileValidator option #{key} : #{value}"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def validate(*values)
|
|
25
|
+
values.all?{|f| seems_a_file?(f)}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end # class NotValidator
|
|
29
|
+
end # module Validation
|
|
30
|
+
end # module Waw
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Validation
|
|
3
|
+
class FloatValidator < ::Waw::Validation::Validator
|
|
4
|
+
|
|
5
|
+
# Regular expression we use
|
|
6
|
+
FLOAT_REGEXP = /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/
|
|
7
|
+
|
|
8
|
+
def validate(*values)
|
|
9
|
+
values.all?{|v| ::Float===v}
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def convert_and_validate(*values)
|
|
13
|
+
ok = values.all?{|v| FLOAT_REGEXP =~ v.to_s}
|
|
14
|
+
ok ? [true, values.collect{|v| v.to_s.to_f}] : [false, values]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end # module Validation
|
|
19
|
+
end # module Waw
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Validation
|
|
3
|
+
module Helpers
|
|
4
|
+
|
|
5
|
+
# Sends a friendly error message if something is wrong
|
|
6
|
+
def error(msg, the_caller)
|
|
7
|
+
raise ::Waw::WawError, msg, the_caller
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Checks if a given value is considered missing. In a web environment,
|
|
11
|
+
# we consider a value being missing when it is nil or an empty string
|
|
12
|
+
# (when stripped). All validators should use this method to share a
|
|
13
|
+
# common definition for 'missing'. It may be overriden, at your own
|
|
14
|
+
# risks however. This method always returns false when invoked on
|
|
15
|
+
# any value other than nil or a String.
|
|
16
|
+
def is_missing?(value)
|
|
17
|
+
value.nil? or (String===value and value.strip.empty?)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Converts missing values to nil
|
|
21
|
+
def missings_to_nil(values)
|
|
22
|
+
values.collect{|v| is_missing?(v) ? nil : v}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Checks if all values are missing
|
|
26
|
+
def all_missing?(values)
|
|
27
|
+
values.all?{|v| is_missing?(v)}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Checks if any value is missing
|
|
31
|
+
def any_missing?(values)
|
|
32
|
+
values.any?{|v| is_missing?(v)}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Checks if no value is considered missing
|
|
36
|
+
def no_missing?(values)
|
|
37
|
+
not(any_missing?(values))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Yields the block inside a rescue on ArgumentError. Returns false
|
|
41
|
+
# if such an error has been raised
|
|
42
|
+
def argument_safe
|
|
43
|
+
yield
|
|
44
|
+
rescue ArgumentError
|
|
45
|
+
false
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Automatically converts specials guys as validators (regular
|
|
49
|
+
# expressions, some ruby classes, etc.)
|
|
50
|
+
def to_validator(who)
|
|
51
|
+
if who.is_a?(Class)
|
|
52
|
+
Waw::Validation.validator_for_ruby_class(who, true)
|
|
53
|
+
else
|
|
54
|
+
case who
|
|
55
|
+
when ::Waw::Validation::Validator
|
|
56
|
+
who
|
|
57
|
+
when Regexp
|
|
58
|
+
RegexpValidator.new(who, true)
|
|
59
|
+
else
|
|
60
|
+
raise "Unable to convert #{who}:#{who.class} to a validator"
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end # module Helpers
|
|
66
|
+
end # module Validation
|
|
67
|
+
end # module Waw
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Validation
|
|
3
|
+
class IntegerValidator < Validator
|
|
4
|
+
|
|
5
|
+
def validate(*values)
|
|
6
|
+
values.all?{|val| ::Integer===val}
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def convert_and_validate(*values)
|
|
10
|
+
ok = values.all?{|v| Integer===v or (/^[+-]?\d+$/ =~ v.to_s.strip)}
|
|
11
|
+
ok ? [true, values.collect{|v| v.to_s.strip.to_i}] : [false, values]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end # class IntegerValidator
|
|
15
|
+
end # module Validation
|
|
16
|
+
end # module Waw
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Validation
|
|
3
|
+
# Checks that arguments belongs to an array of allowed values provided
|
|
4
|
+
# at construction time.
|
|
5
|
+
class IsInValidator < Validator
|
|
6
|
+
|
|
7
|
+
# Creates the validator instance
|
|
8
|
+
def initialize(*allowed)
|
|
9
|
+
@allowed = (allowed.size==1 and Range===allowed[0]) ? allowed[0] : allowed
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Validation method
|
|
13
|
+
def validate(*values)
|
|
14
|
+
values.all?{|v| @allowed.include?(v)}
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Convert and validate method
|
|
18
|
+
def convert_and_validate(*values)
|
|
19
|
+
[validate(*values), values]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end # class IsInValidator
|
|
23
|
+
end # module Validation
|
|
24
|
+
end # module Waw
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Validation
|
|
3
|
+
class MandatoryValidator < Validator
|
|
4
|
+
|
|
5
|
+
# Calls the block installed at initialization time
|
|
6
|
+
def validate(*values)
|
|
7
|
+
no_missing?(values)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Converts and validate
|
|
11
|
+
def convert_and_validate(*values)
|
|
12
|
+
validate(*values) ? [true, values] : [false, values]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end # class MissingValidator
|
|
16
|
+
end # module Validation
|
|
17
|
+
end # module Waw
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Validation
|
|
3
|
+
class MissingValidator < Validator
|
|
4
|
+
|
|
5
|
+
# Calls the block installed at initialization time
|
|
6
|
+
def validate(*values)
|
|
7
|
+
values.all?{|value| is_missing?(value)}
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Converts and validate
|
|
11
|
+
def convert_and_validate(*values)
|
|
12
|
+
validate(*values) ? [true, missings_to_nil(values)] : [false, values]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end # class MissingValidator
|
|
16
|
+
end # module Validation
|
|
17
|
+
end # module Waw
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Validation
|
|
3
|
+
class NotValidator < Validator
|
|
4
|
+
|
|
5
|
+
def initialize(negated)
|
|
6
|
+
@negated = negated
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def validate(*values)
|
|
10
|
+
not(@negated.validate(*values))
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def convert_and_validate(*values)
|
|
14
|
+
ok, converted = @negated.convert_and_validate(*values)
|
|
15
|
+
ok ? [false, values] : [true, converted]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end # class NotValidator
|
|
19
|
+
end # module Validation
|
|
20
|
+
end # module Waw
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Validation
|
|
3
|
+
class OrValidator < Validator
|
|
4
|
+
|
|
5
|
+
# Empty constructor that overrides the top one
|
|
6
|
+
def initialize(*validators)
|
|
7
|
+
@validators = validators
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Calls the block installed at initialization time
|
|
11
|
+
def validate(*values)
|
|
12
|
+
values.all?{|val| @validators.any?{|validator| validator.validate(val)}}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Converts and validate
|
|
16
|
+
def convert_and_validate(*values)
|
|
17
|
+
converted = []
|
|
18
|
+
values.each do |value|
|
|
19
|
+
found = false
|
|
20
|
+
@validators.each do |validator|
|
|
21
|
+
found, val_converted = validator.convert_and_validate(value)
|
|
22
|
+
if found
|
|
23
|
+
converted << val_converted[0]
|
|
24
|
+
break
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
return [false, values] unless found
|
|
28
|
+
end
|
|
29
|
+
[true, converted]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end # class OrValidator
|
|
33
|
+
end # module Validation
|
|
34
|
+
end # module Waw
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Validation
|
|
3
|
+
# Validator that checks that values match a given regular expression
|
|
4
|
+
class RegexpValidator < ::Waw::Validation::Validator
|
|
5
|
+
|
|
6
|
+
#
|
|
7
|
+
# Creates a validator instance.
|
|
8
|
+
#
|
|
9
|
+
# If strip is set to true, the regexp is checked against a stripped
|
|
10
|
+
# version of value.to_s. In this case, the conversion strips the string
|
|
11
|
+
# as well.
|
|
12
|
+
#
|
|
13
|
+
def initialize(regexp, strip = true)
|
|
14
|
+
@regexp, @strip = regexp, strip
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Validation method
|
|
18
|
+
def validate(*values)
|
|
19
|
+
values.all?{|v| @regexp =~ (@strip ? v.to_s.strip : v.to_s)}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Converts and validate method
|
|
23
|
+
def convert_and_validate(*values)
|
|
24
|
+
validate(*values) ? [true, values.collect{|v| @strip ? v.to_s.strip : v}] : [false, values]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end # module Validation
|
|
29
|
+
end # module Waw
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Validation
|
|
3
|
+
# Checks that arguments are all non missing and equal
|
|
4
|
+
class SameValidator < Validator
|
|
5
|
+
|
|
6
|
+
def validate(*values)
|
|
7
|
+
any_missing?(values) ? false : values.uniq.size==1
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def convert_and_validate(*values)
|
|
11
|
+
[validate(*values), values]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end # class IntegerValidator
|
|
15
|
+
end # module Validation
|
|
16
|
+
end # module Waw
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Validation
|
|
3
|
+
#
|
|
4
|
+
# A service or data signature, as a list of validations to be respected.
|
|
5
|
+
#
|
|
6
|
+
class Signature
|
|
7
|
+
|
|
8
|
+
# The DSL attached to signature
|
|
9
|
+
class DSL
|
|
10
|
+
|
|
11
|
+
# Creates a DSL instance
|
|
12
|
+
def initialize(signature)
|
|
13
|
+
@signature = signature
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Executes a block as this DSL
|
|
17
|
+
def execute(&block)
|
|
18
|
+
DSLHelper.new(Class => [:&, :|, :not]) do
|
|
19
|
+
Kernel.load(File.join(File.dirname(__FILE__), 'dsl_ruby_extensions.rb'))
|
|
20
|
+
self.instance_eval(&block)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Adds a validation
|
|
25
|
+
def validation(args, validator, onfailure)
|
|
26
|
+
@signature.add_validation(args, ::Waw::Validation.to_validator(validator), onfailure)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# When a methos is missing
|
|
30
|
+
def method_missing(name, *args, &block)
|
|
31
|
+
Waw::Validation.send(name, *args, &block)
|
|
32
|
+
rescue Exception => ex
|
|
33
|
+
raise ex.class, ex.message, caller
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end # class DSL
|
|
37
|
+
|
|
38
|
+
# A validation rule
|
|
39
|
+
class ValidationRule
|
|
40
|
+
|
|
41
|
+
# Creates a Validation instance
|
|
42
|
+
def initialize(args, validator, onfailure)
|
|
43
|
+
@args = args
|
|
44
|
+
@validator = validator
|
|
45
|
+
@onfailure = onfailure
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Collects the interesting parameters on a hash
|
|
49
|
+
def collect_on_hash(hash)
|
|
50
|
+
@args.collect{|arg| hash[arg]}
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Validates argument values given through a hash. Returns nil
|
|
54
|
+
# if everything is ok, the on_failure installed parameters otherwise.
|
|
55
|
+
def validate(hash)
|
|
56
|
+
@validator.validate(*collect_on_hash(hash)) ? nil : @onfailure
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Validates and convert a hash. Values of the hash are replaced
|
|
60
|
+
# by their convertions if the validation passes. In this case, a
|
|
61
|
+
# nil value is returned. Otherwise, the on_failure is returned
|
|
62
|
+
# and the hash is not changed.
|
|
63
|
+
def convert_and_validate(hash)
|
|
64
|
+
ok, values = @validator.convert_and_validate(*collect_on_hash(hash))
|
|
65
|
+
@args.each_with_index {|arg, i| hash[arg] = values[i]} if ok
|
|
66
|
+
ok ? nil : @onfailure
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Applies the validation and conversion rule on a hash. Returns the
|
|
70
|
+
# first converted (or non converted if validation fails) value.
|
|
71
|
+
def first_converted(hash)
|
|
72
|
+
ok, values = @validator.convert_and_validate(*collect_on_hash(hash))
|
|
73
|
+
values[0]
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Completes a hash of default values
|
|
77
|
+
def complete_defaults(hash)
|
|
78
|
+
ok, values = @validator.convert_and_validate(*collect_on_hash(hash))
|
|
79
|
+
@args.each_with_index {|arg, i| hash[arg] = values[i]}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
end # class Validation
|
|
83
|
+
|
|
84
|
+
# Rules
|
|
85
|
+
attr_accessor :rules
|
|
86
|
+
|
|
87
|
+
# Creates an empty signature
|
|
88
|
+
def initialize(&block)
|
|
89
|
+
@rules = []
|
|
90
|
+
DSL.new(self).execute(&block) unless block.nil?
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Merges this signature with additional definition
|
|
94
|
+
def merge(&block)
|
|
95
|
+
signature = self.dup
|
|
96
|
+
DSL.new(signature).execute(&block) unless block.nil?
|
|
97
|
+
signature
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Adds a validation rule
|
|
101
|
+
def add_validation(args, validator, onfailure)
|
|
102
|
+
args = [args] if Symbol===args
|
|
103
|
+
@rules << ValidationRule.new(args, validator, onfailure)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Validates argument values given through a hash and returns a series
|
|
107
|
+
# of onfailure flags.
|
|
108
|
+
def validate(hash)
|
|
109
|
+
converted, failures = hash.dup, []
|
|
110
|
+
failures = @rules.collect{|rule| rule.validate(converted)}.compact
|
|
111
|
+
failures.empty? ? [true, converted] : [false, failures]
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Validates argument values given through a hash and returns a series
|
|
115
|
+
# of onfailure flags.
|
|
116
|
+
def apply(hash)
|
|
117
|
+
raise ArgumentError, "Hash expected (did you invoked an action without a Hash?)" unless Hash===hash
|
|
118
|
+
converted, failures = hash.dup, []
|
|
119
|
+
failures = @rules.collect{|rule| rule.convert_and_validate(converted)}.compact
|
|
120
|
+
failures.empty? ? [true, converted] : [false, failures]
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Calls first_converted(hash) on the first rule. Returns nil if no rule
|
|
124
|
+
# has been installed. The hash is never modified by this method.
|
|
125
|
+
def first_converted(hash = {})
|
|
126
|
+
return nil if @rules.nil? or @rules.empty?
|
|
127
|
+
@rules[0].first_converted(hash)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Checks if the signature allows passing with some values
|
|
131
|
+
def allows?(hash={})
|
|
132
|
+
apply(hash)[0]
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Checks if the signature blocks with some values
|
|
136
|
+
def blocks?(hash={})
|
|
137
|
+
not(allows?(hash))
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Computed default data for this signature
|
|
141
|
+
def default
|
|
142
|
+
defaults = {}
|
|
143
|
+
@rules.each {|rule| rule.complete_defaults(defaults)}
|
|
144
|
+
defaults
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Duplicates this validation
|
|
148
|
+
def dup
|
|
149
|
+
copy = Signature.new
|
|
150
|
+
copy.rules = self.rules.dup
|
|
151
|
+
copy
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
protected :rules=
|
|
155
|
+
end # class Signature
|
|
156
|
+
end # module Validation
|
|
157
|
+
end # module Waw
|