Module: ActiveLoaders::Test

Defined in:
lib/active_loaders/test.rb

Constant Summary collapse

Error =
Class.new(StandardError)

Instance Method Summary collapse

Instance Method Details

#assert_all_serializers_tested(namespace = nil) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/active_loaders/test.rb', line 51

def assert_all_serializers_tested(namespace = nil)
  descendants =
    ObjectSpace.each_object(Class)
    .select { |klass| klass < ActiveModel::Serializer }
    .select { |klass| (namespace.nil? && !klass.name.include?("::")) || klass.name.starts_with?("#{namespace}::") }
    .reject { |klass| Array(@active_loaders_tested_serializers).include?(klass) }

  unless descendants.empty?
    fail Error, "serializers not tested: #{descendants.map(&:name).join(", ")}"
  end
end

#test_serializer_queries(serializer_klass, model_klass, ignore_columns: [], skip_columns_check: false, allow_queries_per_record: 0) ⇒ Object



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
# File 'lib/active_loaders/test.rb', line 6

def test_serializer_queries(serializer_klass, model_klass, ignore_columns: [], skip_columns_check: false, allow_queries_per_record: 0)
  records = get_all_records(model_klass, serializer_klass)
  fail "Not enough records to test #{serializer_klass}. Create at least 1 #{model_klass}." unless records.size > 0

  records.each do |record|
    queries = get_executed_queries do
      serializer_klass.new(record).as_json
    end

    unless queries.size == allow_queries_per_record
      fail Error, "unexpected queries\n\nRecord:\n#{record.inspect}\n\nQueries:\n#{queries.join("\n")}"
    end
  end

  # just for good measure
  queries = get_executed_queries do
    ActiveModel::ArraySerializer.new(records, each_serializer: serializer_klass).as_json
  end
  unless queries.size == (records.size * allow_queries_per_record)
    fail Error, "unexpected queries when using ArraySerializer\n\nModel:\n#{model_klass}\n\nQueries:\n#{queries.join("\n")}"
  end

  # select values (if supported)
  # TODO: Sequel?
  unless skip_columns_check
    if defined?(ActiveRecord::Base) && model_klass.ancestors.include?(ActiveRecord::Base)
      if records.first.respond_to?(:accessed_fields)
        accessed_fields = Set.new
        records.each { |record| accessed_fields.merge(record.accessed_fields) }

        unaccessed_columns = model_klass.column_names - accessed_fields.to_a - ignore_columns.map(&:to_s)

        unless unaccessed_columns.empty?
          unaccessed_columns_str = unaccessed_columns.join(", ")
          unaccessed_columns_syms = unaccessed_columns.map { |c| ":#{c}" }.join(", ")
          all_unaccessed_columns_syms = (ignore_columns.map(&:to_s) + unaccessed_columns).map { |c| ":#{c}" }.join(", ")
          fail Error, "unnecessary select for #{model_klass} columns: #{unaccessed_columns_str}\n\nAdd to #{serializer_klass} loaders block:\n  skip_select #{unaccessed_columns_syms}\n\nOr ignore this error with:\n  test_serializer_queries(#{serializer_klass}, #{model_klass}, ignore_columns: [#{all_unaccessed_columns_syms}])\n\nOr skip this columns check entirely:\n  test_serializer_queries(#{serializer_klass}, #{model_klass}, skip_columns_check: true)"
        end
      end
    end
  end

  (@active_loaders_tested_serializers ||= Set.new).add(serializer_klass)
end