aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/rails/generators/testing/assertions.rb
blob: 14fd4efd4ef21319cf87a54177868d063a95d616 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
module Rails
  module Generators
    module Testing
      module Assertions
        METHOD_DECLARATION_REGEXP = /(\s+)def #{method}(\(.+\))?(.*?)\n\1end/m

        # Asserts a given file exists. You need to supply an absolute path or a path relative
        # to the configured destination:
        #
        #   assert_file "config/environment.rb"
        #
        # You can also give extra arguments. If the argument is a regexp, it will check if the
        # regular expression matches the given file content. If it's a string, it compares the
        # file with the given string:
        #
        #   assert_file "config/environment.rb", /initialize/
        #
        # Finally, when a block is given, it yields the file content:
        #
        #   assert_file "app/controllers/products_controller.rb" do |controller|
        #     assert_instance_method :index, controller do |index|
        #       assert_match(/Product\.all/, index)
        #     end
        #   end
        def assert_file(relative, *contents)
          absolute = File.expand_path(relative, destination_root)
          assert File.exists?(absolute), "Expected file #{relative.inspect} to exist, but does not"

          read = File.read(absolute) if block_given? || !contents.empty?
          yield read if block_given?

          contents.each do |content|
            case content
              when String
                assert_equal content, read
              when Regexp
                assert_match content, read
            end
          end
        end
        alias :assert_directory :assert_file

        # Asserts a given file does not exist. You need to supply an absolute path or a
        # path relative to the configured destination:
        #
        #   assert_no_file "config/random.rb"
        def assert_no_file(relative)
          absolute = File.expand_path(relative, destination_root)
          assert !File.exists?(absolute), "Expected file #{relative.inspect} to not exist, but does"
        end
        alias :assert_no_directory :assert_no_file

        # Asserts a given migration exists. You need to supply an absolute path or a
        # path relative to the configured destination:
        #
        #   assert_migration "db/migrate/create_products.rb"
        #
        # This method manipulates the given path and tries to find any migration which
        # matches the migration name. For example, the call above is converted to:
        #
        #   assert_file "db/migrate/003_create_products.rb"
        #
        # Consequently, assert_migration accepts the same arguments has assert_file.
        def assert_migration(relative, *contents, &block)
          file_name = migration_file_name(relative)
          assert file_name, "Expected migration #{relative} to exist, but was not found"
          assert_file file_name, *contents, &block
        end

        # Asserts a given migration does not exist. You need to supply an absolute path or a
        # path relative to the configured destination:
        #
        #   assert_no_migration "db/migrate/create_products.rb"
        def assert_no_migration(relative)
          file_name = migration_file_name(relative)
          assert_nil file_name, "Expected migration #{relative} to not exist, but found #{file_name}"
        end

        # Asserts the given class method exists in the given content. This method does not detect
        # class methods inside (class << self), only class methods which starts with "self.".
        # When a block is given, it yields the content of the method.
        #
        #   assert_migration "db/migrate/create_products.rb" do |migration|
        #     assert_class_method :up, migration do |up|
        #       assert_match(/create_table/, up)
        #     end
        #   end
        def assert_class_method(method, content, &block)
          assert_instance_method "self.#{method}", content, &block
        end

        # Asserts the given method exists in the given content. When a block is given,
        # it yields the content of the method.
        #
        #   assert_file "app/controllers/products_controller.rb" do |controller|
        #     assert_instance_method :index, controller do |index|
        #       assert_match(/Product\.all/, index)
        #     end
        #   end
        def assert_instance_method(method, content)
          assert content =~ METHOD_DECLARATION_REGEXP, "Expected to have method #{method}"
          yield $3.strip if block_given?
        end
        alias :assert_method :assert_instance_method

        # Asserts the given attribute type gets translated to a field type
        # properly:
        #
        #   assert_field_type :date, :date_select
        def assert_field_type(attribute_type, field_type)
          assert_equal(field_type, create_generated_attribute(attribute_type).field_type)
        end

        # Asserts the given attribute type gets a proper default value:
        #
        #   assert_field_default_value :string, "MyString"
        def assert_field_default_value(attribute_type, value)
          assert_equal(value, create_generated_attribute(attribute_type).default)
        end
      end
    end
  end
end