Exemplo n.º 1
0
    def test_async_call_loop_error_if_no_loop(self):
        tbl = Table({"a": int, "b": float, "c": str})
        manager = PerspectiveManager()

        with raises(PerspectiveError):
            # loop not set - errors
            manager.call_loop(tbl.update, data)

        manager.set_loop_callback(TestAsync.loop.add_callback)
        manager.call_loop(tbl.update, data)
        manager.host(tbl)

        @syncify
        def _task():
            return tbl.size()

        # subsequent calls to call_loop will work if loop_callback is set.
        assert _task() == 10

        tbl.delete()
    def benchmark_view_two_column_only_updates(self):
        """Benchmark how long it takes for each update to resolve fully, using
        the on update callback that forces resolution of updates across
        25 views."""
        table = Table(self._schema)
        views = [
            table.view(split_by=["Category", "Sub-Category"])
            for i in range(25)
        ]
        for v in views:
            v.on_update(empty_callback)
        update_data = self._get_update_data(1000)

        def resolve_update():
            table.update(update_data)
            table.size()

        func = Benchmark(resolve_update,
                         meta=make_meta("update", "two_column_only"))
        setattr(self, "update_two_column_only", func)
Exemplo n.º 3
0
 def test_view_computed_multiple_dependents(self):
     table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]})
     view = table.view(computed_columns=[
         {
             "column": "computed",
             "computed_function_name": "+",
             "inputs": ["a", "b"],
         },
         {
             "column": "final",
             "computed_function_name": "pow2",
             "inputs": ["computed"],
         },
     ])
     assert view.to_columns() == {
         "a": [1, 2, 3, 4],
         "b": [5, 6, 7, 8],
         "computed": [6, 8, 10, 12],
         "final": [36, 64, 100, 144],
     }
Exemplo n.º 4
0
 def test_viewer_delete_without_table(self):
     table = Table({"a": [1, 2, 3]})
     viewer = PerspectiveViewer(plugin="x_bar", filters=[["a", "==", 2]])
     viewer.load(table)
     assert viewer.filters == [["a", "==", 2]]
     viewer.delete(delete_table=False)
     assert viewer.table_name is not None
     assert viewer.table is not None
     assert viewer._perspective_view_name is not None
     assert viewer._view is not None
     assert viewer.filters == []
Exemplo n.º 5
0
    def test_manager_table_get_computation_input_types(self):
        post_callback = partial(self.validate_post,
                                expected={
                                    "id": 1,
                                    "data": ["string"]
                                })

        message = {
            "id": 1,
            "name": "table1",
            "cmd": "table_method",
            "method": "get_computation_input_types",
            "args": ["concat_comma"]
        }
        manager = PerspectiveManager()
        table = Table(data)
        view = table.view()
        manager.host_table("table1", table)
        manager.host_view("view1", view)
        manager._process(message, post_callback)
Exemplo n.º 6
0
 def test_manager_create_view_one(self):
     message = {"id": 1, "table_name": "table1", "view_name": "view1", "cmd": "view", "config": {"row_pivots": ["a"]}}
     manager = PerspectiveManager()
     table = Table(data)
     manager.host_table("table1", table)
     manager._process(message, self.post)
     assert manager._views["view1"].to_dict() == {
         "__ROW_PATH__": [[], [1], [2], [3]],
         "a": [6, 1, 2, 3],
         "b": [3, 1, 1, 1]
     }
Exemplo n.º 7
0
 def test_to_arrow_start_end_col_end_row(self):
     data = {
         "a": [None, 1, None, 2, 3],
         "b": [1.5, 2.5, None, 3.5, None],
         "c": [1.5, 2.5, None, 4.5, None]
     }
     tbl = Table(data)
     assert tbl.schema() == {"a": int, "b": float, "c": float}
     arr = tbl.view().to_arrow(start_col=1, end_col=2, end_row=2)
     tbl2 = Table(arr)
     assert tbl2.view().to_dict() == tbl.view().to_dict(start_col=1,
                                                        end_col=2,
                                                        end_row=2)
Exemplo n.º 8
0
 def test_widget_load_table_server(self):
     table = Table({"a": np.arange(0, 50)})
     widget = PerspectiveWidget(table, server=True)
     load_msg = widget._make_load_message()
     assert load_msg.to_dict() == {
         "id": -2,
         "type": "table",
         "data": {
             "table_name": widget.table_name
         }
     }
Exemplo n.º 9
0
    def test_manager_to_dict_unix_timestamps_from_datetime(self, sentinel):
        """The conversion from `datetime` to a Unix timestamp should not
        alter the timestamp in any way if both are in local time."""
        s = sentinel(False)

        timestamp_data = {"a": [1580515140000]}

        schema = {"a": datetime}

        def handle_to_dict(msg):
            s.set(True)
            message = json.loads(msg)

            assert message["data"] == timestamp_data

            # convert back
            ts = datetime.fromtimestamp(message["data"]["a"][0] / 1000)

            assert ts == datetime(2020, 1, 31, 23, 59)

        message = {
            "id": 1,
            "table_name": "table1",
            "view_name": "view1",
            "cmd": "view"
        }
        manager = PerspectiveManager()

        table = Table(schema)
        table.update(timestamp_data)

        manager.host_table("table1", table)
        manager._process(message, self.post)
        to_dict_message = {
            "id": 2,
            "name": "view1",
            "cmd": "view_method",
            "method": "to_dict"
        }
        manager._process(to_dict_message, handle_to_dict)
        assert s.get() is True
Exemplo n.º 10
0
    def test_manager_view_computed_schema(self):
        post_callback = partial(self.validate_post, expected={
            "id": 1,
            "data": {
                "abc": "float"
            }
        })

        message = {"id": 1, "name": "view1", "cmd": "view_method", "method": "computed_schema", "args": [False]}
        manager = PerspectiveManager()
        table = Table(data)
        view = table.view(computed_columns=[
            {
                "column": "abc",
                "computed_function_name": "+",
                "inputs": ["a", "a"]
            }
        ])
        manager.host_table("table1", table)
        manager.host_view("view1", view)
        manager._process(message, post_callback)
Exemplo n.º 11
0
 def test_viewer_replace(self):
     table = Table({"a": [1, 2, 3]})
     viewer = PerspectiveViewer()
     viewer.load(table)
     viewer.replace({"a": [4, 5, 6]})
     assert viewer.table.size() == 3
     assert viewer.table.schema() == {
         "a": int
     }
     assert viewer.table.view().to_dict() == {
         "a": [4, 5, 6]
     }
Exemplo n.º 12
0
 def test_locked_manager_create_view(self):
     message = {
         "id": 1,
         "table_name": "table1",
         "view_name": "view1",
         "cmd": "view"
     }
     manager = PerspectiveManager(lock=True)
     table = Table(data)
     manager.host_table("table1", table)
     manager._process(message, self.post)
     assert manager._get_view("view1").schema() == {"a": int, "b": str}
Exemplo n.º 13
0
    def test_manager_create_indexed_table(self):
        message = {"id": 1, "name": "table1", "cmd": "table", "args": [data], "options": {"index": "a"}}
        manager = PerspectiveManager()
        table = Table(data)
        manager.host_table("table1", table)
        manager._process(message, self.post)
        assert manager._tables["table1"].schema() == {
            "a": int,
            "b": str
        }

        assert manager._tables["table1"].get_index() == "a"
Exemplo n.º 14
0
 def test_manager_create_view_zero(self):
     message = {
         "id": 1,
         "table_name": "table1",
         "view_name": "view1",
         "cmd": "view"
     }
     manager = PerspectiveManager()
     table = Table(data)
     manager.host_table("table1", table)
     manager._process(message, self.post)
     assert manager._views["view1"].num_rows() == 3
Exemplo n.º 15
0
 def test_view_month_of_year_date(self):
     table = Table({"a": [date(2020, i, 15) for i in range(1, 13)]})
     view = table.view(expressions=['// bucket \n month_of_year("a")'])
     assert view.schema() == {"a": date, "bucket": str}
     assert view.to_columns() == {
         "a": [datetime(2020, i, 15) for i in range(1, 13)],
         "bucket": [
             "01 January",
             "02 February",
             "03 March",
             "04 April",
             "05 May",
             "06 June",
             "07 July",
             "08 August",
             "09 September",
             "10 October",
             "11 November",
             "12 December",
         ],
     }
Exemplo n.º 16
0
 def test_to_arrow_start_end_row(self):
     data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
     tbl = Table(data)
     assert tbl.schema() == {"a": int, "b": float}
     arr = tbl.view().to_arrow(start_row=2, end_row=3)
     tbl2 = Table(arr)
     assert tbl2.view().to_dict() == {
         "a": data["a"][2:3],
         "b": data["b"][2:3]
     }
Exemplo n.º 17
0
    def test_view_expression_append(self):
        table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]})

        view = table.view(expressions=[
            '// computed \n "a" + "b"',
        ])

        assert view.schema() == {"a": int, "b": int, "computed": float}
        assert view.to_columns() == {
            "a": [1, 2, 3, 4],
            "b": [5, 6, 7, 8],
            "computed": [6, 8, 10, 12],
        }

        table.update({"a": [5, 6], "b": [9, 10]})

        assert view.to_columns() == {
            "a": [1, 2, 3, 4, 5, 6],
            "b": [5, 6, 7, 8, 9, 10],
            "computed": [6, 8, 10, 12, 14, 16],
        }
    def test_exception_from_core_correct_types(self):
        tbl = Table({"a": [1, 2, 3]})

        # `PerspectiveError` should be raised from the Python layer
        with raises(PerspectiveError) as ex:
            tbl.view()
            tbl.delete()
            assert str(
                ex.value
            ) == "Cannot delete a Table with active views still linked to it - call delete() on each view, and try again."

        with raises(PerspectiveCppError) as ex:
            tbl.view(row_pivots=["b"])
            assert str(ex.value) == "Column b does not exist in schema."
Exemplo n.º 19
0
 def test_view_delete_with_scope(self):
     """Tests that `View`'s `__del__` method, when called by the Python
     reference counter, leaves an empty `Table` in a clean state.
     """
     table = Table(
         {
             "id": int,
             "msg": str,
             "val": float
         },
         index="id",
     )
     table.view(
         computed_columns=[{
             "column": "inverted",
             "computed_function_name": "invert",
             "inputs": ["val"],
         }],
         columns=["inverted"],
     )
     table.update([{
         "id": 1,
         "msg": "test",
         "val": 1.0,
     }])
Exemplo n.º 20
0
    def test_view_expression_multiple_views_should_all_clear(self):
        table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]})

        view = table.view(expressions=[
            '// computed \n "a" + "b"',
        ])

        view2 = table.view(expressions=['// computed2 \n "a" - "b"'])

        assert view.schema() == {"a": int, "b": int, "computed": float}

        assert view2.schema() == {"a": int, "b": int, "computed2": float}

        assert view.to_columns() == {
            "a": [1, 2, 3, 4],
            "b": [5, 6, 7, 8],
            "computed": [6, 8, 10, 12],
        }

        assert view2.to_columns() == {
            "a": [1, 2, 3, 4],
            "b": [5, 6, 7, 8],
            "computed2": [-4, -4, -4, -4],
        }

        table.clear()

        assert view.schema() == {"a": int, "b": int, "computed": float}

        assert view2.schema() == {"a": int, "b": int, "computed2": float}

        assert view.to_columns() == {}

        assert view2.to_columns() == {}
Exemplo n.º 21
0
    def test_async_multiple_managers_queue_process(self):
        tbl = Table({"a": int, "b": float, "c": str})
        tbl2 = Table({"a": int, "b": float, "c": str})

        manager = PerspectiveManager()
        manager2 = PerspectiveManager()

        manager.host_table("tbl", tbl)
        manager2.host_table("tbl2", tbl2)

        manager.set_loop_callback(TestAsync.loop.add_callback)
        manager2.set_loop_callback(TestAsync.loop.add_callback)

        @syncify
        def _update_task():
            for i in range(5):
                tbl.update([data[i]])
                tbl2.update([data[i]])
            return tbl.size()

        assert _update_task() == 5

        @syncify
        def _flush_to_process():
            view = tbl2.view()
            records = view.to_records()
            for i in range(5):
                tbl2.update([data[i]])

            view.delete()
            return records

        assert _flush_to_process() == data[:5]

        @syncify
        def _delete_task():
            tbl2.delete()
            tbl.delete()

        _delete_task()
Exemplo n.º 22
0
    def test_async_multiple_managers_queue_process_multiple_ports(self):
        tbl = Table({"a": int, "b": float, "c": str})
        tbl2 = Table({"a": int, "b": float, "c": str})
        port_ids = [0]
        port_data = [{"a": 0, "b": 0, "c": "0"}]

        for i in range(10):
            port_id = tbl.make_port()
            port_id2 = tbl2.make_port()
            assert port_id == port_id2
            port_ids.append(port_id)
            port_data.append({
                "a": port_id,
                "b": port_id * 1.5,
                "c": str(port_id)
            })

        manager = PerspectiveManager()
        manager2 = PerspectiveManager()
        manager.host_table("tbl", tbl)
        manager2.host_table("tbl2", tbl2)

        manager.set_loop_callback(TestAsync.loop.add_callback)
        manager2.set_loop_callback(TestAsync.loop.add_callback)

        @syncify
        def _task():
            random.shuffle(port_ids)
            for port_id in port_ids:
                idx = port_id if port_id < len(port_ids) else len(port_ids) - 1
                tbl.update([port_data[idx]], port_id=port_id)
                tbl2.update([port_data[idx]], port_id=port_id)
            return (tbl.size(), tbl2.size())

        assert _task() == (11, 11)
Exemplo n.º 23
0
    def test_view_expression_delete_and_create_with_updates(self):
        table = Table({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]})

        view = table.view(expressions=[
            '// computed \n "a" + "b"', "upper(concat('abc', 'def'))"
        ])

        assert view.schema() == {
            "a": int,
            "b": int,
            "computed": float,
            "upper(concat('abc', 'def'))": str
        }

        table.update({"a": [5, 6], "b": [9, 10]})

        assert view.to_columns() == {
            "a": [1, 2, 3, 4, 5, 6],
            "b": [5, 6, 7, 8, 9, 10],
            "computed": [6, 8, 10, 12, 14, 16],
            "upper(concat('abc', 'def'))": ["ABCDEF" for _ in range(6)]
        }

        view.delete()

        view2 = table.view(expressions=[
            '// computed2 \n "a" - "b"',
        ])

        assert view2.schema() == {"a": int, "b": int, "computed2": float}

        table.update({"a": [5, 6], "b": [9, 10]})

        table.update({"a": [5, 6], "b": [9, 10]})

        assert view2.to_columns() == {
            "a": [1, 2, 3, 4, 5, 6, 5, 6, 5, 6],
            "b": [5, 6, 7, 8, 9, 10, 9, 10, 9, 10],
            "computed2": [-4, -4, -4, -4, -4, -4, -4, -4, -4, -4],
        }
Exemplo n.º 24
0
    def test_async_queue_process(self):
        tbl = Table({
            "a": int,
            "b": float,
            "c": str
        })
        manager = PerspectiveManager()
        manager._set_queue_process(TestAsync.wrapped_queue_process)
        manager.host(tbl)

        assert tbl.size() == 0

        for i in range(5):
            tbl.update([data[i]])

        table_id = tbl._table.get_id()
        pool = tbl._table.get_pool()

        assert _PerspectiveStateManager.TO_PROCESS == {
            table_id: pool
        }
        assert tbl.view().to_records() == data[:5]

        # should have flushed the process queue
        assert _PerspectiveStateManager.TO_PROCESS == {}
Exemplo n.º 25
0
 def test_to_arrow_date_symmetric(self):
     data = {
         "a": [date(2019, 7, 11),
               date(2016, 2, 29),
               date(2019, 12, 10)]
     }
     tbl = Table(data)
     assert tbl.schema() == {"a": date}
     arr = tbl.view().to_arrow()
     tbl2 = Table(arr)
     assert tbl2.schema() == tbl.schema()
     assert tbl2.view().to_dict() == {
         "a": [
             datetime(2019, 7, 11),
             datetime(2016, 2, 29),
             datetime(2019, 12, 10)
         ]
     }
Exemplo n.º 26
0
 def test_widget_load_table(self):
     table = Table({"a": np.arange(0, 50)})
     widget = PerspectiveWidget(table, plugin="x_bar")
     assert widget.plugin == "x_bar"
     load_msg = widget._make_load_message()
     assert load_msg.to_dict() == {
         "id": -2,
         "type": "table",
         "data": {
             "table_name": widget.table_name,
             "options": {}
         }
     }
Exemplo n.º 27
0
 def test_to_arrow_start_end_col_equiv_row(self):
     data = {"a": [None, 1, None, 2, 3], "b": [1.5, 2.5, None, 3.5, None]}
     tbl = Table(data)
     assert tbl.schema() == {"a": int, "b": float}
     arr = tbl.view().to_arrow(start_col=1,
                               end_col=1,
                               start_row=2,
                               end_row=3)
     tbl2 = Table(arr)
     # start/end col is a range - thus start=end provides no columns
     assert tbl2.view().to_dict() == {}
Exemplo n.º 28
0
 def test_manager_clear_view_no_client_id(self):
     messages = [
         {"id": 1, "table_name": "table1", "view_name": "view1", "cmd": "view"},
         {"id": 2, "table_name": "table1", "view_name": "view2", "cmd": "view"},
         {"id": 3, "table_name": "table1", "view_name": "view3", "cmd": "view"}
     ]
     manager = PerspectiveManager()
     table = Table(data)
     manager.host_table("table1", table)
     for message in messages:
         manager._process(message, self.post)
     with raises(PerspectiveError):
         manager.clear_views(None)
Exemplo n.º 29
0
 def test_manager_clear_view(self):
     messages = [
         {"id": 1, "table_name": "table1", "view_name": "view1", "cmd": "view"},
         {"id": 2, "table_name": "table1", "view_name": "view2", "cmd": "view"},
         {"id": 3, "table_name": "table1", "view_name": "view3", "cmd": "view"}
     ]
     manager = PerspectiveManager()
     table = Table(data)
     manager.host_table("table1", table)
     for message in messages:
         manager._process(message, self.post, client_id=1)
     manager.clear_views(1)
     assert manager._views == {}
Exemplo n.º 30
0
 def test_manager_host_table(self):
     message = {
         "id": 1,
         "name": "table1",
         "cmd": "table_method",
         "method": "schema",
         "args": []
     }
     manager = PerspectiveManager()
     table = Table(data)
     manager.host_table("table1", table)
     manager._process(message, self.post)
     assert manager._tables["table1"].schema() == {"a": int, "b": str}