@@ -12,49 +12,125 @@ defmodule Firenest.PGTest do
1212 { :ok , pg: test }
1313 end
1414
15- test "tracks processes" , % { pg: pg } do
16- PG . track ( pg , self ( ) , :foo , :bar , :baz )
17- assert [ { :bar , :baz } ] == PG . list ( pg , :foo )
15+ describe "join/5" do
16+ test "adds process" , % { pg: pg } do
17+ assert PG . join ( pg , :foo , :bar , self ( ) , :baz ) == :ok
18+ assert [ { :bar , :baz } ] == PG . members ( pg , :foo )
19+ end
20+
21+ test "rejects double joins" , % { pg: pg } do
22+ assert PG . join ( pg , :foo , :bar , self ( ) , :baz ) == :ok
23+ assert PG . join ( pg , :foo , :bar , self ( ) , :baz ) == { :error , :already_joined }
24+ end
25+
26+ test "cleans up entries after process dies" , % { pg: pg } do
27+ { pid , ref } = spawn_monitor ( Process , :sleep , [ :infinity ] )
28+ PG . join ( pg , :foo , :bar , pid , :baz )
29+ assert [ _ ] = PG . members ( pg , :foo )
30+ Process . exit ( pid , :kill )
31+ assert_receive { :DOWN , ^ ref , _ , _ , _ }
32+ assert [ ] = PG . members ( pg , :foo )
33+ end
34+
35+ test "pg dies if other linked process dies" , % { pg: pg } do
36+ parent = self ( )
37+ [ { _ , pid , _ , _ } ] = Supervisor . which_children ( Module . concat ( pg , "Supervisor" ) )
38+ ref = Process . monitor ( pid )
39+
40+ temp =
41+ spawn ( fn ->
42+ Process . link ( pid )
43+ send ( parent , :continue )
44+ Process . sleep ( :infinity )
45+ end )
46+
47+ assert_receive :continue
48+
49+ Process . exit ( temp , :shutdown )
50+ assert_receive { :DOWN , ^ ref , _ , _ , _ }
51+ end
1852 end
1953
20- test "processes are clened up when they die" , % { pg: pg } do
21- { pid , ref } = spawn_monitor ( Process , :sleep , [ :infinity ] )
22- PG . track ( pg , pid , :foo , :bar , :baz )
23- assert [ _ ] = PG . list ( pg , :foo )
24- Process . exit ( pid , :kill )
25- assert_receive { :DOWN , ^ ref , _ , _ , _ }
26- assert [ ] = PG . list ( pg , :foo )
54+ describe "leave/2" do
55+ test "removes entry" , % { pg: pg } do
56+ PG . join ( pg , :foo , :bar , self ( ) , :baz )
57+
58+ assert [ _ ] = PG . members ( pg , :foo )
59+ assert PG . leave ( pg , self ( ) ) == :ok
60+ assert [ ] == PG . members ( pg , :foo )
61+ end
62+
63+ test "does not remove non members" , % { pg: pg } do
64+ [ { _ , pid , _ , _ } ] = Supervisor . which_children ( Module . concat ( pg , "Supervisor" ) )
65+ Process . link ( pid )
66+
67+ assert PG . leave ( pg , self ( ) ) == { :error , :not_member }
68+ { :links , links } = Process . info ( self ( ) , :links )
69+ assert pid in links
70+ end
2771 end
2872
29- test "pg dies if linked, untracked process terminates" , % { pg: pg } do
30- parent = self ( )
31- [ { _ , pid , _ , _ } ] = Supervisor . which_children ( Module . concat ( pg , "Supervisor" ) )
32- ref = Process . monitor ( pid )
73+ describe "leave/4" do
74+ test "removes single entry" , % { pg: pg } do
75+ PG . join ( pg , :foo , :bar , self ( ) , :baz )
76+ assert [ _ ] = PG . members ( pg , :foo )
77+
78+ assert PG . leave ( pg , :foo , :bar , self ( ) ) == :ok
79+ assert [ ] == PG . members ( pg , :foo )
80+ end
3381
34- temp =
35- spawn ( fn ->
36- Process . link ( pid )
37- send ( parent , :continue )
38- Process . sleep ( :infinity )
39- end )
82+ test "leaves other entries intact" , % { pg: pg } do
83+ PG . join ( pg , :foo , :bar , self ( ) , :baz )
84+ PG . join ( pg , :foo , :baar , self ( ) , :baz )
85+ assert [ _ , _ ] = PG . members ( pg , :foo )
4086
41- assert_receive :continue
87+ assert PG . leave ( pg , :foo , :bar , self ( ) ) == :ok
88+ assert [ { :baar , :baz } ] == PG . members ( pg , :foo )
89+ end
4290
43- Process . exit ( temp , :shutdown )
44- assert_receive { :DOWN , ^ ref , _ , _ , _ }
91+ test "does not remove non members" , % { pg: pg } do
92+ [ { _ , pid , _ , _ } ] = Supervisor . which_children ( Module . concat ( pg , "Supervisor" ) )
93+ Process . link ( pid )
94+
95+ assert PG . leave ( pg , :foo , :bar , self ( ) ) == { :error , :not_member }
96+ { :links , links } = Process . info ( self ( ) , :links )
97+ assert pid in links
98+ end
4599 end
46100
47- test "untrack/2" , % { pg: pg } do
48- PG . track ( pg , self ( ) , :foo , :bar , :baz )
49- assert [ _ ] = PG . list ( pg , :foo )
50- PG . untrack ( pg , self ( ) )
51- assert [ ] == PG . list ( pg , :foo )
101+ describe "update/5" do
102+ test "executes the update if entry is present" , % { pg: pg } do
103+ parent = self ( )
104+ PG . join ( pg , :foo , :bar , self ( ) , 1 )
105+ assert [ { :bar , 1 } ] == PG . members ( pg , :foo )
106+
107+ update = fn value ->
108+ send ( parent , value )
109+ value + 1
110+ end
111+
112+ assert PG . update ( pg , :foo , :bar , self ( ) , update ) == :ok
113+ assert_received 1
114+ assert [ { :bar , 2 } ] == PG . members ( pg , :foo )
115+ end
116+
117+ test "does not execute update if entry is absent" , % { pg: pg } do
118+ parent = self ( )
119+ update = fn value -> Process . exit ( parent , { :unexpected_update , value } ) end
120+ assert PG . update ( pg , :foo , :bar , self ( ) , update ) == { :error , :not_member }
121+ end
52122 end
53123
54- test "untrack/4" , % { pg: pg } do
55- PG . track ( pg , self ( ) , :foo , :bar , :baz )
56- assert [ _ ] = PG . list ( pg , :foo )
57- PG . untrack ( pg , self ( ) , :foo , :bar )
58- assert [ ] == PG . list ( pg , :foo )
124+ describe "replace/5" do
125+ test "updates value if entry is present" , % { pg: pg } do
126+ PG . join ( pg , :foo , :bar , self ( ) , 1 )
127+ assert [ { :bar , 1 } ] == PG . members ( pg , :foo )
128+ assert PG . replace ( pg , :foo , :bar , self ( ) , 2 ) == :ok
129+ assert [ { :bar , 2 } ] == PG . members ( pg , :foo )
130+ end
131+
132+ test "does not update value if entry is absent" , % { pg: pg } do
133+ assert PG . replace ( pg , :foo , :bar , self ( ) , 2 ) == { :error , :not_member }
134+ end
59135 end
60136end
0 commit comments