Beispiel #1
0
  def test_create_section_existing_view(self):
    # Test that CreateViewSection works for an existing view.

    self.load_sample(self.sample)
    self.assertTables([self.starting_table])

    # Create a view + section for the initial table.
    self.apply_user_action(["CreateViewSection", 1, 0, "record", None])

    # Verify that we got a new view, with one section, and three fields.
    self.assertViews([View(1, sections=[
      Section(1, parentKey="record", tableRef=1, fields=[
        Field(1, colRef=21),
      ])
    ]) ])

    # Create a new section for the same view, check that only a section is added.
    self.apply_user_action(["CreateViewSection", 1, 1, "record", None])
    self.assertTables([self.starting_table])
    self.assertViews([View(1, sections=[
      Section(1, parentKey="record", tableRef=1, fields=[
        Field(1, colRef=21),
      ]),
      Section(2, parentKey="record", tableRef=1, fields=[
        Field(2, colRef=21),
      ])
    ]) ])

    # Create another section for the same view, this time summarized.
    self.apply_user_action(["CreateViewSection", 1, 1, "record", [21]])
    summary_table = Table(2, "GristSummary_7_Address", 0, summarySourceTable=1, columns=[
        Column(22, "city", "Text", isFormula=False, formula="", summarySourceCol=21),
        Column(23, "group", "RefList:Address", isFormula=True,
               formula="table.getSummarySourceGroup(rec)", summarySourceCol=0),
        Column(24, "count", "Int", isFormula=True, formula="len($group)", summarySourceCol=0),
      ])
    self.assertTables([self.starting_table, summary_table])
    # Check that we still have one view, with sections for different tables.
    view = View(1, sections=[
      Section(1, parentKey="record", tableRef=1, fields=[
        Field(1, colRef=21),
      ]),
      Section(2, parentKey="record", tableRef=1, fields=[
        Field(2, colRef=21),
      ]),
      Section(3, parentKey="record", tableRef=2, fields=[
        Field(3, colRef=22),
        Field(4, colRef=24),
      ]),
    ])
    self.assertTables([self.starting_table, summary_table])
    self.assertViews([view])

    # Try to create a summary table for an invalid column, and check that it fails.
    with self.assertRaises(ValueError):
      self.apply_user_action(["CreateViewSection", 1, 1, "record", [23]])
    self.assertTables([self.starting_table, summary_table])
    self.assertViews([view])
Beispiel #2
0
  def test_view_remove(self):
    # Add a couple of tables and views, to trigger creation of some related items.
    self.init_views_sample()

    # Remove a view. Ensure related items, sections, fields get removed.
    self.apply_user_action(["BulkRemoveRecord", "_grist_Views", [2,3]])

    # Verify the new structure of tables and views.
    self.assertTables([
      Table(1, "Schools", 1, 0, columns=[
        Column(1, "manualSort", "ManualSortPos", False, "", 0),
        Column(2, "city",  "Text", False, "", 0),
        Column(3, "state", "Text", False, "", 0),
        Column(4, "size",  "Numeric", False, "", 0),
      ]),
      # Note that the summary table is gone.
      Table(3, 'Table1', 4, 0, columns=[
        Column(9, "manualSort", "ManualSortPos", False, "", 0),
        Column(10, "A", "Any", True, "", 0),
        Column(11, "B", "Any", True, "", 0),
        Column(12, "C", "Any", True, "", 0),
      ]),
    ])
    self.assertViews([
      View(1, sections=[
        Section(1, parentKey="record", tableRef=1, fields=[
          Field(1, colRef=2),
          Field(2, colRef=3),
          Field(3, colRef=4),
        ]),
      ]),
      View(4, sections=[
        Section(5, parentKey='record', tableRef=3, fields=[
          Field(12, colRef=10),
          Field(13, colRef=11),
          Field(14, colRef=12),
        ]),
      ]),
    ])
    self.assertTableData('_grist_TableViews', data=[
      ["id",  "tableRef", "viewRef"],
    ])
    self.assertTableData('_grist_TabBar', cols="subset", data=[
      ["id",  "viewRef"],
      [1,     1],
      [4,     4],
    ])
    self.assertTableData('_grist_Pages', cols="subset", data=[
      ["id",  "viewRef"],
      [1,     1],
      [4,     4],
    ])
Beispiel #3
0
  def test_section_removes(self):
    # Add a couple of tables and views, to trigger creation of some related items.
    self.init_views_sample()

    # Remove a couple of sections. Ensure their fields get removed.
    self.apply_user_action(['BulkRemoveRecord', '_grist_Views_section', [3,6]])

    self.assertViews([
      View(1, sections=[
        Section(1, parentKey="record", tableRef=1, fields=[
          Field(1, colRef=2),
          Field(2, colRef=3),
          Field(3, colRef=4),
        ]),
      ]),
      View(2, sections=[
        Section(2, parentKey="detail", tableRef=1, fields=[
          Field(4, colRef=2),
          Field(5, colRef=3),
          Field(6, colRef=4),
        ]),
      ]),
      View(3, sections=[
        Section(4, parentKey="chart", tableRef=1, fields=[
          Field(10, colRef=2),
          Field(11, colRef=3),
        ]),
      ]),
      View(4, sections=[
        Section(5, parentKey='record', tableRef=3, fields=[
          Field(12, colRef=10),
          Field(13, colRef=11),
          Field(14, colRef=12),
        ]),
      ]),
    ])
  def test_create_view_section(self):
    self.load_sample(self.sample)

    # Verify the starting table; there should be no views yet.
    self.assertTables([self.starting_table])
    self.assertViews([])

    # Create a view + section for the initial table.
    self.apply_user_action(["CreateViewSection", 1, 0, "record", None])

    # Verify that we got a new view, with one section, and three fields.
    self.assertTables([self.starting_table])
    basic_view = View(1, sections=[
      Section(1, parentKey="record", tableRef=1, fields=[
        Field(1, colRef=11),
        Field(2, colRef=12),
        Field(3, colRef=13),
      ])
    ])
    self.assertViews([basic_view])

    self.assertTableData("Address", self.starting_table_data)

    # Create a "Totals" section, i.e. a summary with no group-by columns.
    self.apply_user_action(["CreateViewSection", 1, 0, "record", []])

    # Verify that a new table gets created, and a new view, with a section for that table,
    # and some auto-generated summary fields.
    summary_table1 = Table(2, "GristSummary_7_Address", primaryViewId=0, summarySourceTable=1,
                           columns=[
      Column(14, "group", "RefList:Address", isFormula=True, summarySourceCol=0,
             formula="table.getSummarySourceGroup(rec)"),
      Column(15, "count", "Int", isFormula=True, summarySourceCol=0,
             formula="len($group)"),
      Column(16, "amount", "Numeric", isFormula=True, summarySourceCol=0,
             formula="SUM($group.amount)"),
    ])
    summary_view1 = View(2, sections=[
      Section(2, parentKey="record", tableRef=2, fields=[
        Field(4, colRef=15),
        Field(5, colRef=16),
      ])
    ])
    self.assertTables([self.starting_table, summary_table1])
    self.assertViews([basic_view, summary_view1])

    # Verify the summarized data.
    self.assertTableData('GristSummary_7_Address', cols="subset", data=[
      [ "id", "count",  "amount"],
      [ 1,    11,       66.0    ],
    ])

    # Create a summary section, grouped by the "State" column.
    self.apply_user_action(["CreateViewSection", 1, 0, "record", [12]])

    # Verify that a new table gets created again, a new view, and a section for that table.
    # Note that we also check that summarySourceTable and summarySourceCol fields are correct.
    summary_table2 = Table(3, "GristSummary_7_Address2", primaryViewId=0, summarySourceTable=1,
                           columns=[
      Column(17, "state", "Text", isFormula=False, formula="", summarySourceCol=12),
      Column(18, "group", "RefList:Address", isFormula=True, summarySourceCol=0,
             formula="table.getSummarySourceGroup(rec)"),
      Column(19, "count", "Int", isFormula=True, summarySourceCol=0,
             formula="len($group)"),
      Column(20, "amount", "Numeric", isFormula=True, summarySourceCol=0,
             formula="SUM($group.amount)"),
    ])
    summary_view2 = View(3, sections=[
      Section(3, parentKey="record", tableRef=3, fields=[
        Field(6, colRef=17),
        Field(7, colRef=19),
        Field(8, colRef=20),
      ])
    ])
    self.assertTables([self.starting_table, summary_table1, summary_table2])
    self.assertViews([basic_view, summary_view1, summary_view2])

    # Verify more fields of the new column objects.
    self.assertTableData('_grist_Tables_column', rows="subset", cols="subset", data=[
      ['id', 'colId',  'type',    'formula',            'widgetOptions', 'label'],
      [17,   'state',  'Text',    '',                   'WidgetOptions1', 'State'],
      [20,   'amount', 'Numeric', 'SUM($group.amount)', 'WidgetOptions2', 'Amount'],
    ])

    # Verify the summarized data.
    self.assertTableData('GristSummary_7_Address2', cols="subset", data=[
      [ "id", "state", "count", "amount"          ],
      [ 1,    "NY",     7,      1.+2+6+7+8+10+11  ],
      [ 2,    "WA",     1,      3.                ],
      [ 3,    "IL",     1,      4.                ],
      [ 4,    "MA",     2,      5.+9              ],
    ])

    # Create a summary section grouped by two columns ("city" and "state").
    self.apply_user_action(["CreateViewSection", 1, 0, "record", [11,12]])

    # Verify the new table and views.
    summary_table3 = Table(4, "GristSummary_7_Address3", primaryViewId=0, summarySourceTable=1,
                           columns=[
      Column(21, "city", "Text", isFormula=False, formula="", summarySourceCol=11),
      Column(22, "state", "Text", isFormula=False, formula="", summarySourceCol=12),
      Column(23, "group", "RefList:Address", isFormula=True, summarySourceCol=0,
             formula="table.getSummarySourceGroup(rec)"),
      Column(24, "count", "Int", isFormula=True, summarySourceCol=0,
             formula="len($group)"),
      Column(25, "amount", "Numeric", isFormula=True, summarySourceCol=0,
             formula="SUM($group.amount)"),
    ])
    summary_view3 = View(4, sections=[
      Section(4, parentKey="record", tableRef=4, fields=[
        Field(9, colRef=21),
        Field(10, colRef=22),
        Field(11, colRef=24),
        Field(12, colRef=25),
      ])
    ])
    self.assertTables([self.starting_table, summary_table1, summary_table2, summary_table3])
    self.assertViews([basic_view, summary_view1, summary_view2, summary_view3])

    # Verify the summarized data.
    self.assertTableData('GristSummary_7_Address3', cols="subset", data=[
      [ "id", "city",     "state", "count", "amount"  ],
      [ 1,    "New York", "NY"   , 3,       1.+6+11   ],
      [ 2,    "Albany",   "NY"   , 1,       2.        ],
      [ 3,    "Seattle",  "WA"   , 1,       3.        ],
      [ 4,    "Chicago",  "IL"   , 1,       4.        ],
      [ 5,    "Bedford",  "MA"   , 1,       5.        ],
      [ 6,    "Buffalo",  "NY"   , 1,       7.        ],
      [ 7,    "Bedford",  "NY"   , 1,       8.        ],
      [ 8,    "Boston",   "MA"   , 1,       9.        ],
      [ 9,    "Yonkers",  "NY"   , 1,       10.       ],
    ])

    # The original table's data should not have changed.
    self.assertTableData("Address", self.starting_table_data)
  def test_summary_table_reuse(self):
    # Test that we'll reuse a suitable summary table when already available.

    self.load_sample(self.sample)

    # Create a summary section grouped by two columns ("city" and "state").
    self.apply_user_action(["CreateViewSection", 1, 0, "record", [11,12]])

    # Verify the new table and views.
    summary_table = Table(2, "GristSummary_7_Address", primaryViewId=0, summarySourceTable=1,
                           columns=[
      Column(14, "city", "Text", isFormula=False, formula="", summarySourceCol=11),
      Column(15, "state", "Text", isFormula=False, formula="", summarySourceCol=12),
      Column(16, "group", "RefList:Address", isFormula=True, summarySourceCol=0,
             formula="table.getSummarySourceGroup(rec)"),
      Column(17, "count", "Int", isFormula=True, summarySourceCol=0,
             formula="len($group)"),
      Column(18, "amount", "Numeric", isFormula=True, summarySourceCol=0,
             formula="SUM($group.amount)"),
    ])
    summary_view = View(1, sections=[
      Section(1, parentKey="record", tableRef=2, fields=[
        Field(1, colRef=14),
        Field(2, colRef=15),
        Field(3, colRef=17),
        Field(4, colRef=18),
      ])
    ])
    self.assertTables([self.starting_table, summary_table])
    self.assertViews([summary_view])

    # Create twoo other views + view sections with the same breakdown (in different order
    # of group-by fields, which should still reuse the same table).
    self.apply_user_action(["CreateViewSection", 1, 0, "record", [12,11]])
    self.apply_user_action(["CreateViewSection", 1, 0, "record", [11,12]])
    summary_view2 = View(2, sections=[
      Section(2, parentKey="record", tableRef=2, fields=[
        Field(5, colRef=15),
        Field(6, colRef=14),
        Field(7, colRef=17),
        Field(8, colRef=18),
      ])
    ])
    summary_view3 = View(3, sections=[
      Section(3, parentKey="record", tableRef=2, fields=[
        Field(9, colRef=14),
        Field(10, colRef=15),
        Field(11, colRef=17),
        Field(12, colRef=18),
      ])
    ])
    # Verify that we have a new view, but are reusing the table.
    self.assertTables([self.starting_table, summary_table])
    self.assertViews([summary_view, summary_view2, summary_view3])

    # Verify the summarized data.
    self.assertTableData('GristSummary_7_Address', cols="subset", data=[
      [ "id", "city",     "state", "count", "amount"  ],
      [ 1,    "New York", "NY"   , 3,       1.+6+11   ],
      [ 2,    "Albany",   "NY"   , 1,       2.        ],
      [ 3,    "Seattle",  "WA"   , 1,       3.        ],
      [ 4,    "Chicago",  "IL"   , 1,       4.        ],
      [ 5,    "Bedford",  "MA"   , 1,       5.        ],
      [ 6,    "Buffalo",  "NY"   , 1,       7.        ],
      [ 7,    "Bedford",  "NY"   , 1,       8.        ],
      [ 8,    "Boston",   "MA"   , 1,       9.        ],
      [ 9,    "Yonkers",  "NY"   , 1,       10.       ],
    ])
Beispiel #6
0
    def test_table_removes(self):
        # Verify table removals triggered by UpdateRecord actions, and related behavior.

        # Same setup as previous test.
        self.init_sample_data()

        # Add one more table, and one more view for tables #1 and #4 (those we are about to delete).
        self.apply_user_action(["AddEmptyTable"])
        out_actions = self.apply_user_action(
            ["CreateViewSection", 1, 0, 'detail', None])
        self.assertEqual(out_actions.retValues[0]["viewRef"], 5)
        self.apply_user_action(["CreateViewSection", 4, 5, 'detail', None])

        # See what's in TableViews and TabBar tables, to verify after we remove a table.
        self.assertTableData('_grist_TableViews',
                             data=[
                                 ["id", "tableRef", "viewRef"],
                                 [1, 1, 3],
                                 [2, 1, 5],
                             ])
        self.assertTableData('_grist_TabBar',
                             cols="subset",
                             data=[
                                 ["id", "viewRef"],
                                 [1, 1],
                                 [2, 2],
                                 [3, 3],
                                 [4, 4],
                                 [5, 5],
                             ])

        # Remove two tables, ensure certain views get removed.
        self.apply_user_action(["BulkRemoveRecord", "_grist_Tables", [1, 4]])

        # See that some TableViews/TabBar entries disappear, or tableRef gets unset.
        self.assertTableData('_grist_TableViews',
                             data=[
                                 ["id", "tableRef", "viewRef"],
                                 [1, 0, 3],
                             ])
        self.assertTableData('_grist_TabBar',
                             cols="subset",
                             data=[
                                 ["id", "viewRef"],
                                 [2, 2],
                                 [3, 3],
                             ])

        # Check that reference columns to this table get removed, with associated fields.
        self.assertTables([
            Table(2,
                  "People",
                  primaryViewId=2,
                  summarySourceTable=0,
                  columns=[
                      Column(5, "manualSort", "ManualSortPos", False, "", 0),
                      Column(6, "name", "Text", False, "", 0),
                      Column(8, "city", "Any", True, "$address.city", 0),
                  ]),
            # Note that the summary table is also gone.
        ])
        self.assertViews([
            View(2,
                 sections=[
                     Section(2,
                             parentKey="record",
                             tableRef=2,
                             fields=[
                                 Field(4, colRef=6),
                                 Field(6, colRef=8),
                             ]),
                 ]),
            View(3,
                 sections=[
                     Section(5,
                             parentKey="record",
                             tableRef=2,
                             fields=[
                                 Field(13, colRef=6),
                                 Field(15, colRef=8),
                             ]),
                 ]),
        ])
Beispiel #7
0
    def init_sample_data(self):
        # Add a couple of tables, including references.
        self.apply_user_action([
            "AddTable", "Address",
            [
                {
                    "id": "city",
                    "type": "Text"
                },
                {
                    "id": "state",
                    "type": "Text"
                },
                {
                    "id": "amount",
                    "type": "Numeric"
                },
            ]
        ])
        self.apply_user_action([
            "AddTable", "People",
            [{
                "id": "name",
                "type": "Text"
            }, {
                "id": "address",
                "type": "Ref:Address"
            }, {
                "id": "city",
                "type": "Any",
                "formula": "$address.city"
            }]
        ])

        # Populate some data.
        d = testutil.table_data_from_rows("Address",
                                          self.address_table_data[0],
                                          self.address_table_data[1:])
        self.apply_user_action(
            ["BulkAddRecord", "Address", d.row_ids, d.columns])

        d = testutil.table_data_from_rows("People", self.people_table_data[0],
                                          self.people_table_data[1:])
        self.apply_user_action(
            ["BulkAddRecord", "People", d.row_ids, d.columns])

        # Add a view with several sections, including a summary table.
        self.apply_user_action(["CreateViewSection", 1, 0, 'record', None])
        self.apply_user_action(["CreateViewSection", 1, 3, 'record', [3]])
        self.apply_user_action(["CreateViewSection", 2, 3, 'record', None])

        # Verify the new structure of tables and views.
        self.assertTables([
            Table(1,
                  "Address",
                  primaryViewId=1,
                  summarySourceTable=0,
                  columns=[
                      Column(1, "manualSort", "ManualSortPos", False, "", 0),
                      Column(2, "city", "Text", False, "", 0),
                      Column(3, "state", "Text", False, "", 0),
                      Column(4, "amount", "Numeric", False, "", 0),
                  ]),
            Table(2,
                  "People",
                  primaryViewId=2,
                  summarySourceTable=0,
                  columns=[
                      Column(5, "manualSort", "ManualSortPos", False, "", 0),
                      Column(6, "name", "Text", False, "", 0),
                      Column(7, "address", "Ref:Address", False, "", 0),
                      Column(8, "city", "Any", True, "$address.city", 0),
                  ]),
            Table(3,
                  "GristSummary_7_Address",
                  0,
                  1,
                  columns=[
                      Column(9, "state", "Text", False, "",
                             summarySourceCol=3),
                      Column(10,
                             "group",
                             "RefList:Address",
                             True,
                             summarySourceCol=0,
                             formula="table.getSummarySourceGroup(rec)"),
                      Column(11,
                             "count",
                             "Int",
                             True,
                             summarySourceCol=0,
                             formula="len($group)"),
                      Column(12,
                             "amount",
                             "Numeric",
                             True,
                             summarySourceCol=0,
                             formula="SUM($group.amount)"),
                  ]),
        ])
        self.assertViews([
            View(1,
                 sections=[
                     Section(1,
                             parentKey="record",
                             tableRef=1,
                             fields=[
                                 Field(1, colRef=2),
                                 Field(2, colRef=3),
                                 Field(3, colRef=4),
                             ]),
                 ]),
            View(2,
                 sections=[
                     Section(2,
                             parentKey="record",
                             tableRef=2,
                             fields=[
                                 Field(4, colRef=6),
                                 Field(5, colRef=7),
                                 Field(6, colRef=8),
                             ]),
                 ]),
            View(3,
                 sections=[
                     Section(3,
                             parentKey="record",
                             tableRef=1,
                             fields=[
                                 Field(7, colRef=2),
                                 Field(8, colRef=3),
                                 Field(9, colRef=4),
                             ]),
                     Section(4,
                             parentKey="record",
                             tableRef=3,
                             fields=[
                                 Field(10, colRef=9),
                                 Field(11, colRef=11),
                                 Field(12, colRef=12),
                             ]),
                     Section(5,
                             parentKey="record",
                             tableRef=2,
                             fields=[
                                 Field(13, colRef=6),
                                 Field(14, colRef=7),
                                 Field(15, colRef=8),
                             ]),
                 ]),
        ])

        # Verify the data we've loaded.
        self.assertTableData('Address',
                             cols="subset",
                             data=self.address_table_data)
        self.assertTableData('People',
                             cols="subset",
                             data=self.people_table_data)
        self.assertTableData("GristSummary_7_Address",
                             cols="subset",
                             data=[
                                 ["id", "state", "count", "amount"],
                                 [1, "NY", 7, 1. + 2 + 6 + 7 + 8 + 10 + 11],
                                 [2, "WA", 1, 3.],
                                 [3, "IL", 1, 4.],
                                 [4, "MA", 2, 5. + 9],
                             ])
Beispiel #8
0
  def init_views_sample(self):
    # Add a new table and a view, to get some Views/Sections/Fields, and TableView/TabBar items.
    self.apply_user_action(['AddTable', 'Schools', [
      {'id': 'city', 'type': 'Text'},
      {'id': 'state', 'type': 'Text'},
      {'id': 'size', 'type': 'Numeric'},
    ]])
    self.apply_user_action(['BulkAddRecord', 'Schools', [1,2,3,4], {
      'city': ['New York', 'Colombia', 'New York', ''],
      'state': ['NY', 'NY', 'NY', ''],
      'size': [1000, 2000, 3000, 4000],
    }])
    # Add a new view; a second section (summary) to it; and a third view.
    self.apply_user_action(['CreateViewSection', 1, 0, 'detail', None])
    self.apply_user_action(['CreateViewSection', 1, 2, 'record', [3]])
    self.apply_user_action(['CreateViewSection', 1, 0, 'chart', None])
    self.apply_user_action(['CreateViewSection', 0, 2, 'record', None])

    # Verify the new structure of tables and views.
    self.assertTables([
      Table(1, "Schools", 1, 0, columns=[
        Column(1, "manualSort", "ManualSortPos", False, "", 0),
        Column(2, "city",  "Text", False, "", 0),
        Column(3, "state", "Text", False, "", 0),
        Column(4, "size",  "Numeric", False, "", 0),
      ]),
      Table(2, "GristSummary_7_Schools", 0, 1, columns=[
        Column(5, "state", "Text", False, "", 3),
        Column(6, "group", "RefList:Schools", True, "table.getSummarySourceGroup(rec)", 0),
        Column(7, "count", "Int",     True, "len($group)", 0),
        Column(8, "size",  "Numeric", True, "SUM($group.size)", 0),
      ]),
      Table(3, 'Table1', 4, 0, columns=[
        Column(9, "manualSort", "ManualSortPos", False, "", 0),
        Column(10, "A", "Any", True, "", 0),
        Column(11, "B", "Any", True, "", 0),
        Column(12, "C", "Any", True, "", 0),
      ]),
    ])
    self.assertViews([
      View(1, sections=[
        Section(1, parentKey="record", tableRef=1, fields=[
          Field(1, colRef=2),
          Field(2, colRef=3),
          Field(3, colRef=4),
        ]),
      ]),
      View(2, sections=[
        Section(2, parentKey="detail", tableRef=1, fields=[
          Field(4, colRef=2),
          Field(5, colRef=3),
          Field(6, colRef=4),
        ]),
        Section(3, parentKey="record", tableRef=2, fields=[
          Field(7, colRef=5),
          Field(8, colRef=7),
          Field(9, colRef=8),
        ]),
        Section(6, parentKey='record', tableRef=3, fields=[
          Field(15, colRef=10),
          Field(16, colRef=11),
          Field(17, colRef=12),
        ]),
      ]),
      View(3, sections=[
        Section(4, parentKey="chart", tableRef=1, fields=[
          Field(10, colRef=2),
          Field(11, colRef=3),
        ]),
      ]),
      View(4, sections=[
        Section(5, parentKey='record', tableRef=3, fields=[
          Field(12, colRef=10),
          Field(13, colRef=11),
          Field(14, colRef=12),
        ]),
      ]),
    ])
    self.assertTableData('_grist_TableViews', data=[
      ["id",  "tableRef", "viewRef"],
      [1,     1,          2],
      [2,     1,          3],
    ])
    self.assertTableData('_grist_TabBar', cols="subset", data=[
      ["id",  "viewRef"],
      [1,     1],
      [2,     2],
      [3,     3],
      [4,     4],
    ])
    self.assertTableData('_grist_Pages', cols="subset", data=[
      ["id", "viewRef"],
      [1,    1],
      [2,    2],
      [3,    3],
      [4,    4]
    ])
Beispiel #9
0
  def test_creates_section_new_table(self):
    # Test that CreateViewSection works for adding a new table.

    self.load_sample(self.sample)
    self.assertTables([self.starting_table])
    self.assertViews([])

    # When we create a section/view for new table, we get both a primary view, and the new view we
    # are creating.
    self.apply_user_action(["CreateViewSection", 0, 0, "record", None])
    new_table = Table(2, "Table1", primaryViewId=1, summarySourceTable=0, columns=[
      Column(22, "manualSort", "ManualSortPos", isFormula=False, formula="", summarySourceCol=0),
      Column(23, "A", "Any", isFormula=True, formula="", summarySourceCol=0),
      Column(24, "B", "Any", isFormula=True, formula="", summarySourceCol=0),
      Column(25, "C", "Any", isFormula=True, formula="", summarySourceCol=0),
    ])
    primary_view = View(1, sections=[
      Section(1, parentKey="record", tableRef=2, fields=[
        Field(1, colRef=23),
        Field(2, colRef=24),
        Field(3, colRef=25),
      ])
    ])
    new_view = View(2, sections=[
      Section(2, parentKey="record", tableRef=2, fields=[
        Field(4, colRef=23),
        Field(5, colRef=24),
        Field(6, colRef=25),
      ])
    ])
    self.assertTables([self.starting_table, new_table])
    self.assertViews([primary_view, new_view])

    # Create another section in an existing view for a new table.
    self.apply_user_action(["CreateViewSection", 0, 2, "record", None])
    new_table2 = Table(3, "Table2", primaryViewId=3, summarySourceTable=0, columns=[
      Column(26, "manualSort", "ManualSortPos", isFormula=False, formula="", summarySourceCol=0),
      Column(27, "A", "Any", isFormula=True, formula="", summarySourceCol=0),
      Column(28, "B", "Any", isFormula=True, formula="", summarySourceCol=0),
      Column(29, "C", "Any", isFormula=True, formula="", summarySourceCol=0),
    ])
    primary_view2 = View(3, sections=[
      Section(3, parentKey="record", tableRef=3, fields=[
        Field(7, colRef=27),
        Field(8, colRef=28),
        Field(9, colRef=29),
      ])
    ])
    new_view.sections.append(
      Section(4, parentKey="record", tableRef=3, fields=[
        Field(10, colRef=27),
        Field(11, colRef=28),
        Field(12, colRef=29),
      ])
    )
    # Check that we have a new table, only the primary view as new view; and a new section.
    self.assertTables([self.starting_table, new_table, new_table2])
    self.assertViews([primary_view, new_view, primary_view2])

    # Check that we can't create a summary of a table grouped by a column that doesn't exist yet.
    with self.assertRaises(ValueError):
      self.apply_user_action(["CreateViewSection", 0, 2, "record", [31]])
    self.assertTables([self.starting_table, new_table, new_table2])
    self.assertViews([primary_view, new_view, primary_view2])

    # But creating a new table and showing totals for it is possible though dumb.
    self.apply_user_action(["CreateViewSection", 0, 2, "record", []])

    # We expect a new table.
    new_table3 = Table(4, "Table3", primaryViewId=4, summarySourceTable=0, columns=[
      Column(30, "manualSort", "ManualSortPos", isFormula=False, formula="", summarySourceCol=0),
      Column(31, "A", "Any", isFormula=True, formula="", summarySourceCol=0),
      Column(32, "B", "Any", isFormula=True, formula="", summarySourceCol=0),
      Column(33, "C", "Any", isFormula=True, formula="", summarySourceCol=0),
    ])
    # A summary of it.
    summary_table = Table(5, "GristSummary_6_Table3", 0, summarySourceTable=4, columns=[
      Column(34, "group", "RefList:Table3", isFormula=True,
             formula="table.getSummarySourceGroup(rec)", summarySourceCol=0),
      Column(35, "count", "Int", isFormula=True, formula="len($group)", summarySourceCol=0),
    ])
    # The primary view of the new table.
    primary_view3 = View(4, sections=[
      Section(5, parentKey="record", tableRef=4, fields=[
        Field(13, colRef=31),
        Field(14, colRef=32),
        Field(15, colRef=33),
      ])
    ])
    # And a new view section for the summary.
    new_view.sections.append(Section(6, parentKey="record", tableRef=5, fields=[
      Field(16, colRef=35)
    ]))
    self.assertTables([self.starting_table, new_table, new_table2, new_table3, summary_table])
    self.assertViews([primary_view, new_view, primary_view2, primary_view3])
    def test_summary_column_removals(self):
        # Verify that when we remove a column used for summary-table group-by, it updates summary
        # tables appropriately.

        self.init_sample_data()

        # Test that we cannot remove group-by columns from summary tables directly.
        with self.assertRaisesRegex(ValueError, "cannot remove .* group-by"):
            self.apply_user_action(
                ["BulkRemoveRecord", '_grist_Tables_column', [20, 18]])

        # Test that group-by columns in summary tables get removed.
        self.apply_user_action(
            ["BulkRemoveRecord", '_grist_Tables_column', [11, 12, 16]])

        # Verify the new structure of tables and views.
        self.assertTables([
            Table(1,
                  "Address",
                  primaryViewId=0,
                  summarySourceTable=0,
                  columns=[
                      Column(13, "amount", "Numeric", False, "", 0),
                  ]),
            Table(2,
                  "Table1",
                  2,
                  0,
                  columns=[
                      Column(14, "manualSort", "ManualSortPos", False, "", 0),
                      Column(15, "A", "Text", False, "", 0),
                      Column(17, "C", "Text", False, "", 0),
                  ]),
            # Note that the summary table here switches to a new one, without the deleted group-by.
            Table(4,
                  "GristSummary_7_Address2",
                  0,
                  1,
                  columns=[
                      Column(22,
                             "count",
                             "Int",
                             True,
                             summarySourceCol=0,
                             formula="len($group)"),
                      Column(23,
                             "amount",
                             "Numeric",
                             True,
                             summarySourceCol=0,
                             formula="SUM($group.amount)"),
                      Column(24,
                             "group",
                             "RefList:Address",
                             True,
                             summarySourceCol=0,
                             formula="table.getSummarySourceGroup(rec)"),
                  ]),
        ])
        self.assertViews([
            View(1,
                 sections=[
                     Section(1,
                             parentKey="record",
                             tableRef=1,
                             fields=[
                                 Field(3, colRef=13),
                             ]),
                     Section(4,
                             parentKey="record",
                             tableRef=2,
                             fields=[
                                 Field(10, colRef=15),
                                 Field(12, colRef=17),
                             ]),
                     Section(5,
                             parentKey="record",
                             tableRef=4,
                             fields=[
                                 Field(14, colRef=22),
                                 Field(15, colRef=23),
                             ]),
                 ]),
            View(2,
                 sections=[
                     Section(2,
                             parentKey="record",
                             tableRef=2,
                             fields=[
                                 Field(4, colRef=15),
                                 Field(6, colRef=17),
                             ]),
                 ])
        ])

        # Verify the data itself.
        self.assertTableData('Address',
                             data=[
                                 ["id", "amount"],
                                 [21, 1.],
                                 [22, 2.],
                                 [23, 3.],
                                 [24, 4.],
                                 [25, 5.],
                                 [26, 6.],
                                 [27, 7.],
                                 [28, 8.],
                                 [29, 9.],
                                 [30, 10.],
                                 [31, 11.],
                             ])
        self.assertTableData('Table1',
                             data=[
                                 ["id", "A", "C", "manualSort"],
                                 [1, "a", "", 1.0],
                                 [2, "b", "", 2.0],
                                 [3, "c", "", 3.0],
                             ])
        self.assertTableData("GristSummary_7_Address2",
                             cols="subset",
                             data=[
                                 ["id", "count", "amount"],
                                 [
                                     1, 7 + 1 + 1 + 2, 1. + 2 + 6 + 7 + 8 +
                                     10 + 11 + 3 + 4 + 5 + 9
                                 ],
                             ])
    def test_column_removals(self):
        # Verify removal of fields when columns are removed.

        self.init_sample_data()

        # Add link{Src,Target}ColRef to ViewSections. These aren't actually meaningful links, but they
        # should still get cleared automatically when columns get removed.
        self.apply_user_action([
            'UpdateRecord', '_grist_Views_section', 2, {
                'linkSrcSectionRef': 1,
                'linkSrcColRef': 11,
                'linkTargetColRef': 16
            }
        ])
        self.assertTableData('_grist_Views_section',
                             cols="subset",
                             rows="subset",
                             data=[
                                 [
                                     "id", "linkSrcSectionRef",
                                     "linkSrcColRef", "linkTargetColRef"
                                 ],
                                 [2, 1, 11, 16],
                             ])

        # Test that we can remove multiple columns using BulkUpdateRecord.
        self.apply_user_action(
            ["BulkRemoveRecord", '_grist_Tables_column', [11, 16]])

        # Test that link{Src,Target}colRef back-references get unset.
        self.assertTableData('_grist_Views_section',
                             cols="subset",
                             rows="subset",
                             data=[
                                 [
                                     "id", "linkSrcSectionRef",
                                     "linkSrcColRef", "linkTargetColRef"
                                 ],
                                 [2, 1, 0, 0],
                             ])

        # Test that columns and section fields got removed.
        self.assertTables([
            Table(1,
                  "Address",
                  primaryViewId=0,
                  summarySourceTable=0,
                  columns=[
                      Column(12, "state", "Text", False, "", 0),
                      Column(13, "amount", "Numeric", False, "", 0),
                  ]),
            Table(2,
                  "Table1",
                  2,
                  0,
                  columns=[
                      Column(14, "manualSort", "ManualSortPos", False, "", 0),
                      Column(15, "A", "Text", False, "", 0),
                      Column(17, "C", "Text", False, "", 0),
                  ]),
            Table(3,
                  "GristSummary_7_Address",
                  0,
                  1,
                  columns=[
                      Column(18,
                             "state",
                             "Text",
                             False,
                             "",
                             summarySourceCol=12),
                      Column(19,
                             "group",
                             "RefList:Address",
                             True,
                             summarySourceCol=0,
                             formula="table.getSummarySourceGroup(rec)"),
                      Column(20,
                             "count",
                             "Int",
                             True,
                             summarySourceCol=0,
                             formula="len($group)"),
                      Column(21,
                             "amount",
                             "Numeric",
                             True,
                             summarySourceCol=0,
                             formula="SUM($group.amount)"),
                  ]),
        ])
        self.assertViews([
            View(1,
                 sections=[
                     Section(1,
                             parentKey="record",
                             tableRef=1,
                             fields=[
                                 Field(2, colRef=12),
                                 Field(3, colRef=13),
                             ]),
                     Section(4,
                             parentKey="record",
                             tableRef=2,
                             fields=[
                                 Field(10, colRef=15),
                                 Field(12, colRef=17),
                             ]),
                     Section(5,
                             parentKey="record",
                             tableRef=3,
                             fields=[
                                 Field(13, colRef=18),
                                 Field(14, colRef=20),
                                 Field(15, colRef=21),
                             ]),
                 ]),
            View(2,
                 sections=[
                     Section(2,
                             parentKey="record",
                             tableRef=2,
                             fields=[
                                 Field(4, colRef=15),
                                 Field(6, colRef=17),
                             ]),
                 ])
        ])
    def init_sample_data(self):
        # Add a new view with a section, and a new table to that view, and a summary table.
        self.load_sample(self.sample2)
        self.apply_user_action(["CreateViewSection", 1, 0, "record", None])
        self.apply_user_action(["CreateViewSection", 0, 1, "record", None])
        self.apply_user_action(["CreateViewSection", 1, 1, "record", [12]])
        self.apply_user_action([
            "BulkAddRecord", "Table1", [None] * 3, {
                "A": ["a", "b", "c"],
                "B": ["d", "e", "f"],
                "C": ["", "", ""]
            }
        ])

        # Verify the new structure of tables and views.
        self.assertTables([
            Table(1,
                  "Address",
                  primaryViewId=0,
                  summarySourceTable=0,
                  columns=[
                      Column(11, "city", "Text", False, "", 0),
                      Column(12, "state", "Text", False, "", 0),
                      Column(13, "amount", "Numeric", False, "", 0),
                  ]),
            Table(2,
                  "Table1",
                  2,
                  0,
                  columns=[
                      Column(14, "manualSort", "ManualSortPos", False, "", 0),
                      Column(15, "A", "Text", False, "", 0),
                      Column(16, "B", "Text", False, "", 0),
                      Column(17, "C", "Text", False, "", 0),
                  ]),
            Table(3,
                  "GristSummary_7_Address",
                  0,
                  1,
                  columns=[
                      Column(18,
                             "state",
                             "Text",
                             False,
                             "",
                             summarySourceCol=12),
                      Column(19,
                             "group",
                             "RefList:Address",
                             True,
                             summarySourceCol=0,
                             formula="table.getSummarySourceGroup(rec)"),
                      Column(20,
                             "count",
                             "Int",
                             True,
                             summarySourceCol=0,
                             formula="len($group)"),
                      Column(21,
                             "amount",
                             "Numeric",
                             True,
                             summarySourceCol=0,
                             formula="SUM($group.amount)"),
                  ]),
        ])
        self.assertViews([
            View(1,
                 sections=[
                     Section(1,
                             parentKey="record",
                             tableRef=1,
                             fields=[
                                 Field(1, colRef=11),
                                 Field(2, colRef=12),
                                 Field(3, colRef=13),
                             ]),
                     Section(4,
                             parentKey="record",
                             tableRef=2,
                             fields=[
                                 Field(10, colRef=15),
                                 Field(11, colRef=16),
                                 Field(12, colRef=17),
                             ]),
                     Section(5,
                             parentKey="record",
                             tableRef=3,
                             fields=[
                                 Field(13, colRef=18),
                                 Field(14, colRef=20),
                                 Field(15, colRef=21),
                             ]),
                 ]),
            View(2,
                 sections=[
                     Section(2,
                             parentKey="record",
                             tableRef=2,
                             fields=[
                                 Field(4, colRef=15),
                                 Field(5, colRef=16),
                                 Field(6, colRef=17),
                             ]),
                 ])
        ])
        self.assertTableData('Address', data=self.address_table_data)
        self.assertTableData('Table1',
                             data=[
                                 ["id", "A", "B", "C", "manualSort"],
                                 [1, "a", "d", "", 1.0],
                                 [2, "b", "e", "", 2.0],
                                 [3, "c", "f", "", 3.0],
                             ])
        self.assertTableData("GristSummary_7_Address",
                             cols="subset",
                             data=[
                                 ["id", "state", "count", "amount"],
                                 [1, "NY", 7, 1. + 2 + 6 + 7 + 8 + 10 + 11],
                                 [2, "WA", 1, 3.],
                                 [3, "IL", 1, 4.],
                                 [4, "MA", 2, 5. + 9],
                             ])