File: stub.rb

package info (click to toggle)
ruby-factory-bot 6.5.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,372 kB
  • sloc: ruby: 7,827; makefile: 6
file content (127 lines) | stat: -rw-r--r-- 3,276 bytes parent folder | download
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
124
125
126
127
module FactoryBot
  module Strategy
    class Stub
      @@next_id = 1000

      DISABLED_PERSISTENCE_METHODS = [
        :connection,
        :decrement!,
        :delete,
        :destroy!,
        :destroy,
        :increment!,
        :reload,
        :save!,
        :save,
        :toggle!,
        :touch,
        :update!,
        :update,
        :update_attribute,
        :update_attributes!,
        :update_attributes,
        :update_column,
        :update_columns
      ].freeze

      def self.next_id=(id)
        @@next_id = id
      end

      def association(runner)
        runner.run(:build_stubbed)
      end

      def result(evaluation)
        evaluation.object.tap do |instance|
          stub_database_interaction_on_result(instance)
          set_timestamps(instance)
          clear_changes_information(instance)
          evaluation.notify(:after_stub, instance)
        end
      end

      def to_sym
        :stub
      end

      private

      def next_id(result_instance)
        if uuid_primary_key?(result_instance)
          SecureRandom.uuid
        else
          @@next_id += 1
        end
      end

      def stub_database_interaction_on_result(result_instance)
        if has_settable_id?(result_instance)
          result_instance.id ||= next_id(result_instance)
        end

        result_instance.instance_eval do
          def persisted?
            true
          end

          def new_record?
            false
          end

          def destroyed?
            false
          end

          DISABLED_PERSISTENCE_METHODS.each do |write_method|
            define_singleton_method(write_method) do |*args|
              raise "stubbed models are not allowed to access the database - " \
                    "#{self.class}##{write_method}(#{args.join(",")})"
            end
          end
        end
      end

      def has_settable_id?(result_instance)
        result_instance.respond_to?(:id=) &&
          (!result_instance.class.respond_to?(:primary_key) ||
          result_instance.class.primary_key)
      end

      def uuid_primary_key?(result_instance)
        result_instance.respond_to?(:column_for_attribute) &&
          (column = result_instance.column_for_attribute(result_instance.class.primary_key)) &&
          column.respond_to?(:sql_type) &&
          column.sql_type == "uuid"
      end

      def clear_changes_information(result_instance)
        if result_instance.respond_to?(:clear_changes_information)
          result_instance.clear_changes_information
        end
      end

      def set_timestamps(result_instance)
        if missing_created_at?(result_instance)
          result_instance.created_at = Time.current
        end

        if missing_updated_at?(result_instance)
          result_instance.updated_at = Time.current
        end
      end

      def missing_created_at?(result_instance)
        result_instance.respond_to?(:created_at) &&
          result_instance.respond_to?(:created_at=) &&
          result_instance.created_at.blank?
      end

      def missing_updated_at?(result_instance)
        result_instance.respond_to?(:updated_at) &&
          result_instance.respond_to?(:updated_at=) &&
          result_instance.updated_at.blank?
      end
    end
  end
end