@@ -80,6 +80,73 @@ def test_write_creates_item(self, api_write_mock, *_):
8080 self .assertEqual ('item' , kwargs .get ('new' ))
8181 self .assertIn ('data' , kwargs )
8282
83+ class Merge (unittest .TestCase ):
84+
85+ def setUp (self ):
86+ self .item = wdpy .Item ('Q1' )
87+ self .item ._loaded = True
88+
89+ def _s (self , val = 'Q5' , prop = 'P31' ):
90+ return wdpy .Statement (wdpy .Snak (prop , (val ,)))
91+
92+ # ── insert ────────────────────────────────────────────────────────────────
93+
94+ def test_new_property_bucket_created (self ):
95+ s = self ._s ()
96+ self .item .merge (s )
97+ self .assertIn ('P31' , self .item .claims )
98+
99+ def test_new_statement_appended (self ):
100+ s = self ._s ()
101+ result = self .item .merge (s )
102+ self .assertIn (s , self .item .claims ['P31' ])
103+ self .assertIs (result , s )
104+
105+ def test_id_assigned_when_qid_known (self ):
106+ self .item .merge (self ._s ())
107+ self .assertTrue (self .item .claims ['P31' ][0 ].id .startswith ('Q1$' ))
108+
109+ def test_no_id_assigned_without_qid (self ):
110+ self .item .qid = None
111+ s = self ._s ()
112+ self .item .merge (s )
113+ self .assertIsNone (s .id )
114+
115+ def test_second_distinct_value_also_inserted (self ):
116+ self .item .merge (self ._s ('Q5' ))
117+ self .item .merge (self ._s ('Q6' ))
118+ self .assertEqual (len (self .item .claims ['P31' ]), 2 )
119+
120+ def test_multiple_properties_independent (self ):
121+ self .item .merge (self ._s ('Q5' , 'P31' ))
122+ self .item .merge (self ._s ('Q5' , 'P21' ))
123+ self .assertEqual (len (self .item .claims ['P31' ]), 1 )
124+ self .assertEqual (len (self .item .claims ['P21' ]), 1 )
125+
126+ # ── upsert ────────────────────────────────────────────────────────────────
127+
128+ def test_duplicate_returns_existing (self ):
129+ existing = self ._s ()
130+ self .item .claims ['P31' ] = [existing ]
131+ result = self .item .merge (self ._s ())
132+ self .assertIs (result , existing )
133+ self .assertEqual (len (self .item .claims ['P31' ]), 1 )
134+
135+ def test_duplicate_does_not_overwrite_existing_id (self ):
136+ existing = self ._s ()
137+ existing .id = 'Q1$original'
138+ self .item .claims ['P31' ] = [existing ]
139+ self .item .merge (self ._s ())
140+ self .assertEqual (self .item .claims ['P31' ][0 ].id , 'Q1$original' )
141+
142+ # ── _ensure_loaded called ─────────────────────────────────────────────────
143+
144+ @patch ('wdpy.item.get_entities' , return_value = {})
145+ def test_triggers_load_if_not_loaded (self , mock_get ):
146+ item = wdpy .Item ('Q99' )
147+ item .merge (self ._s ())
148+ mock_get .assert_called_once ()
149+
83150 @patch ('wdpy.item.api_write' , return_value = {'entity' : {'id' : 'Q7' }})
84151 def test_write_updates_existing_item (self , api_write_mock , * _ ):
85152 item = wdpy .Item ('Q7' )
0 commit comments