@@ -212,7 +212,8 @@ def test_put_bad_wal(self):
212212
213213 def mock_warn (message ):
214214 warned .append (message )
215- # Raise an exception so we don't
215+ # Raise an exception so we don't have to mock the entire
216+ # environment needed for put().
216217 raise RuntimeError ('No need to execute the rest.' )
217218
218219 table = object ()
@@ -288,6 +289,139 @@ def _try_send(self):
288289 self .assertEqual (batch ._mutation_count , 0 )
289290 self .assertEqual (batch .try_send_calls , 1 )
290291
292+ def _delete_columns_test_helper (self , time_range = None ):
293+ table = object ()
294+ batch = self ._makeOne (table )
295+ batch ._delete_range = time_range
296+
297+ col1_fam = 'cf1'
298+ col2_fam = 'cf2'
299+ col2_qual = 'col-name'
300+ columns = [col1_fam + ':' , col2_fam + ':' + col2_qual ]
301+ row_object = _MockRow ()
302+
303+ batch ._delete_columns (columns , row_object )
304+ self .assertEqual (row_object .commits , 0 )
305+
306+ cell_deleted_args = (col2_fam , col2_qual )
307+ cell_deleted_kwargs = {'time_range' : time_range }
308+ self .assertEqual (row_object .delete_cell_calls ,
309+ [(cell_deleted_args , cell_deleted_kwargs )])
310+ fam_deleted_args = (col1_fam ,)
311+ fam_deleted_kwargs = {'columns' : row_object .ALL_COLUMNS }
312+ self .assertEqual (row_object .delete_cells_calls ,
313+ [(fam_deleted_args , fam_deleted_kwargs )])
314+
315+ def test__delete_columns (self ):
316+ self ._delete_columns_test_helper ()
317+
318+ def test__delete_columns_w_time_and_col_fam (self ):
319+ time_range = object ()
320+ with self .assertRaises (ValueError ):
321+ self ._delete_columns_test_helper (time_range = time_range )
322+
323+ def test_delete_bad_wal (self ):
324+ from gcloud ._testing import _Monkey
325+ from gcloud .bigtable .happybase import batch as MUT
326+
327+ warned = []
328+
329+ def mock_warn (message ):
330+ warned .append (message )
331+ # Raise an exception so we don't have to mock the entire
332+ # environment needed for delete().
333+ raise RuntimeError ('No need to execute the rest.' )
334+
335+ table = object ()
336+ batch = self ._makeOne (table )
337+
338+ row = 'row-key'
339+ columns = []
340+ wal = None
341+
342+ self .assertNotEqual (wal , MUT ._WAL_SENTINEL )
343+ with _Monkey (MUT , _WARN = mock_warn ):
344+ with self .assertRaises (RuntimeError ):
345+ batch .delete (row , columns = columns , wal = wal )
346+
347+ self .assertEqual (warned , [MUT ._WAL_WARNING ])
348+
349+ def test_delete_entire_row (self ):
350+ table = object ()
351+ batch = self ._makeOne (table )
352+
353+ row_key = 'row-key'
354+ batch ._row_map [row_key ] = row = _MockRow ()
355+
356+ self .assertEqual (row .deletes , 0 )
357+ self .assertEqual (batch ._mutation_count , 0 )
358+ batch .delete (row_key , columns = None )
359+ self .assertEqual (row .deletes , 1 )
360+ self .assertEqual (batch ._mutation_count , 1 )
361+
362+ def test_delete_entire_row_with_ts (self ):
363+ table = object ()
364+ batch = self ._makeOne (table )
365+ batch ._delete_range = object ()
366+
367+ row_key = 'row-key'
368+ batch ._row_map [row_key ] = row = _MockRow ()
369+
370+ self .assertEqual (row .deletes , 0 )
371+ self .assertEqual (batch ._mutation_count , 0 )
372+ with self .assertRaises (ValueError ):
373+ batch .delete (row_key , columns = None )
374+ self .assertEqual (row .deletes , 0 )
375+ self .assertEqual (batch ._mutation_count , 0 )
376+
377+ def test_delete_call_try_send (self ):
378+ klass = self ._getTargetClass ()
379+
380+ class CallTrySend (klass ):
381+
382+ try_send_calls = 0
383+
384+ def _try_send (self ):
385+ self .try_send_calls += 1
386+
387+ table = object ()
388+ batch = CallTrySend (table )
389+
390+ row_key = 'row-key'
391+ batch ._row_map [row_key ] = _MockRow ()
392+
393+ self .assertEqual (batch ._mutation_count , 0 )
394+ self .assertEqual (batch .try_send_calls , 0 )
395+ # No columns so that nothing happens
396+ batch .delete (row_key , columns = [])
397+ self .assertEqual (batch ._mutation_count , 0 )
398+ self .assertEqual (batch .try_send_calls , 1 )
399+
400+ def test_delete_some_columns (self ):
401+ table = object ()
402+ batch = self ._makeOne (table )
403+
404+ row_key = 'row-key'
405+ batch ._row_map [row_key ] = row = _MockRow ()
406+
407+ self .assertEqual (batch ._mutation_count , 0 )
408+
409+ col1_fam = 'cf1'
410+ col2_fam = 'cf2'
411+ col2_qual = 'col-name'
412+ columns = [col1_fam + ':' , col2_fam + ':' + col2_qual ]
413+ batch .delete (row_key , columns = columns )
414+
415+ self .assertEqual (batch ._mutation_count , 2 )
416+ cell_deleted_args = (col2_fam , col2_qual )
417+ cell_deleted_kwargs = {'time_range' : None }
418+ self .assertEqual (row .delete_cell_calls ,
419+ [(cell_deleted_args , cell_deleted_kwargs )])
420+ fam_deleted_args = (col1_fam ,)
421+ fam_deleted_kwargs = {'columns' : row .ALL_COLUMNS }
422+ self .assertEqual (row .delete_cells_calls ,
423+ [(fam_deleted_args , fam_deleted_kwargs )])
424+
291425 def test_context_manager (self ):
292426 klass = self ._getTargetClass ()
293427
@@ -390,16 +524,30 @@ def clear(self):
390524
391525class _MockRow (object ):
392526
527+ ALL_COLUMNS = object ()
528+
393529 def __init__ (self ):
394530 self .commits = 0
531+ self .deletes = 0
395532 self .set_cell_calls = []
533+ self .delete_cell_calls = []
534+ self .delete_cells_calls = []
396535
397536 def commit (self ):
398537 self .commits += 1
399538
539+ def delete (self ):
540+ self .deletes += 1
541+
400542 def set_cell (self , * args , ** kwargs ):
401543 self .set_cell_calls .append ((args , kwargs ))
402544
545+ def delete_cell (self , * args , ** kwargs ):
546+ self .delete_cell_calls .append ((args , kwargs ))
547+
548+ def delete_cells (self , * args , ** kwargs ):
549+ self .delete_cells_calls .append ((args , kwargs ))
550+
403551
404552class _MockTable (object ):
405553
0 commit comments