2222 'filtering.twb'
2323)
2424
25+ WORKSHEET_NO_DATASOURCES_FILE = os .path .join (
26+ TEST_ASSET_DIR ,
27+ 'worksheet_no_datasources.twb'
28+ )
29+
30+ WORKSHEET_NO_SHELVES_FILE = os .path .join (
31+ TEST_ASSET_DIR ,
32+ 'worksheet_no_shelves.twb'
33+ )
34+
2535
2636class EphemeralFields (unittest .TestCase ):
2737 def test_ephemeral_fields_do_not_cause_errors (self ):
@@ -56,4 +66,72 @@ def test_worksheets_setup(self):
5666 self .assertEqual (len (wb .worksheet_items ), 2 )
5767 worksheet_names = [ws .name for ws in wb .worksheet_items ]
5868 worksheet_names .sort ()
59- self .assertEqual (worksheet_names [0 ], 'Sheet 1' )
69+ self .assertEqual (worksheet_names [0 ], 'Sheet 1' )
70+
71+ def test_worksheet_fields_returns_list_not_method (self ):
72+ # fields property was returning the method object instead of self._fields
73+ wb = Workbook (DASHBOARDS_FILE )
74+ ws = wb .worksheet_items [0 ]
75+ fields = ws .fields
76+ self .assertIsInstance (fields , list , "fields should return a list, not a method object" )
77+
78+ def test_worksheet_fields_are_field_objects (self ):
79+ wb = Workbook (DASHBOARDS_FILE )
80+ ws = wb .worksheet_items [0 ]
81+ from tableaudocumentapi import Field
82+ for f in ws .fields :
83+ self .assertIsInstance (f , Field )
84+
85+ def test_worksheet_datasources_not_empty (self ):
86+ wb = Workbook (DASHBOARDS_FILE )
87+ ws = wb .worksheet_items [0 ]
88+ self .assertGreater (len (ws .datasources ), 0 )
89+
90+ def test_worksheet_rows_returns_list (self ):
91+ wb = Workbook (DASHBOARDS_FILE )
92+ ws = wb .worksheet_items [0 ]
93+ # Sheet 1 has two fields on rows shelf
94+ self .assertIsNotNone (ws .rows )
95+ self .assertIsInstance (ws .rows , list )
96+ self .assertEqual (len (ws .rows ), 2 )
97+
98+ def test_worksheet_cols_empty_shelf_returns_none_or_list (self ):
99+ # Sheet 1 has an empty <cols /> element - should not crash
100+ wb = Workbook (DASHBOARDS_FILE )
101+ ws = wb .worksheet_items [0 ]
102+ result = ws .cols
103+ self .assertTrue (result is None or isinstance (result , list ))
104+
105+ def test_worksheet_rows_field_names (self ):
106+ wb = Workbook (DASHBOARDS_FILE )
107+ ws = wb .worksheet_items [0 ]
108+ # Sheet 1 rows: Calculation_88946136969252864 (caption: SHOW) and "Burst Out Set list"
109+ # _ds_fields_to_items resolves via datasource.fields, so we get Field objects or raw strings
110+ from tableaudocumentapi import Field
111+ names = [f .caption if isinstance (f , Field ) else f for f in ws .rows ]
112+ self .assertIn ('SHOW' , names ) # Calculation resolved to its caption
113+
114+ def test_all_datasource_dependencies_collected (self ):
115+ # return inside loop meant only first datasource-dependencies block was processed
116+ wb = Workbook (DASHBOARDS_FILE )
117+ ws = wb .worksheet_items [0 ]
118+ # Sheet 1 has 3 columns in its datasource-dependencies block
119+ self .assertEqual (len (ws .fields ), 3 )
120+
121+ def test_worksheet_with_no_datasources_element_does_not_crash (self ):
122+ # _prepare_datasources iterates the result of find(), which is None if element absent
123+ wb = Workbook (WORKSHEET_NO_DATASOURCES_FILE )
124+ ws = wb .worksheet_items [0 ]
125+ self .assertEqual (ws .datasources , [])
126+
127+ def test_worksheet_with_no_rows_element_does_not_crash (self ):
128+ # _prepare_rows calls .text on find() result without None check
129+ wb = Workbook (WORKSHEET_NO_SHELVES_FILE )
130+ ws = wb .worksheet_items [0 ]
131+ self .assertIsNone (ws .rows )
132+
133+ def test_worksheet_with_no_cols_element_does_not_crash (self ):
134+ # _prepare_cols calls .text on find() result without None check
135+ wb = Workbook (WORKSHEET_NO_SHELVES_FILE )
136+ ws = wb .worksheet_items [0 ]
137+ self .assertIsNone (ws .cols )
0 commit comments