@@ -557,12 +557,15 @@ defmodule Phoenix.ChannelTest do
557557 assert_push "some_event", expected_payload
558558 # The code above does not assert the payload matches the described map.
559559
560+ Guards can also be given to the payload pattern:
561+
562+ assert_push "some_event", %{"counter" => c} when c > 0
560563 """
561564 defmacro assert_push ( event , payload , timeout \\ Application . fetch_env! ( :ex_unit , :assert_receive_timeout ) ) do
565+ pattern = extract_pattern_and_apply_guard ( event , payload , Phoenix.Socket.Message )
566+
562567 quote do
563- assert_receive % Phoenix.Socket.Message {
564- event: unquote ( event ) ,
565- payload: unquote ( payload ) } , unquote ( timeout )
568+ assert_receive unquote ( pattern ) , unquote ( timeout )
566569 end
567570 end
568571
@@ -579,6 +582,7 @@ defmodule Phoenix.ChannelTest do
579582 will certainly slow down your test suite.
580583 """
581584 defmacro refute_push ( event , payload , timeout \\ Application . fetch_env! ( :ex_unit , :refute_receive_timeout ) ) do
585+
582586 quote do
583587 refute_receive % Phoenix.Socket.Message {
584588 event: unquote ( event ) ,
@@ -600,14 +604,27 @@ defmodule Phoenix.ChannelTest do
600604
601605 The timeout is in milliseconds and defaults to the `:assert_receive_timeout`
602606 set on the `:ex_unit` application (which defaults to 100ms).
607+
608+ Guards can also be given to the payload pattern:
609+
610+ ref = push(channel, "some_event")
611+ assert_reply ref, :ok, %{"counter" => c} when c > 0
603612 """
604613 defmacro assert_reply ( ref , status , payload \\ Macro . escape ( % { } ) , timeout \\ Application . fetch_env! ( :ex_unit , :assert_receive_timeout ) ) do
605- quote do
606- ref = unquote ( ref )
607- assert_receive % Phoenix.Socket.Reply {
614+ { payload , guard } = extract_guard ( payload )
615+
616+ pattern = quote do
617+ % Phoenix.Socket.Reply {
608618 ref: ^ ref ,
609619 status: unquote ( status ) ,
610- payload: unquote ( payload ) } , unquote ( timeout )
620+ payload: unquote ( payload ) }
621+ end
622+
623+ struct_pattern = apply_guard ( pattern , guard )
624+
625+ quote do
626+ ref = unquote ( ref )
627+ assert_receive unquote ( struct_pattern ) , unquote ( timeout )
611628 end
612629 end
613630
@@ -650,11 +667,16 @@ defmodule Phoenix.ChannelTest do
650667
651668 The timeout is in milliseconds and defaults to the `:assert_receive_timeout`
652669 set on the `:ex_unit` application (which defaults to 100ms).
670+
671+ Guards can also be given to the payload pattern:
672+
673+ assert_broadcast "some_event", %{"counter" => c} when c > 0
653674 """
654675 defmacro assert_broadcast ( event , payload , timeout \\ Application . fetch_env! ( :ex_unit , :assert_receive_timeout ) ) do
676+ pattern = extract_pattern_and_apply_guard ( event , payload , Phoenix.Socket.Broadcast )
677+
655678 quote do
656- assert_receive % Phoenix.Socket.Broadcast { event: unquote ( event ) ,
657- payload: unquote ( payload ) } , unquote ( timeout )
679+ assert_receive unquote ( pattern ) , unquote ( timeout )
658680 end
659681 end
660682
@@ -695,6 +717,22 @@ defmodule Phoenix.ChannelTest do
695717 end
696718 end
697719
720+ defp extract_guard ( { :when , _ , [ payload , guard ] } ) , do: { payload , guard }
721+ defp extract_guard ( payload ) , do: { payload , nil }
722+
723+ defp apply_guard ( pattern , nil ) , do: pattern
724+ defp apply_guard ( pattern , guard ) , do: { :when , [ ] , [ pattern , guard ] }
725+
726+ defp extract_pattern_and_apply_guard ( event , payload , struct_module ) do
727+ { payload , guard } = extract_guard ( payload )
728+
729+ pattern_struct = quote do
730+ % { __struct__: unquote ( struct_module ) , event: unquote ( event ) , payload: unquote ( payload ) }
731+ end
732+
733+ apply_guard ( pattern_struct , guard )
734+ end
735+
698736 @ doc false
699737 def __stringify__ ( % { __struct__: _ } = struct ) ,
700738 do: struct
0 commit comments