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
|
# frozen_string_literal: true
require 'set'
module ActiveModelSerializers
module Test
module Serializer
extend ActiveSupport::Concern
included do
setup :setup_serialization_subscriptions
teardown :teardown_serialization_subscriptions
end
# Asserts that the request was rendered with the appropriate serializers.
#
# # assert that the "PostSerializer" serializer was rendered
# assert_serializer "PostSerializer"
#
# # return a custom error message
# assert_serializer "PostSerializer", "PostSerializer not rendered"
#
# # assert that the instance of PostSerializer was rendered
# assert_serializer PostSerializer
#
# # assert that the "PostSerializer" serializer was rendered
# assert_serializer :post_serializer
#
# # assert that the rendered serializer starts with "Post"
# assert_serializer %r{\APost.+\Z}
#
# # assert that no serializer was rendered
# assert_serializer nil
#
def assert_serializer(expectation, message = nil)
@assert_serializer.expectation = expectation
@assert_serializer.message = message
@assert_serializer.response = response
assert(@assert_serializer.matches?, @assert_serializer.message)
end
class AssertSerializer
attr_reader :serializers, :message
attr_accessor :response, :expectation
def initialize
@serializers = Set.new
@_subscribers = []
end
def message=(message)
@message = message || "expecting <#{expectation.inspect}> but rendering with <#{serializers.to_a}>"
end
def matches?
# Force body to be read in case the template is being streamed.
response.body
case expectation
when a_serializer? then matches_class?
when Symbol then matches_symbol?
when String then matches_string?
when Regexp then matches_regexp?
when NilClass then matches_nil?
else fail ArgumentError, 'assert_serializer only accepts a String, Symbol, Regexp, ActiveModel::Serializer, or nil'
end
end
def subscribe
@_subscribers << ActiveSupport::Notifications.subscribe(event_name) do |_name, _start, _finish, _id, payload|
serializer = payload[:serializer].name
serializers << serializer
end
end
def unsubscribe
@_subscribers.each do |subscriber|
ActiveSupport::Notifications.unsubscribe(subscriber)
end
end
private
def matches_class?
serializers.include?(expectation.name)
end
def matches_symbol?
camelize_expectation = expectation.to_s.camelize
serializers.include?(camelize_expectation)
end
def matches_string?
!expectation.empty? && serializers.include?(expectation)
end
def matches_regexp?
serializers.any? do |serializer|
serializer.match(expectation)
end
end
def matches_nil?
serializers.empty?
end
def a_serializer?
->(exp) { exp.is_a?(Class) && exp < ActiveModel::Serializer }
end
def event_name
::ActiveModelSerializers::Logging::RENDER_EVENT
end
end
private
def setup_serialization_subscriptions
@assert_serializer = AssertSerializer.new
@assert_serializer.subscribe
end
def teardown_serialization_subscriptions
@assert_serializer.unsubscribe
end
end
end
end
|