@@ -1110,7 +1110,7 @@ def test_enable
11101110 end
11111111 end
11121112
1113- def test_responses
1113+ test "#responses" do
11141114 with_fake_server do |server , imap |
11151115 # responses available before SELECT/EXAMINE
11161116 assert_equal ( %w[ IMAP4REV1 NAMESPACE MOVE IDLE UTF8=ACCEPT ] ,
@@ -1144,7 +1144,7 @@ def test_responses
11441144 end
11451145 end
11461146
1147- def test_clear_responses
1147+ test "#clear_responses" do
11481148 with_fake_server do |server , imap |
11491149 resp = imap . select "INBOX"
11501150 assert_equal ( [ Net ::IMAP ::TaggedResponse , "RUBY0001" , "OK" ] ,
@@ -1168,6 +1168,49 @@ def test_clear_responses
11681168 end
11691169 end
11701170
1171+ test "#extract_responses" do
1172+ with_fake_server do |server , imap |
1173+ resp = imap . select "INBOX"
1174+ assert_equal ( [ Net ::IMAP ::TaggedResponse , "RUBY0001" , "OK" ] ,
1175+ [ resp . class , resp . tag , resp . name ] )
1176+ # Need to send a string type and a block
1177+ assert_raise ( ArgumentError ) do imap . extract_responses { true } end
1178+ assert_raise ( ArgumentError ) do imap . extract_responses ( nil ) { true } end
1179+ assert_raise ( ArgumentError ) do imap . extract_responses ( "OK" ) end
1180+ # matching nothing
1181+ assert_equal ( [ 172 ] , imap . responses ( "EXISTS" , &:dup ) )
1182+ assert_equal ( [ ] , imap . extract_responses ( "EXISTS" ) { String === _1 } )
1183+ assert_equal ( [ 172 ] , imap . responses ( "EXISTS" , &:dup ) )
1184+ # matching everything
1185+ assert_equal ( [ 172 ] , imap . responses ( "EXISTS" , &:dup ) )
1186+ assert_equal ( [ 172 ] , imap . extract_responses ( "EXISTS" , &:even? ) )
1187+ assert_equal ( [ ] , imap . responses ( "EXISTS" , &:dup ) )
1188+ # matching some
1189+ server . unsolicited ( "101 FETCH (UID 1111 FLAGS (\\ Seen))" )
1190+ server . unsolicited ( "102 FETCH (UID 2222 FLAGS (\\ Seen \\ Flagged))" )
1191+ server . unsolicited ( "103 FETCH (UID 3333 FLAGS (\\ Deleted))" )
1192+ wait_for_response_count ( imap , type : "FETCH" , count : 3 )
1193+
1194+ result = imap . extract_responses ( "FETCH" ) { _1 . flags . include? ( :Flagged ) }
1195+ assert_equal (
1196+ [
1197+ Net ::IMAP ::FetchData . new (
1198+ 102 , { "UID" => 2222 , "FLAGS" => [ :Seen , :Flagged ] }
1199+ ) ,
1200+ ] ,
1201+ result ,
1202+ )
1203+ assert_equal 2 , imap . responses ( "FETCH" , &:count )
1204+
1205+ result = imap . extract_responses ( "FETCH" ) { _1 . flags . include? ( :Deleted ) }
1206+ assert_equal (
1207+ [ Net ::IMAP ::FetchData . new ( 103 , { "UID" => 3333 , "FLAGS" => [ :Deleted ] } ) ] ,
1208+ result
1209+ )
1210+ assert_equal 1 , imap . responses ( "FETCH" , &:count )
1211+ end
1212+ end
1213+
11711214 test "#select with condstore" do
11721215 with_fake_server do |server , imap |
11731216 imap . select "inbox" , condstore : true
@@ -1423,4 +1466,16 @@ def create_tcp_server
14231466 def server_addr
14241467 Addrinfo . tcp ( "localhost" , 0 ) . ip_address
14251468 end
1469+
1470+ def wait_for_response_count ( imap , type :, count :,
1471+ timeout : 0.5 , interval : 0.001 )
1472+ deadline = Time . now + timeout
1473+ loop do
1474+ current_count = imap . responses ( type , &:size )
1475+ break :count if count <= current_count
1476+ break :deadline if deadline < Time . now
1477+ sleep interval
1478+ end
1479+ end
1480+
14261481end
0 commit comments