should_pricot 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/Manifest +92 -0
  3. data/README.rdoc +45 -0
  4. data/Rakefile +36 -0
  5. data/lib/should_pricot.rb +19 -0
  6. data/lib/should_pricot/count_assertion.rb +12 -0
  7. data/lib/should_pricot/element_assertion.rb +39 -0
  8. data/should_pricot.gemspec +31 -0
  9. data/tasks/should_pricot_tasks.rake +4 -0
  10. data/test/fixtures/posts.yml +4 -0
  11. data/test/fixtures/users.yml +9 -0
  12. data/test/functional/users_controller_test.rb +16 -0
  13. data/test/should_pricot_test.rb +6 -0
  14. data/test/test-app/app/controllers/application_controller.rb +10 -0
  15. data/test/test-app/app/controllers/users_controller.rb +40 -0
  16. data/test/test-app/app/helpers/application_helper.rb +3 -0
  17. data/test/test-app/app/models/post.rb +3 -0
  18. data/test/test-app/app/models/user.rb +7 -0
  19. data/test/test-app/app/views/users/edit.html.erb +0 -0
  20. data/test/test-app/app/views/users/index.html.erb +9 -0
  21. data/test/test-app/app/views/users/new.html.erb +0 -0
  22. data/test/test-app/config/boot.rb +110 -0
  23. data/test/test-app/config/database.yml +4 -0
  24. data/test/test-app/config/environment.rb +12 -0
  25. data/test/test-app/config/environments/test.rb +0 -0
  26. data/test/test-app/config/initializers/funktional.rb +8 -0
  27. data/test/test-app/config/initializers/new_rails_defaults.rb +21 -0
  28. data/test/test-app/config/routes.rb +5 -0
  29. data/test/test-app/db/migrate/001_create_users.rb +18 -0
  30. data/test/test-app/db/migrate/002_create_posts.rb +13 -0
  31. data/test/test-app/public/404.html +30 -0
  32. data/test/test-app/public/422.html +30 -0
  33. data/test/test-app/public/500.html +30 -0
  34. data/test/test-app/script/console +3 -0
  35. data/test/test-app/script/generate +3 -0
  36. data/test/test-app/vendor/plugins/funktional/MIT-LICENSE +20 -0
  37. data/test/test-app/vendor/plugins/funktional/README.rdoc +289 -0
  38. data/test/test-app/vendor/plugins/funktional/Rakefile +23 -0
  39. data/test/test-app/vendor/plugins/funktional/init.rb +8 -0
  40. data/test/test-app/vendor/plugins/funktional/install.rb +1 -0
  41. data/test/test-app/vendor/plugins/funktional/lib/funktional.rb +41 -0
  42. data/test/test-app/vendor/plugins/funktional/lib/funktional/assertion.rb +9 -0
  43. data/test/test-app/vendor/plugins/funktional/lib/funktional/assigned_assertion.rb +39 -0
  44. data/test/test-app/vendor/plugins/funktional/lib/funktional/attribute_test_helper.rb +27 -0
  45. data/test/test-app/vendor/plugins/funktional/lib/funktional/context.rb +126 -0
  46. data/test/test-app/vendor/plugins/funktional/lib/funktional/context/assigned_should_block.rb +32 -0
  47. data/test/test-app/vendor/plugins/funktional/lib/funktional/context/collector.rb +21 -0
  48. data/test/test-app/vendor/plugins/funktional/lib/funktional/context/count_should_block.rb +21 -0
  49. data/test/test-app/vendor/plugins/funktional/lib/funktional/context/delegating_should_block.rb +30 -0
  50. data/test/test-app/vendor/plugins/funktional/lib/funktional/context/element_should_block.rb +29 -0
  51. data/test/test-app/vendor/plugins/funktional/lib/funktional/context/flashed_should_block.rb +17 -0
  52. data/test/test-app/vendor/plugins/funktional/lib/funktional/context/should_block.rb +60 -0
  53. data/test/test-app/vendor/plugins/funktional/lib/funktional/context/should_create_block.rb +17 -0
  54. data/test/test-app/vendor/plugins/funktional/lib/funktional/context/should_delete_block.rb +17 -0
  55. data/test/test-app/vendor/plugins/funktional/lib/funktional/context/should_not_block.rb +20 -0
  56. data/test/test-app/vendor/plugins/funktional/lib/funktional/context/should_not_create_block.rb +17 -0
  57. data/test/test-app/vendor/plugins/funktional/lib/funktional/context/should_not_delete_block.rb +17 -0
  58. data/test/test-app/vendor/plugins/funktional/lib/funktional/context/should_not_send_email_block.rb +18 -0
  59. data/test/test-app/vendor/plugins/funktional/lib/funktional/context/stack_recorder.rb +34 -0
  60. data/test/test-app/vendor/plugins/funktional/lib/funktional/email_assertion.rb +50 -0
  61. data/test/test-app/vendor/plugins/funktional/lib/funktional/flashed_assertion.rb +12 -0
  62. data/test/test-app/vendor/plugins/funktional/lib/funktional/model_assertions.rb +108 -0
  63. data/test/test-app/vendor/plugins/funktional/lib/funktional/random_characters.rb +11 -0
  64. data/test/test-app/vendor/plugins/funktional/lib/funktional/recursive_assertion.rb +23 -0
  65. data/test/test-app/vendor/plugins/funktional/lib/funktional/route_checker.rb +49 -0
  66. data/test/test-app/vendor/plugins/funktional/lib/funktional/setup.rb +11 -0
  67. data/test/test-app/vendor/plugins/funktional/lib/funktional/test_class_methods.rb +28 -0
  68. data/test/test-app/vendor/plugins/funktional/lib/funktional/test_instance_methods.rb +131 -0
  69. data/test/test-app/vendor/plugins/funktional/tasks/should_b_tasks.rake +4 -0
  70. data/test/test-app/vendor/plugins/funktional/test/fixtures/posts.yml +4 -0
  71. data/test/test-app/vendor/plugins/funktional/test/fixtures/users.yml +5 -0
  72. data/test/test-app/vendor/plugins/funktional/test/test-app/app/controllers/application_controller.rb +10 -0
  73. data/test/test-app/vendor/plugins/funktional/test/test-app/app/helpers/application_helper.rb +3 -0
  74. data/test/test-app/vendor/plugins/funktional/test/test-app/app/models/post.rb +3 -0
  75. data/test/test-app/vendor/plugins/funktional/test/test-app/app/models/user.rb +7 -0
  76. data/test/test-app/vendor/plugins/funktional/test/test-app/config/boot.rb +110 -0
  77. data/test/test-app/vendor/plugins/funktional/test/test-app/config/database.yml +4 -0
  78. data/test/test-app/vendor/plugins/funktional/test/test-app/config/environment.rb +12 -0
  79. data/test/test-app/vendor/plugins/funktional/test/test-app/config/environments/test.rb +0 -0
  80. data/test/test-app/vendor/plugins/funktional/test/test-app/config/initializers/funktional.rb +8 -0
  81. data/test/test-app/vendor/plugins/funktional/test/test-app/config/initializers/new_rails_defaults.rb +21 -0
  82. data/test/test-app/vendor/plugins/funktional/test/test-app/config/routes.rb +4 -0
  83. data/test/test-app/vendor/plugins/funktional/test/test-app/db/migrate/001_create_users.rb +18 -0
  84. data/test/test-app/vendor/plugins/funktional/test/test-app/db/migrate/002_create_posts.rb +13 -0
  85. data/test/test-app/vendor/plugins/funktional/test/test-app/public/404.html +30 -0
  86. data/test/test-app/vendor/plugins/funktional/test/test-app/public/422.html +30 -0
  87. data/test/test-app/vendor/plugins/funktional/test/test-app/public/500.html +30 -0
  88. data/test/test-app/vendor/plugins/funktional/test/test-app/script/console +3 -0
  89. data/test/test-app/vendor/plugins/funktional/test/test-app/script/generate +3 -0
  90. data/test/test-app/vendor/plugins/funktional/test/test_helper.rb +27 -0
  91. data/test/test-app/vendor/plugins/funktional/test/unit/user_test.rb +12 -0
  92. data/test/test-app/vendor/plugins/funktional/uninstall.rb +1 -0
  93. data/test/test_helper.rb +30 -0
  94. metadata +170 -0
@@ -0,0 +1,60 @@
1
+ module Funktional
2
+ class ShouldBlock
3
+
4
+ def self.build(options, context, &blk)
5
+ return self.new(name = options, context, &blk) if options.is_a? String
6
+
7
+ options = {:render_404 => 'public/404'} if options == :render_404
8
+
9
+ case options.keys.first
10
+ when :create
11
+ ShouldCreateBlock.new(options[:create], context)
12
+ when :delete
13
+ ShouldDeleteBlock.new(options[:delete], context)
14
+ else
15
+ DelegatingShouldBlock.new(options, context, &blk)
16
+ end
17
+ end
18
+
19
+ def initialize(should_name, context, &blk)
20
+ raise 'block required' unless block_given?
21
+ @should_name, @blk, @context = should_name, blk, context
22
+ end
23
+
24
+ def to_test
25
+ context, blk, before = @context, @blk, @before
26
+
27
+ @context.test_unit_class.send(:define_method, build_test_name) do
28
+ begin
29
+ context.run_parent_setup_blocks(self)
30
+ before.bind(self).call if before
31
+
32
+ context.run_current_setup_blocks(self)
33
+ blk.bind(self).call
34
+ ensure
35
+ context.run_all_teardown_blocks(self)
36
+ end
37
+ end
38
+ end
39
+
40
+ protected
41
+
42
+ def test_and_line_no
43
+ stack_frame = caller.grep(/bind/).last
44
+ stack_frame.split(':in ').first
45
+ end
46
+
47
+ def build_test_name
48
+ test_name = test_name_parts.flatten.join(' ')
49
+
50
+ if @context.test_unit_class.instance_methods.include?(test_name)
51
+ warn " * WARNING: '#{test_name}' is already defined"
52
+ end
53
+ return test_name.to_sym
54
+ end
55
+
56
+ def test_name_parts
57
+ ["test:", @context.full_name, "should", "#{@should_name}."]
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,17 @@
1
+ module Funktional
2
+ class ShouldCreateBlock < ShouldBlock
3
+
4
+ def initialize(klass, context)
5
+ @context = context
6
+ @should_name = "create a #{klass}"
7
+
8
+ @before = lambda { @before_setup_count = klass.count }
9
+ where = test_and_line_no
10
+
11
+ @blk = lambda do
12
+ expected_count = @before_setup_count + 1
13
+ assert_equal expected_count, klass.count, "New [#{klass}] was not created. #{where}"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Funktional
2
+ class ShouldDeleteBlock < ShouldBlock
3
+
4
+ def initialize(klass, context)
5
+ @context = context
6
+ @should_name = "delete a #{klass}"
7
+
8
+ @before = lambda { @before_setup_count = klass.count }
9
+ where = test_and_line_no
10
+
11
+ @blk = lambda do
12
+ expected_count = @before_setup_count - 1
13
+ assert_equal expected_count, klass.count, "New [#{klass}] was not deleted. #{where}"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ module Funktional
2
+ class ShouldNotBlock
3
+
4
+ def self.build(options, context, &blk)
5
+
6
+ if options.is_a? Symbol and options.eql? :send_email
7
+ return ShouldNotSendEmailBlock.new(context)
8
+ end
9
+
10
+ case options.keys.first
11
+ when :create
12
+ ShouldNotCreateBlock.new(options[:create], context)
13
+ when :delete
14
+ ShouldNotDeleteBlock.new(options[:delete], context)
15
+ else
16
+ raise "Unknown assertion [should_not #{options.inspect}]"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ module Funktional
2
+ class ShouldNotCreateBlock < ShouldBlock
3
+
4
+ def initialize(klass, context)
5
+ @context = context
6
+ @should_name = "not create a #{klass}"
7
+
8
+ @before = lambda { @before_setup_count = klass.count }
9
+ where = test_and_line_no
10
+
11
+ @blk = lambda do
12
+ expected_count = @before_setup_count
13
+ assert_equal expected_count, klass.count, "New [#{klass}] was created. #{where}"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Funktional
2
+ class ShouldNotDeleteBlock < ShouldBlock
3
+
4
+ def initialize(klass, context)
5
+ @context = context
6
+ @should_name = "not delete a #{klass}"
7
+
8
+ @before = lambda { @before_setup_count = klass.count }
9
+ where = test_and_line_no
10
+
11
+ @blk = lambda do
12
+ expected_count = @before_setup_count
13
+ assert_equal expected_count, klass.count, "New [#{klass}] was deleted. #{where}"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ module Funktional
2
+ class ShouldNotSendEmailBlock < ShouldBlock
3
+
4
+ def initialize(context)
5
+ @context = context
6
+ @should_name = "not send an email"
7
+
8
+ @before = lambda { @before_setup_count = ActionMailer::Base.deliveries.size }
9
+ where = test_and_line_no
10
+
11
+ @blk = lambda do
12
+ expected_count = @before_setup_count
13
+ current = ActionMailer::Base.deliveries.size
14
+ assert_equal expected_count, current, "New [Email] was sent."
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ module Funktional
2
+ class BlankSlate
3
+ instance_methods.each { |m| undef_method m unless m =~ /^__/ }
4
+ end
5
+
6
+ class StackRecorder < BlankSlate
7
+ attr_reader :__target
8
+
9
+ def initialize(target)
10
+ @__target = target
11
+ @__methods = []
12
+ end
13
+
14
+ def __meth(index)
15
+ @__methods[index]
16
+ end
17
+
18
+ def __each_called
19
+ @__methods.each { |meth| yield [meth[:name], meth[:args]] }
20
+ end
21
+
22
+ def __last_value
23
+ @__methods.last[:args].first
24
+ end
25
+
26
+ def method_missing(method_name, *args)
27
+ @__methods << {
28
+ :name => method_name,
29
+ :args => args
30
+ }
31
+ return self
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,50 @@
1
+ module Funktional
2
+ class EmailAssertion < Funktional::Assertion
3
+ def initialize(expectations)
4
+ if ActionMailer::Base.deliveries.size < 1
5
+ flunk 'No emails have been sent'
6
+ end
7
+
8
+ email = ActionMailer::Base.deliveries.last
9
+
10
+ expectations.each_key do |key|
11
+ case key
12
+ when :from
13
+ then check_from(expectations[:from], email.from)
14
+ when :to
15
+ then check_to(expectations[:to], email.to)
16
+ when :subject
17
+ then assert_equal expectations[:subject], email.subject
18
+ when :containing
19
+ then check_containing(expectations[:containing], email.body)
20
+ else
21
+ flunk "Assertion key: [#{key}] not recognised"
22
+ end
23
+ end
24
+ end
25
+
26
+ def check_from(expected_from, email_from)
27
+ if email_from.nil?
28
+ flunk 'email is missing a [from]'
29
+ end
30
+ assert_equal expected_from, email_from[0]
31
+ end
32
+
33
+ def check_to(expected_to, email_to)
34
+ if email_to.nil?
35
+ flunk 'email is missing a [to]'
36
+ end
37
+ assert_equal expected_to, email_to[0]
38
+ end
39
+
40
+ def check_containing(should_contain, body)
41
+ if should_contain.is_a? Array
42
+ should_contain.each do |should_i|
43
+ assert_match /#{Regexp.escape(should_i)}/, body
44
+ end
45
+ else
46
+ assert_match /#{Regexp.escape(should_contain)}/, body
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,12 @@
1
+ module Funktional
2
+ class FlashedAssertion < Funktional::Assertion
3
+ def initialize(symbol)
4
+ @symbol = symbol
5
+ end
6
+
7
+ def should_be(expected_value)
8
+ assert_not_nil flash[@symbol], "Flash is empty [#{expected_value}] expected."
9
+ assert_equal expected_value, flash[@symbol]
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,108 @@
1
+ module Funktional
2
+ module ModelAssertions
3
+ def should_require_a(field, expected_error_message = nil)
4
+ check_test_instance!
5
+ must_be_valid_before_test!
6
+
7
+ assign_nil_to(field, expected_error_message) do
8
+ assert_invalid("'#{self.class.name}' should require a '#{field}'")
9
+ end
10
+ end
11
+
12
+ alias :should_require_an :should_require_a
13
+
14
+ def should_not_require_a(field)
15
+ check_test_instance!
16
+
17
+ assign_nil_to(field) do
18
+ assert_valid
19
+ end
20
+ end
21
+
22
+ alias :should_not_require_an :should_not_require_a
23
+
24
+ def should_have_invalid(field, expected_error_message = nil)
25
+ check_test_instance!
26
+
27
+ assert_invalid("'#{self.class.name}' should have invalid '#{field}'")
28
+ assert_message(field, expected_error_message) if expected_error_message
29
+ end
30
+
31
+ def should_mass_assign(*fields)
32
+ check_test_instance!
33
+ fields.each do |field|
34
+ Funktional.test_instance.assert self.class.accessible_attributes.include?(field.to_s)
35
+ end
36
+ end
37
+
38
+ def should_not_mass_assign(*fields)
39
+ check_test_instance!
40
+ accessible_attrib = self.class.accessible_attributes.to_a
41
+ protected_attrib = self.class.protected_attributes.to_a
42
+ fields = fields.map(&:to_s)
43
+
44
+ if accessible_attrib.any?
45
+ common_fields = (accessible_attrib & fields)
46
+ @test.assert((common_fields.size == 0), "#{common_fields.inspect} marked accessible")
47
+ elsif protected_attrib.any?
48
+ common_fields = (protected_attrib & fields)
49
+ difference = (fields - protected_attrib)
50
+ @test.assert((common_fields.size == fields.size), "#{difference.inspect} not protected")
51
+ else
52
+ @test.flunk "#{fields.inspect} not protected"
53
+ end
54
+ end
55
+
56
+ def should_protect(*fields)
57
+ check_test_instance!
58
+ fields.each do |field|
59
+ Funktional.test_instance.assert self.class.protected_attributes.include?(field.to_s)
60
+ end
61
+ end
62
+
63
+ def should_respond_to(method)
64
+ Funktional.test_instance.assert_respond_to self, method
65
+ end
66
+
67
+ private
68
+
69
+ def assign_nil_to(field, expected_error_message = nil)
70
+ saved_existing_value = self.send field
71
+ self.send "#{field}=", nil
72
+
73
+ yield
74
+
75
+ assert_message(field, expected_error_message) if expected_error_message
76
+ self.send "#{field}=", saved_existing_value
77
+
78
+ # clear errors
79
+ self.valid?
80
+ end
81
+
82
+ def assert_invalid(message)
83
+ Funktional.test_instance.assert self.invalid?, message
84
+ end
85
+
86
+ def assert_valid
87
+ Funktional.test_instance.assert self.valid?
88
+ end
89
+
90
+ def assert_message(field, expected_error_message)
91
+ Funktional.test_instance.assert_equal(expected_error_message, self.errors[field])
92
+ end
93
+
94
+ def must_be_valid_before_test!
95
+ if self.invalid?
96
+ error = "Funktional requires a valid instance of #{self.class.name}"
97
+ Funktional.test_instance.flunk error
98
+ end
99
+ end
100
+
101
+ def check_test_instance!
102
+ if Funktional.test_instance.nil?
103
+ raise Funktional::Setup::Error, 'Did you forget to (setup :funktional) in test/test_helper?'
104
+ end
105
+ @test = Funktional.test_instance
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,11 @@
1
+ module Funktional
2
+ module RandomCharacters
3
+ def random_characters
4
+ chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'
5
+ str = ''
6
+ self.times { str << chars[rand(chars.size)] }
7
+
8
+ return str
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+ module Funktional
2
+ class RecursiveAssertion < Funktional::Assertion
3
+ def initialize(assigned, method)
4
+ @test = Funktional.test_instance
5
+ @assigned = assigned
6
+ @method = method
7
+
8
+ @test.assert_respond_to @assigned, @method
9
+ end
10
+
11
+ def should_be(expected_value)
12
+ value = @assigned.send @method
13
+ @test.assert_equal expected_value, value
14
+ end
15
+
16
+ protected
17
+
18
+ def method_missing(method, *args)
19
+ @assigned = @assigned.send @method
20
+ RecursiveAssertion.new(@assigned, method)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,49 @@
1
+ module Funktional
2
+
3
+ class RouteChecker
4
+ instance_methods.each do |method|
5
+ undef_method(method) unless %w(__send__ __id__ instance_eval).include?(method)
6
+ end
7
+
8
+ attr_reader :__path_and_method, :__controller_action_etc
9
+
10
+ def self.build(params, &blk)
11
+ checker = self.new(params)
12
+
13
+ checker.instance_eval(&blk)
14
+ return checker
15
+ end
16
+
17
+ def initialize(params)
18
+ @__path_and_method = __get_path_and_method(params)
19
+ @__controller_action_etc = {}
20
+ end
21
+
22
+ def __test_name
23
+ path = @__path_and_method[:path]
24
+ method = @__path_and_method[:method]
25
+
26
+ "route '#{path}' :method '#{method}' to #{@__controller_action_etc.inspect}"
27
+ end
28
+
29
+ def method_missing(method_name, value)
30
+ @__controller_action_etc[method_name] = value
31
+ end
32
+
33
+ private
34
+
35
+ def __get_path_and_method(params)
36
+ if params.is_a? Hash
37
+ {
38
+ :path => params[:route],
39
+ :method => params[:method].to_sym
40
+ }
41
+ else
42
+ {
43
+ :path => params,
44
+ :method => :get
45
+ }
46
+ end
47
+ end
48
+ end
49
+ end