class TestUnit(TestCase): @given(get_labels()) def test_index_values_len(self, values): def property_values(cls, values): #Property: that the length of the index is the length of the (unique) values. index = cls(values) self.assertEqual(len(index), len(values)) self.assertEqual(len(index.values), len(values)) property_values(Index, values) property_values(IndexGO, values) @given(get_labels()) def test_index_values_list(self, values): def property_values(cls, values): index = cls(values) # must cast both sides to the dtype, as some int to float conversions result in different floats self.assertAlmostEqualValues( index.values, np.array(values, dtype=index.values.dtype)) property_values(Index, values) property_values(IndexGO, values) @given(get_labels()) def test_index_loc_to_iloc_element(self, values): def property_loc_to_iloc_element(cls, values): index = cls(values) for i, v in enumerate(values): self.assertEqual(index.loc_to_iloc(v), i) property_loc_to_iloc_element(Index, values) property_loc_to_iloc_element(IndexGO, values) @given(get_labels(min_size=1)) def test_index_loc_to_iloc_slice(self, values): def property_loc_to_iloc_slice(cls, values): # Property: that the key translates to the appropriate slice. index = cls(values) for i, v in enumerate(values): # insure that we get teh same slice going through loc that we would get by direct iloc if v is None: self.assertEqual(index.loc_to_iloc(slice(v, None)), slice(None)) else: self.assertEqual(index.loc_to_iloc(slice(v, None)), slice(i, None)) property_loc_to_iloc_slice(Index, values) property_loc_to_iloc_slice(IndexGO, values) @given(get_labels(min_size=2)) def test_index_go_append(self, values): index = IndexGO(values[:-1]) length_start = len(index) index.append(values[-1]) length_end = len(index) self.assertEqual(length_start + 1, length_end)
class TestUnit(TestCase): @given(get_array_1d2d()) def test_mloc(self, array): x = util.mloc(array) self.assertTrue(isinstance(x, int)) @given(get_dtype_pairs()) def test_resolve_dtype(self, dtype_pair): x = util.resolve_dtype(*dtype_pair) self.assertTrue(isinstance(x, np.dtype)) @given(get_dtypes(min_size=1)) def test_resolve_dtype_iter(self, dtypes): x = util.resolve_dtype_iter(dtypes) self.assertTrue(isinstance(x, np.dtype)) @given(get_labels(min_size=1)) def test_resolve_type_object_iter(self, objects): x = util.resolve_type_object_iter(objects) self.assertTrue(x in (None, str, object)) @given(get_arrays_2d_aligned_columns()) def test_concat_resolved_axis_0(self, arrays): array = util.concat_resolved(arrays, axis=0) self.assertEqual(array.ndim, 2) self.assertEqual(array.dtype, util.resolve_dtype_iter((x.dtype for x in arrays))) @given(get_arrays_2d_aligned_rows()) def test_concat_resolved_axis_1(self, arrays): array = util.concat_resolved(arrays, axis=1) self.assertEqual(array.ndim, 2) self.assertEqual(array.dtype, util.resolve_dtype_iter((x.dtype for x in arrays))) @given(get_dtype(), get_shape_1d2d(), get_value()) def test_full_or_fill(self, dtype, shape, value): array = util.full_for_fill(dtype, shape, fill_value=value) self.assertTrue(array.shape == shape) if isinstance(value, (float, complex)) and np.isnan(value): pass else: self.assertTrue(value in array)
class TestUnit(TestCase): @given(sfst.get_labels()) # type: ignore def test_get_labels(self, values: tp.Iterable[tp.Hashable]) -> None: for value in values: self.assertTrue(isinstance(hash(value), int)) @given(sfst.get_dtypes()) # type: ignore def test_get_dtypes(self, dtypes: tp.Iterable[np.dtype]) -> None: for dt in dtypes: self.assertTrue(isinstance(dt, np.dtype)) @given(sfst.get_spacing(10)) # type: ignore def test_get_spacing_10(self, spacing: tp.Iterable[int]) -> None: self.assertEqual(sum(spacing), 10) @hypo_settings(max_examples=10) # type: ignore @given(sfst.get_shape_1d2d()) # type: ignore def test_get_shape_1d2d(self, shape: tp.Tuple[int, ...]) -> None: self.assertTrue(isinstance(shape, tuple)) self.assertTrue(len(shape) in (1, 2)) @hypo_settings(max_examples=10) # type: ignore @given(sfst.get_array_1d2d()) # type: ignore def test_get_array_1d2d(self, array: np.ndarray) -> None: self.assertTrue(isinstance(array, np.ndarray)) self.assertTrue(array.ndim in (1, 2)) @hypo_settings(max_examples=10) # type: ignore @given(sfst.get_arrays_2d_aligned_columns(min_size=2)) # type: ignore def test_get_arrays_2s_aligned_columns(self, arrays: tp.Iterable[np.ndarray]) -> None: array_iter = iter(arrays) a1 = next(array_iter) match = a1.shape[1] for array in array_iter: self.assertEqual(array.shape[1], match) @given(sfst.get_arrays_2d_aligned_rows(min_size=2)) # type: ignore def test_get_arrays_2s_aligned_rows(self, arrays: tp.Iterable[np.ndarray]) -> None: array_iter = iter(arrays) a1 = next(array_iter) match = a1.shape[0] for array in array_iter: self.assertEqual(array.shape[0], match) @hypo_settings(max_examples=10) # type: ignore @given(sfst.get_blocks()) # type: ignore def test_get_blocks(self, blocks: tp.Tuple[np.ndarray]) -> None: self.assertTrue(isinstance(blocks, tuple)) for b in blocks: self.assertTrue(isinstance(b, np.ndarray)) self.assertTrue(b.ndim in (1, 2)) @hypo_settings(max_examples=10) # type: ignore @given(sfst.get_type_blocks()) # type: ignore def test_get_type_blocks(self, tb: TypeBlocks) -> None: self.assertTrue(isinstance(tb, TypeBlocks)) rows, cols = tb.shape col_count = 0 for b in tb._blocks: if b.ndim == 1: self.assertEqual(len(b), rows) col_count += 1 else: self.assertEqual(b.ndim, 2) self.assertEqual(b.shape[0], rows) col_count += b.shape[1] self.assertEqual(col_count, cols) @hypo_settings(max_examples=10) # type: ignore @given(sfst.get_index()) # type: ignore def test_get_index(self, idx: Index) -> None: self.assertTrue(isinstance(idx, Index)) self.assertEqual(len(idx), len(idx.values)) @hypo_settings(max_examples=10) # type: ignore @given(sfst.get_index_hierarchy()) # type: ignore def test_get_index_hierarchy(self, idx: IndexHierarchy) -> None: self.assertTrue(isinstance(idx, IndexHierarchy)) self.assertTrue(idx.depth > 1) self.assertEqual(len(idx), len(idx.values)) @hypo_settings(max_examples=10) # type: ignore @given(sfst.get_series()) # type: ignore def test_get_series(self, series: Series) -> None: self.assertTrue(isinstance(series, Series)) self.assertEqual(len(series), len(series.values)) @hypo_settings(max_examples=10) # type: ignore @given(sfst.get_frame()) # type: ignore def test_get_frame(self, frame: Frame) -> None: self.assertTrue(isinstance(frame, Frame)) self.assertEqual(frame.shape, frame.values.shape) @hypo_settings(max_examples=10) # type: ignore @given(sfst.get_frame(index_cls=IndexHierarchy, columns_cls=IndexHierarchy)) # type: ignore def test_get_frame_hierarchy(self, frame: Frame) -> None: self.assertTrue(isinstance(frame, Frame)) self.assertTrue(frame.index.depth > 1) self.assertTrue(frame.columns.depth > 1) self.assertEqual(frame.shape, frame.values.shape)
class TestUnit(TestCase): @given(st.lists(sfst.get_shape_2d(), min_size=1), sfst.get_labels(min_size=1)) def test_from_element_items(self, shapes: tp.List[tp.Tuple[int, int]], labels: tp.Sequence[tp.Hashable]) -> None: # use shapes to get coordinates, where the max shape + 1 is the final shape shape = tuple(np.array(shapes).max(axis=0) + 1) def values() -> tp.Iterator[tp.Tuple[tp.Tuple[int, int], tp.Hashable]]: for idx, coord in enumerate(shapes): yield coord, labels[idx % len(labels)] post = TypeBlocks.from_element_items(values(), shape=shape, dtype=object) self.assertEqual(post.shape, shape) @given(st.integers(max_value=sfst.MAX_COLUMNS)) def test_from_zero_size_shape(self, value: int) -> None: for shape in ((0, value), (value, 0)): post = TypeBlocks.from_zero_size_shape(shape=shape) self.assertEqual(post.shape, shape) @given(sfst.get_type_blocks()) def test_basic_attributes(self, tb: TypeBlocks) -> None: self.assertEqual(len(tb.dtypes), tb.shape[1]) self.assertEqual(len(tb.shapes), len(tb.mloc)) self.assertEqual(tb.copy().shape, tb.shape) self.assertEqual(tb.ndim, 2) self.assertEqual(tb.unified, len(tb.mloc) <= 1) if tb.shape[0] > 0 and tb.shape[1] > 0: self.assertTrue(tb.size > 0) self.assertTrue(tb.nbytes > 0) else: self.assertTrue(tb.size == 0) self.assertTrue(tb.nbytes == 0) @given(sfst.get_type_blocks()) def test_values(self, tb: TypeBlocks) -> None: values = tb.values self.assertEqual(values.shape, tb.shape) self.assertEqual(values.dtype, tb._row_dtype) @given(sfst.get_type_blocks()) def test_axis_values(self, tb: TypeBlocks) -> None: # this test found a flaw in axis_values when dealing with axis 1 and unified, 1D type blocks for axis in (0, 1): for reverse in (True, False): post = tuple(tb.axis_values(axis=axis, reverse=reverse)) for idx, array in enumerate(post): self.assertTrue(len(array) == tb.shape[axis]) if axis == 0 and not reverse: # colums self.assertTrue(array.dtype == tb.dtypes[idx]) elif axis == 0 and reverse: # colums self.assertTrue(array.dtype == tb.dtypes[tb.shape[1] - 1 - idx]) else: # NOTE: only checking kinde because found cases where byte-order deviates self.assertTrue(array.dtype.kind == tb._row_dtype.kind) @given(sfst.get_type_blocks()) def test_element_items(self, tb: TypeBlocks) -> None: # NOTE: this found a flaw in _extract_iloc where we tried to optimize selection with a unified array count = 0 for k, v in tb.element_items(): count += 1 v_extract = tb.iloc[k] self.assertEqualWithNaN(v, v_extract) self.assertEqual(count, tb.size) @given(sfst.get_type_blocks()) def test_reblock_signature(self, tb: TypeBlocks) -> None: post = tuple(tb._reblock_signature()) unique_dtypes = np.unique(tb.dtypes) # the reblock signature must be have at least as many entries as types self.assertTrue(len(post) >= len(unique_dtypes)) # sum of column widths is qual to columns in shape self.assertTrue(sum(p[1] for p in post), tb.shape[1]) @given(sfst.get_type_blocks(), sfst.get_type_blocks()) def test_block_compatible(self, tb1: TypeBlocks, tb2: TypeBlocks) -> None: for axis in (None, 0, 1): post1 = tb1.block_compatible(tb2, axis) post2 = tb2.block_compatible(tb1, axis) # either direction gets the same result self.assertTrue(post1 == post2) # if the shapes are different, they cannot be block compatible if axis is None and tb1.shape != tb2.shape: self.assertFalse(post1) @given(sfst.get_type_blocks(), sfst.get_type_blocks()) def test_reblock_compatible(self, tb1: TypeBlocks, tb2: TypeBlocks) -> None: post1 = tb1.reblock_compatible(tb2) post2 = tb2.reblock_compatible(tb1) # either direction gets the same result self.assertTrue(post1 == post2) # if the shapes are different, they cannot be block compatible if tb1.shape[1] != tb2.shape[1]: self.assertFalse(post1) @unittest.skip('pending') def test_concatenate_blocks(self) -> None: pass @given(sfst.get_type_blocks()) def test_consolidate_blocks(self, tb: TypeBlocks) -> None: tb_post = TypeBlocks.from_blocks(tb.consolidate_blocks(tb._blocks)) self.assertEqual(tb_post.shape, tb.shape) self.assertTrue((tb_post.dtypes == tb.dtypes).all()) @given(sfst.get_type_blocks()) def test_reblock(self, tb: TypeBlocks) -> None: tb_post = TypeBlocks.from_blocks(tb._reblock()) self.assertEqual(tb_post.shape, tb.shape) self.assertTrue((tb_post.dtypes == tb.dtypes).all()) @given(sfst.get_type_blocks()) def test_consolidate(self, tb: TypeBlocks) -> None: tb_post = tb.consolidate() self.assertEqual(tb_post.shape, tb.shape) self.assertTrue((tb_post.dtypes == tb.dtypes).all()) @unittest.skip('pending') def test_resize_blocks(self) -> None: pass @unittest.skip('pending') def test_group(self) -> None: pass @unittest.skip('pending') def test_ufunc_axis_skipna(self) -> None: pass @given(sfst.get_type_blocks()) def test_display(self, tb: TypeBlocks) -> None: post = tb.display() self.assertTrue(len(post) > 0) @unittest.skip('pending') def test_cols_to_slice(self) -> None: pass @unittest.skip('pending') def test_indices_to_contiguous_pairs(self) -> None: pass @unittest.skip('pending') def test_key_to_block_slices(self) -> None: pass @unittest.skip('pending') def test_mask_blocks(self) -> None: pass @unittest.skip('pending') def test_astype_blocks(self) -> None: pass @unittest.skip('pending') def test_shift_blocks(self) -> None: pass @given(sfst.get_type_blocks()) def test_assign_blocks_from_keys(self, tb1: TypeBlocks) -> None: # assigning a single value from a list of column keys for i in range(tb1.shape[1]): tb2 = TypeBlocks.from_blocks( tb1._assign_from_iloc_by_unit(column_key=[i], value=300)) self.assertTrue(tb1.shape == tb2.shape) # no more than one type should be changed self.assertTrue((tb1.dtypes != tb2.dtypes).sum() <= 1) # assigning a single value from a list of row keys for i in range(tb1.shape[0]): tb3 = TypeBlocks.from_blocks( tb1._assign_from_iloc_by_unit(row_key=[i], value=300)) self.assertTrue(tb1.shape == tb3.shape) self.assertTrue(tb3.iloc[i, 0] == 300) # column slices to the end for i in range(tb1.shape[1]): tb4 = TypeBlocks.from_blocks( tb1._assign_from_iloc_by_unit(column_key=slice(i, None), value=300)) self.assertTrue(tb1.shape == tb4.shape) # we have as many or more blocks self.assertTrue(len(tb4.shapes) >= len(tb1.shapes)) @unittest.skip('pending') def test_assign_blocks_from_boolean_blocks(self) -> None: pass @unittest.skip('pending') def test_slice_blocks(self) -> None: pass @unittest.skip('pending') def test_extract_array(self) -> None: pass @unittest.skip('pending') def test_extract(self) -> None: pass @unittest.skip('pending') def test_extract_iloc(self) -> None: pass @unittest.skip('pending') def test_extract_iloc_mask(self) -> None: pass @unittest.skip('pending') def test_extract_iloc_assign(self) -> None: pass @given(sfst.get_type_blocks(min_rows=1, min_columns=1)) def test_drop(self, tb: TypeBlocks) -> None: for row in range(tb.shape[0]): tb_post1 = tb.drop(row) self.assertTrue(tb_post1.shape[0] == tb.shape[0] - 1) if tb.shape[0] > 2: for start in range(1, tb.shape[0]): tb_post2 = tb.drop(slice(start, None)) self.assertTrue(tb_post2.shape[0] == start) for col in range(tb.shape[1]): tb_post3 = tb.drop((None, col)) self.assertTrue(tb_post3.shape[1] == tb.shape[1] - 1) if tb.shape[1] > 2: for start in range(1, tb.shape[1]): tb_post4 = tb.drop((None, slice(start, None))) self.assertTrue(tb_post4.shape[1] == start) @unittest.skip('pending') def test_getitem(self) -> None: pass @unittest.skip('pending') def test_ufunc_unary_operator(self) -> None: pass @unittest.skip('pending') def test_block_shape_slices(self) -> None: pass @unittest.skip('pending') def test_ufunc_binary_operator(self) -> None: pass @unittest.skip('pending') def test_transpose(self) -> None: pass @unittest.skip('pending') def test_isna(self) -> None: pass @unittest.skip('pending') def test_notna(self) -> None: pass @unittest.skip('pending') def test_fillna_leading(self) -> None: pass @unittest.skip('pending') def test_fillna_trailing(self) -> None: pass @unittest.skip('pending') def test_fillna_forward(self) -> None: pass @unittest.skip('pending') def test_fillna_backward(self) -> None: pass @unittest.skip('pending') def test_dropna_to_keep_locations(self) -> None: pass @unittest.skip('pending') def test_fillna(self) -> None: pass @given(sfst.get_type_blocks_aligned_array()) def test_append( self, tb_aligned_array: tp.Tuple[TypeBlocks, np.ndarray]) -> None: tb, aa = tb_aligned_array shape_original = tb.shape tb.append(aa) if aa.ndim == 1: self.assertEqual(tb.shape[1], shape_original[1] + 1) else: self.assertEqual(tb.shape[1], shape_original[1] + aa.shape[1]) @given(sfst.get_type_blocks_aligned_type_blocks(min_size=2, max_size=2)) def test_extend(self, tbs: tp.Sequence[TypeBlocks]) -> None: front = tbs[0] back = tbs[1] shape_original = front.shape # extend with type blocks front.extend(back) self.assertEqual( front.shape, (shape_original[0], shape_original[1] + back.shape[1])) # extend with iterable of arrays front.extend(back._blocks) self.assertEqual( front.shape, (shape_original[0], shape_original[1] + back.shape[1] * 2))
class TestUnit(TestCase): @given(get_array_1d2d()) # type: ignore def test_mloc(self, array: np.ndarray) -> None: x = util.mloc(array) self.assertTrue(isinstance(x, int)) @given(get_array_1d2d()) # type: ignore def test_shape_filter(self, shape: np.ndarray) -> None: self.assertTrue(len(util.shape_filter(shape)), 2) @given(get_dtype_pairs()) # type: ignore def test_resolve_dtype(self, dtype_pair: tp.Tuple[np.dtype, np.dtype]) -> None: x = util.resolve_dtype(*dtype_pair) self.assertTrue(isinstance(x, np.dtype)) @given(get_dtypes(min_size=1)) # type: ignore def test_resolve_dtype_iter(self, dtypes: tp.Iterable[np.dtype]) -> None: x = util.resolve_dtype_iter(dtypes) self.assertTrue(isinstance(x, np.dtype)) @given(get_labels(min_size=1)) # type: ignore def test_resolve_type_iter(self, objects: tp.Iterable[object]) -> None: known_types = set( (None, type(None), bool, str, object, int, float, complex, datetime.date, datetime.datetime, fractions.Fraction)) resolved, has_tuple, values_post = util.resolve_type_iter(objects) self.assertTrue(resolved in known_types) @given(get_arrays_2d_aligned_columns()) # type: ignore def test_concat_resolved_axis_0(self, arrays: tp.List[np.ndarray]) -> None: array = util.concat_resolved(arrays, axis=0) self.assertEqual(array.ndim, 2) self.assertEqual(array.dtype, util.resolve_dtype_iter((x.dtype for x in arrays))) @given(get_arrays_2d_aligned_rows()) # type: ignore def test_concat_resolved_axis_1(self, arrays: tp.List[np.ndarray]) -> None: array = util.concat_resolved(arrays, axis=1) self.assertEqual(array.ndim, 2) self.assertEqual(array.dtype, util.resolve_dtype_iter((x.dtype for x in arrays))) @given(get_dtype(), get_shape_1d2d(), get_value()) # type: ignore def test_full_or_fill(self, dtype: np.dtype, shape: tp.Union[tp.Tuple[int], tp.Tuple[int, int]], value: object) -> None: array = util.full_for_fill(dtype, shape, fill_value=value) self.assertTrue(array.shape == shape) if isinstance(value, (float, complex)) and np.isnan(value): pass else: self.assertTrue(value in array) @given(get_dtype()) # type: ignore def test_dtype_to_na(self, dtype: util.DtypeSpecifier) -> None: post = util.dtype_to_na(dtype) self.assertTrue(post in {0, False, None, '', np.nan, util.NAT}) @given(get_array_1d2d(dtype_group=DTGroup.NUMERIC)) # type: ignore def test_ufunc_axis_skipna(self, array: np.ndarray) -> None: has_na = util.isna_array(array).any() for nt in UFUNC_AXIS_SKIPNA.values(): ufunc = nt.ufunc ufunc_skipna = nt.ufunc_skipna # dtypes = nt.dtypes # composable = nt.composable # doc = nt.doc_header # size_one_unity = nt.size_one_unity with np.errstate(over='ignore', under='ignore', divide='ignore'): post = util.ufunc_axis_skipna(array=array, skipna=True, axis=0, ufunc=ufunc, ufunc_skipna=ufunc_skipna) if array.ndim == 2: self.assertTrue(post.ndim == 1) @given(get_array_1d2d()) # type: ignore def test_ufunc_unique(self, array: np.ndarray) -> None: post = util.ufunc_unique(array, axis=0) self.assertTrue(len(post) <= array.shape[0]) @given(get_array_1d(min_size=1), st.integers()) # type: ignore def test_roll_1d(self, array: np.ndarray, shift: int) -> None: post = util.roll_1d(array, shift) self.assertEqual(len(post), len(array)) self.assertEqualWithNaN(array[-(shift % len(array))], post[0]) @given(get_array_2d(min_rows=1, min_columns=1), st.integers()) # type: ignore def test_roll_2d(self, array: np.ndarray, shift: int) -> None: for axis in (0, 1): post = util.roll_2d(array, shift=shift, axis=axis) self.assertEqual(post.shape, array.shape) start = -(shift % array.shape[axis]) if axis == 0: a = array[start] b = post[0] else: a = array[:, start] b = post[:, 0] self.assertAlmostEqualValues(a, b) @given(get_array_1d(dtype_group=DTGroup.OBJECT)) # type: ignore def test_iterable_to_array_a(self, array: np.ndarray) -> None: values = array.tolist() post, _ = util.iterable_to_array(values) self.assertAlmostEqualValues(post, values) # explicitly giving object dtype post, _ = util.iterable_to_array(values, dtype=util.DTYPE_OBJECT) self.assertAlmostEqualValues(post, values) @given(get_labels()) # type: ignore def test_iterable_to_array_b(self, labels: tp.Iterable[tp.Any]) -> None: post, _ = util.iterable_to_array(labels) self.assertAlmostEqualValues(post, labels) self.assertTrue(isinstance(post, np.ndarray)) @given(st.slices(10)) # type: ignore #pylint: disable=E1120 def test_slice_to_ascending_slice(self, key: slice) -> None: post_key = util.slice_to_ascending_slice(key, size=10) self.assertEqual(set(range(*key.indices(10))), set(range(*post_key.indices(10)))) # to_datetime64 # to_timedelta64 # key_to_datetime_key @given(get_array_1d2d()) # type: ignore def test_array_to_groups_and_locations(self, array: np.ndarray) -> None: groups, locations = util.array_to_groups_and_locations(array, 0) if len(array) > 0: self.assertTrue(len(groups) >= 1) # always 1dm locations self.assertTrue(locations.ndim == 1) self.assertTrue(len(np.unique(locations)) == len(groups)) @given(get_array_1d2d()) # type: ignore def test_isna_array(self, array: np.ndarray) -> None: post = util.isna_array(array) self.assertTrue(post.dtype == bool) values = np.ravel(array) count_na = sum(util.isna_element(x) for x in values) self.assertTrue(np.ravel(post).sum() == count_na) @given(get_array_1d(dtype_group=DTGroup.BOOL)) # type: ignore def test_binary_transition(self, array: np.ndarray) -> None: post = util.binary_transition(array) # could be 32 via result of np.nonzero self.assertTrue(post.dtype in (np.int32, np.int64)) # if no True in original array, result will be empty if array.sum() == 0: self.assertTrue(len(post) == 0) # if all True, result is empty elif array.sum() == len(array): self.assertTrue(len(post) == 0) else: # the post selection shold always be indices that are false self.assertTrue(array[post].sum() == 0) @given(get_array_1d2d()) # type: ignore def test_array_to_duplicated(self, array: np.ndarray) -> None: if array.ndim == 2: for axis in (0, 1): post = util.array_to_duplicated(array, axis=axis) if axis == 0: unique_count = len(set(tuple(x) for x in array)) else: unique_count = len( set(tuple(array[:, i]) for i in range(array.shape[1]))) if unique_count < array.shape[axis]: self.assertTrue(post.sum() > 0) else: post = util.array_to_duplicated(array) # if not all value are unique, we must have some duplicated if len(set(array)) < len(array): self.assertTrue(post.sum() > 0) self.assertTrue(post.dtype == bool) @given(get_array_1d2d()) # type: ignore def test_array_shift(self, array: np.ndarray) -> None: for shift in (-1, 1): for wrap in (True, False): tests = [] post1 = util.array_shift(array=array, shift=shift, axis=0, wrap=wrap) tests.append(post1) if array.ndim == 2: post2 = util.array_shift(array=array, shift=shift, axis=1, wrap=wrap) tests.append(post2) for post in tests: self.assertTrue(array.shape == post.shape) # type is only always maintained if we are wrapping if wrap: self.assertTrue(array.dtype == post.dtype) @given(st.lists(get_array_1d(), min_size=2, max_size=2)) # type: ignore def test_union1d(self, arrays: tp.Sequence[np.ndarray]) -> None: post = util.union1d(arrays[0], arrays[1], assume_unique=False) self.assertTrue(post.ndim == 1) # nan values in complex numbers make direct comparison tricky self.assertTrue(len(post) == len(set(arrays[0]) | set(arrays[1]))) # complex results are tricky to compare after forming sets if (post.dtype.kind not in ('O', 'M', 'm', 'c', 'f') and not np.isnan(post).any()): self.assertTrue(set(post) == (set(arrays[0]) | set(arrays[1]))) @given(st.lists(get_array_1d(), min_size=2, max_size=2)) # type: ignore def test_intersect1d(self, arrays: tp.Sequence[np.ndarray]) -> None: post = util.intersect1d(arrays[0], arrays[1], assume_unique=False) self.assertTrue(post.ndim == 1) # nan values in complex numbers make direct comparison tricky self.assertTrue(len(post) == len(set(arrays[0]) & set(arrays[1]))) if (post.dtype.kind not in ('O', 'M', 'm', 'c', 'f') and not np.isnan(post).any()): self.assertTrue(set(post) == (set(arrays[0]) & set(arrays[1]))) @given(get_arrays_2d_aligned_columns(min_size=2, max_size=2)) # type: ignore def test_union2d(self, arrays: tp.Sequence[np.ndarray]) -> None: post = util.union2d(arrays[0], arrays[1], assume_unique=False) if post.dtype == object: self.assertTrue(post.ndim == 1) else: self.assertTrue(post.ndim == 2) self.assertTrue( len(post) == len( set(util.array2d_to_tuples(arrays[0])) | set(util.array2d_to_tuples(arrays[1])))) @given(get_arrays_2d_aligned_columns(min_size=2, max_size=2)) # type: ignore def test_intersect2d(self, arrays: tp.Sequence[np.ndarray]) -> None: post = util.intersect2d(arrays[0], arrays[1], assume_unique=False) if post.dtype == object: self.assertTrue(post.ndim == 1) else: self.assertTrue(post.ndim == 2) self.assertTrue( len(post) == len( set(util.array2d_to_tuples(arrays[0])) & set(util.array2d_to_tuples(arrays[1])))) @given(get_arrays_2d_aligned_columns()) # type: ignore def test_array_set_ufunc_many(self, arrays: tp.Sequence[np.ndarray]) -> None: for union in (True, False): post = util.ufunc_set_iter(arrays, union=union) if post.dtype == object: # returned object arrays might be 2D or 1D of tuples self.assertTrue(post.ndim in (1, 2)) else: self.assertTrue(post.ndim == 2)
class TestUnit(TestCase): @given(get_array_1d2d()) # type: ignore def test_mloc(self, array: np.ndarray) -> None: x = util.mloc(array) self.assertTrue(isinstance(x, int)) @given(get_dtype_pairs()) # type: ignore def test_resolve_dtype(self, dtype_pair: tp.Tuple[np.dtype, np.dtype]) -> None: x = util.resolve_dtype(*dtype_pair) self.assertTrue(isinstance(x, np.dtype)) @given(get_dtypes(min_size=1)) # type: ignore def test_resolve_dtype_iter(self, dtypes: tp.Iterable[np.dtype]) -> None: x = util.resolve_dtype_iter(dtypes) self.assertTrue(isinstance(x, np.dtype)) @given(get_labels(min_size=1)) # type: ignore def test_resolve_type_iter(self, objects: tp.Iterable[object]) -> None: known_types = set(( None, type(None), bool, str, object, int, float, complex, datetime.date, datetime.datetime, fractions.Fraction )) resolved, has_tuple, values_post = util.resolve_type_iter(objects) self.assertTrue(resolved in known_types) @given(get_arrays_2d_aligned_columns()) # type: ignore def test_concat_resolved_axis_0(self, arrays: tp.List[np.ndarray]) -> None: array = util.concat_resolved(arrays, axis=0) self.assertEqual(array.ndim, 2) self.assertEqual(array.dtype, util.resolve_dtype_iter((x.dtype for x in arrays))) @given(get_arrays_2d_aligned_rows()) # type: ignore def test_concat_resolved_axis_1(self, arrays: tp.List[np.ndarray]) -> None: array = util.concat_resolved(arrays, axis=1) self.assertEqual(array.ndim, 2) self.assertEqual(array.dtype, util.resolve_dtype_iter((x.dtype for x in arrays))) @given(get_dtype(), get_shape_1d2d(), get_value()) # type: ignore def test_full_or_fill(self, dtype: np.dtype, shape: tp.Union[tp.Tuple[int], tp.Tuple[int, int]], value: object) -> None: array = util.full_for_fill(dtype, shape, fill_value=value) self.assertTrue(array.shape == shape) if isinstance(value, (float, complex)) and np.isnan(value): pass else: self.assertTrue(value in array) @given(get_dtype()) # type: ignore def test_dtype_to_na(self, dtype: util.DtypeSpecifier) -> None: post = util.dtype_to_na(dtype) self.assertTrue(post in {0, False, None, '', np.nan, util.NAT}) @given(get_array_1d(min_size=1, dtype_group=DTGroup.NUMERIC)) # type: ignore def test_ufunc_skipna_1d(self, array: np.ndarray) -> None: has_na = util.isna_array(array).any() for ufunc, ufunc_skipna, dtype in UFUNC_AXIS_SKIPNA.values(): with np.errstate(over='ignore', under='ignore'): v1 = ufunc_skipna(array) # this should return a single value self.assertFalse(isinstance(v1, np.ndarray)) if has_na: v2 = ufunc(array) self.assertFalse(isinstance(v2, np.ndarray)) @given(get_array_1d2d()) # type: ignore def test_ufunc_unique(self, array: np.ndarray) -> None: post = util.ufunc_unique(array, axis=0) self.assertTrue(len(post) <= array.shape[0]) @given(get_array_1d(min_size=1), st.integers()) # type: ignore def test_roll_1d(self, array: np.ndarray, shift: int) -> None: post = util.roll_1d(array, shift) self.assertEqual(len(post), len(array)) self.assertEqualWithNaN(array[-(shift % len(array))], post[0]) @given(get_array_2d(min_rows=1, min_columns=1), st.integers()) # type: ignore def test_roll_2d(self, array: np.ndarray, shift: int) -> None: for axis in (0, 1): post = util.roll_2d(array, shift=shift, axis=axis) self.assertEqual(post.shape, array.shape) start = -(shift % array.shape[axis]) if axis == 0: a = array[start] b = post[0] else: a = array[:, start] b = post[:, 0] self.assertAlmostEqualValues(a, b) @given(get_array_1d(dtype_group=DTGroup.OBJECT)) # type: ignore def test_iterable_to_array_a(self, array: np.ndarray) -> None: values = array.tolist() post, _ = util.iterable_to_array(values) self.assertAlmostEqualValues(post, values) # explicitly giving object dtype post, _ = util.iterable_to_array(values, dtype=util.DTYPE_OBJECT) self.assertAlmostEqualValues(post, values) @given(get_labels()) # type: ignore def test_iterable_to_array_b(self, labels: tp.Iterable[tp.Any]) -> None: post, _ = util.iterable_to_array(labels) self.assertAlmostEqualValues(post, labels) self.assertTrue(isinstance(post, np.ndarray)) @given(st.slices(10)) # type: ignore def test_slice_to_ascending_slice(self, key: slice) -> None: post_key = util.slice_to_ascending_slice(key, size=10) self.assertEqual( set(range(*key.indices(10))), set(range(*post_key.indices(10))) ) # to_datetime64 # to_timedelta64 # key_to_datetime_key @given(get_array_1d2d()) # type: ignore def test_array_to_groups_and_locations(self, array: np.ndarray) -> None: groups, locations = util.array_to_groups_and_locations(array, 0) if len(array) > 0: self.assertTrue(len(groups) >= 1) # always 1dm locations self.assertTrue(locations.ndim == 1) self.assertTrue(len(np.unique(locations)) == len(groups)) @given(get_array_1d2d()) # type: ignore def test_isna_array(self, array: np.ndarray) -> None: post = util.isna_array(array) self.assertTrue(post.dtype == bool) values = np.ravel(array) count_na = sum(util.isna_element(x) for x in values) self.assertTrue(np.ravel(post).sum() == count_na) @given(get_array_1d(dtype_group=DTGroup.BOOL)) # type: ignore def test_binary_transition(self, array: np.ndarray) -> None: post = util.binary_transition(array) # could be 32 via result of np.nonzero self.assertTrue(post.dtype in (np.int32, np.int64)) # if no True in original array, result will be empty if array.sum() == 0: self.assertTrue(len(post) == 0) # if all True, result is empty elif array.sum() == len(array): self.assertTrue(len(post) == 0) else: # the post selection shold always be indices that are false self.assertTrue(array[post].sum() == 0)
class TestUnit(TestCase): @given(get_labels()) def test_index_values_len(self, values: tp.Sequence[tp.Hashable]) -> None: def property_values(cls: tp.Type[Index], values: tp.Sequence[tp.Hashable]) -> None: #Property: that the length of the index is the length of the (unique) values. index = cls(values) self.assertEqual(len(index), len(values)) self.assertEqual(len(index.values), len(values)) property_values(Index, values) property_values(IndexGO, values) @given(get_labels()) def test_index_values_list(self, values: tp.Sequence[tp.Hashable]) -> None: def property_values(cls: tp.Type[Index], values: tp.Iterable[tp.Hashable]) -> None: index = cls(values) # must cast both sides to the dtype, as some int to float conversions result in different floats self.assertAlmostEqualValues( index.values, np.array(values, dtype=index.values.dtype)) property_values(Index, values) property_values(IndexGO, values) @given(get_labels()) def test_index_loc_to_iloc_element( self, values: tp.Sequence[tp.Hashable]) -> None: def property_loc_to_iloc_element( cls: tp.Type[Index], values: tp.Iterable[tp.Hashable]) -> None: index = cls(values) for i, v in enumerate(values): self.assertEqual(index._loc_to_iloc(v), i) property_loc_to_iloc_element(Index, values) property_loc_to_iloc_element(IndexGO, values) @given(get_labels(min_size=1)) def test_index_loc_to_iloc_slice(self, values: tp.Sequence[tp.Hashable]) -> None: def property_loc_to_iloc_slice( cls: tp.Type[Index], values: tp.Iterable[tp.Hashable]) -> None: # Property: that the key translates to the appropriate slice. index = cls(values) for i, v in enumerate(values): # insure that we get teh same slice going through loc that we would get by direct iloc if v is None: self.assertEqual(index._loc_to_iloc(slice(v, None)), slice(None)) #type: ignore [unreachable] else: self.assertEqual(index._loc_to_iloc(slice(v, None)), slice(i, None)) property_loc_to_iloc_slice(Index, values) property_loc_to_iloc_slice(IndexGO, values) @given(get_labels(min_size=2)) def test_index_go_append(self, values: tp.Sequence[tp.Hashable]) -> None: index = IndexGO(values[:-1]) length_start = len(index) index.append(values[-1]) length_end = len(index) self.assertEqual(length_start + 1, length_end) @given(get_labels(min_size=1)) def test_index_isin(self, labels: tp.Sequence[tp.Hashable]) -> None: index = Index(labels) self.assertTrue(index.isin((labels[0], ))[0]) #--------------------------------------------------------------------------- @given(get_index_any()) def test_index_display(self, index: Index) -> None: d1 = index.display() self.assertTrue(len(d1) > 0) d2 = index.display_tall() self.assertTrue(len(d2) > 0) d3 = index.display_wide() self.assertTrue(len(d3) > 0) @given(get_index_any()) def test_index_to_series(self, index: Index) -> None: s1 = index.to_series() self.assertEqual(len(s1), len(index)) #--------------------------------------------------------------------------- @given(get_index_any()) def test_index_iloc_map_a(self, index: Index) -> None: # We can't handle NaNs if any(map(isna_element, index.values)): return np.random.seed(0) ilocs = np.arange(len(index)) # Need new array, will shuffle in-place np.random.shuffle(ilocs) other = tp.cast(Index, index.iloc[ilocs]) expected = index.iter_label().apply(other._loc_to_iloc) post = index._index_iloc_map(other) self.assertEqual(post.tolist(), expected.tolist())
class TestUnit(TestCase): @given(get_labels()) # type: ignore def test_index_values_len(self, values: tp.Sequence[tp.Hashable]) -> None: def property_values(cls: tp.Type[Index], values: tp.Sequence[tp.Hashable]) -> None: #Property: that the length of the index is the length of the (unique) values. index = cls(values) self.assertEqual(len(index), len(values)) self.assertEqual(len(index.values), len(values)) property_values(Index, values) property_values(IndexGO, values) @given(get_labels()) # type: ignore def test_index_values_list(self, values: tp.Sequence[tp.Hashable]) -> None: def property_values(cls: tp.Type[Index], values: tp.Iterable[tp.Hashable]) -> None: index = cls(values) # must cast both sides to the dtype, as some int to float conversions result in different floats self.assertAlmostEqualValues( index.values, np.array(values, dtype=index.values.dtype)) property_values(Index, values) property_values(IndexGO, values) @given(get_labels()) # type: ignore def test_index_loc_to_iloc_element( self, values: tp.Sequence[tp.Hashable]) -> None: def property_loc_to_iloc_element( cls: tp.Type[Index], values: tp.Iterable[tp.Hashable]) -> None: index = cls(values) for i, v in enumerate(values): self.assertEqual(index.loc_to_iloc(v), i) property_loc_to_iloc_element(Index, values) property_loc_to_iloc_element(IndexGO, values) @given(get_labels(min_size=1)) # type: ignore def test_index_loc_to_iloc_slice(self, values: tp.Sequence[tp.Hashable]) -> None: def property_loc_to_iloc_slice( cls: tp.Type[Index], values: tp.Iterable[tp.Hashable]) -> None: # Property: that the key translates to the appropriate slice. index = cls(values) for i, v in enumerate(values): # insure that we get teh same slice going through loc that we would get by direct iloc if v is None: self.assertEqual(index.loc_to_iloc(slice(v, None)), slice(None)) else: self.assertEqual( index.loc_to_iloc(slice(v, None)), slice(i, None) ) # type: ignore # https://github.com/python/typeshed/pull/3024 property_loc_to_iloc_slice(Index, values) property_loc_to_iloc_slice(IndexGO, values) @given(get_labels(min_size=2)) # type: ignore def test_index_go_append(self, values: tp.Sequence[tp.Hashable]) -> None: index = IndexGO(values[:-1]) length_start = len(index) index.append(values[-1]) length_end = len(index) self.assertEqual(length_start + 1, length_end) @given(get_labels(min_size=1)) # type: ignore def test_index_isin(self, labels: tp.Sequence[tp.Hashable]) -> None: index = Index(labels) self.assertTrue(index.isin((labels[0], ))[0])