class AdaptedDataContextTestCase(unittest.TestCase): ########################################################################### # TestCase interface ########################################################################### def setUp(self): unittest.TestCase.setUp(self) # Put unit adapters on either side of a masking adapter to see if they # cooperate. Store meters in the raw context, push fathoms through the # mask, and expose feet to the outside world. self.units = units = { 'in':meters, 'mid':fathom, 'out':feet } # Set up data for the contexts depth = Log(linspace(0.0, 100.0, 11), units=units['in']) lith = array(['sand']*len(depth), dtype=object) # Create the contexts self.context = AdaptedDataContext(context=DataContext()) self.raw_context = self.context.context # Add data (before creating the adapters) self.context.update(depth=depth, lith=lith) # (This simplifies creating UnitConversionAdapters) def always(value): class C(dict): def get(self, key, default=None): return value def __repr__(self): return '{*:%r}' % value return C() # Layer multiple adapters self.mask = (15.0 < depth) & (depth < 55.0) self.convert_out = lambda x: convert(x, units['in'], units['out']) self.convert_in = lambda x: convert(x, units['out'], units['in']) #self.context.push_adapter( # UnitConversionAdapter(setitem_units=always(units['in']), # getitem_units=always(units['mid']))) self.context.push_adapter(MaskingAdapter(mask=self.mask)) self.context.push_adapter( # UnitConversionAdapter(setitem_units=always(units['mid']), UnitConversionAdapter(setitem_units=always(units['in']), getitem_units=always(units['out']))) # TODO Nest masking adapters (broken) # TODO Allow unit adapters on either side of masking adapters (broken) ########################################################################### # AdaptedDataContextTestCase interface ########################################################################### def test_getitem(self): """ Is getitem adapted correctly? """ value = self.context['depth'] desired = self.convert_out(array((20., 30., 40., 50.))) self.assertEqual(len(value), 4) self.assertTrue(allclose(value, desired)) def test_setitem_existing_value(self): """ Is setitem adapted correctly for existing values? """ new_values = self.convert_out(array((30.0, 40.0, 50.0, 60.0))) desired = self.raw_context['depth'].copy() desired[self.mask] = self.convert_in(new_values) self.context['depth'] = Log(new_values, units=self.units['out']) value = self.raw_context['depth'] self.assertEqual(len(value), len(desired)) self.assertTrue(allclose(value, desired)) def test_setitem_non_existing_value(self): """ Is setitem adapted correctly for non-existing values? """ new_values = self.convert_out(array((30.0, 40.0, 50.0, 60.0))) dummy = 12345.67 desired = self.raw_context['depth'].copy() desired[self.mask] = self.convert_in(new_values) desired[~self.mask] = dummy self.context['foo'] = Log(new_values, units=self.units['out']) value = self.raw_context['foo'] value[isnan(value)] = dummy self.assertEqual(len(value), len(desired)) self.assertTrue(allclose(value, desired))
class MaskingAdapterTestCase(unittest.TestCase): ########################################################################### # TestCase interface ########################################################################### def setUp(self): unittest.TestCase.setUp(self) # Set up data for the contexts depth = linspace(0.0, 100.0, 11) lith = array(['sand'] * len(depth), dtype=object) # Create the contexts self.context = AdaptedDataContext(context=DataContext()) self.raw_context = self.context.context # Add data (before creating the adapter) self.context.update(depth=depth, lith=lith) # Add an adapter self.mask = (20.0 <= depth) & (depth <= 50.0) self.adapter = MaskingAdapter(mask=self.mask) self.context.push_adapter(self.adapter) def tearDown(self): unittest.TestCase.tearDown(self) ########################################################################### # MaskingAdapterTestCase interface ########################################################################### def test_getitem(self): """ Does adapter mask values correctly? """ name, value = self.adapter.adapt_getitem(self.raw_context, 'depth', self.raw_context['depth']) self.assertEqual(len(value), 4) self.assertTrue(all(value == (20.0, 30.0, 40.0, 50.0))) def test_setitem_existing_value(self): """ Does setitem on existing data only change the masked values? """ new_values = (30.0, 40.0, 50.0, 60.0) desired = self.raw_context['depth'].copy() desired[self.mask] = new_values name, value = self.adapter.adapt_setitem(self.raw_context, 'depth', new_values) self.assertEqual(len(value), 11) self.assertTrue(all(value == desired)) def test_setitem_non_existing_value(self): """ Does setitem on non-existing data expand to depth's shape? """ new_values = (30.0, 40.0, 50.0, 60.0) desired = self.raw_context['depth'].copy() desired[self.mask] = new_values desired[~self.mask] = nan name, value = self.adapter.adapt_setitem(self.raw_context, 'foo', new_values) self.assertEqual(len(value), len(desired)) self.assertTrue( all((value == desired) | (isnan(value) == isnan(desired)))) def test_context_getitem(self): """ Are the returned values from context masked correctly? """ depth = self.context['depth'] self.assertEqual(len(depth), 4) self.assertTrue(all(depth == (20.0, 30.0, 40.0, 50.0))) def test_context_setitem_existing(self): """ Are the returned values from context masked correctly? """ new_values = (30.0, 40.0, 50.0, 60.0) self.context['depth'] = new_values # Grab the values from the underlying context, skipping the mask. depth = self.raw_context['depth'] desired = self.raw_context['depth'].copy() desired[self.mask] = new_values self.assertTrue(all(depth == desired))
class MaskingAdapterTestCase(unittest.TestCase): ########################################################################### # TestCase interface ########################################################################### def setUp(self): unittest.TestCase.setUp(self) # Set up data for the contexts depth = linspace(0.0, 100.0, 11) lith = array(["sand"] * len(depth), dtype=object) # Create the contexts self.context = AdaptedDataContext(context=DataContext()) self.raw_context = self.context.context # Add data (before creating the adapter) self.context.update(depth=depth, lith=lith) # Add an adapter self.mask = (20.0 <= depth) & (depth <= 50.0) self.adapter = MaskingAdapter(mask=self.mask) self.context.push_adapter(self.adapter) def tearDown(self): unittest.TestCase.tearDown(self) ########################################################################### # MaskingAdapterTestCase interface ########################################################################### def test_getitem(self): """ Does adapter mask values correctly? """ name, value = self.adapter.adapt_getitem(self.raw_context, "depth", self.raw_context["depth"]) self.assertEqual(len(value), 4) self.assertTrue(all(value == (20.0, 30.0, 40.0, 50.0))) def test_setitem_existing_value(self): """ Does setitem on existing data only change the masked values? """ new_values = (30.0, 40.0, 50.0, 60.0) desired = self.raw_context["depth"].copy() desired[self.mask] = new_values name, value = self.adapter.adapt_setitem(self.raw_context, "depth", new_values) self.assertEqual(len(value), 11) self.assertTrue(all(value == desired)) def test_setitem_non_existing_value(self): """ Does setitem on non-existing data expand to depth's shape? """ new_values = (30.0, 40.0, 50.0, 60.0) desired = self.raw_context["depth"].copy() desired[self.mask] = new_values desired[~self.mask] = nan name, value = self.adapter.adapt_setitem(self.raw_context, "foo", new_values) self.assertEqual(len(value), len(desired)) self.assertTrue(all((value == desired) | (isnan(value) == isnan(desired)))) def test_context_getitem(self): """ Are the returned values from context masked correctly? """ depth = self.context["depth"] self.assertEqual(len(depth), 4) self.assertTrue(all(depth == (20.0, 30.0, 40.0, 50.0))) def test_context_setitem_existing(self): """ Are the returned values from context masked correctly? """ new_values = (30.0, 40.0, 50.0, 60.0) self.context["depth"] = new_values # Grab the values from the underlying context, skipping the mask. depth = self.raw_context["depth"] desired = self.raw_context["depth"].copy() desired[self.mask] = new_values self.assertTrue(all(depth == desired))