2323 Domain , DiscreteVariable , ContinuousVariable
2424from Orange .util import OrangeDeprecationWarning
2525
26- from Orange .data .io import TabReader
26+ from Orange .data .io import TabReader , XlsReader
2727from Orange .tests import named_file
2828from Orange .widgets .data .owfile import OWFile , OWFileDropHandler , DEFAULT_READER_TEXT
2929from Orange .widgets .utils .filedialogs import dialog_formats , format_filter , RecentPath
@@ -361,13 +361,13 @@ def test_reader_custom_tab(self):
361361 outdata = self .get_output (self .widget .Outputs .data )
362362 self .assertEqual (len (outdata ), 150 ) # loaded iris
363363
364- def test_no_reader_extension (self ):
364+ def test_unknown_extension (self ):
365365 with named_file ("" , suffix = ".xyz_unknown" ) as fn :
366366 no_reader = RecentPath (fn , None , None )
367367 self .widget = self .create_widget (OWFile ,
368368 stored_settings = {"recent_paths" : [no_reader ]})
369369 self .widget .load_data ()
370- self .assertTrue (self .widget .Error .missing_reader .is_shown ())
370+ self .assertTrue (self .widget .Error .select_file_type .is_shown ())
371371
372372 def test_fail_sheets (self ):
373373 with named_file ("" , suffix = ".failed_sheet" ) as fn :
@@ -418,6 +418,22 @@ def test_no_specified_reader(self):
418418 self .assertTrue (self .widget .Error .missing_reader .is_shown ())
419419 self .assertEqual (self .widget .reader_combo .currentText (), "not.a.file.reader.class" )
420420
421+
422+ def _select_reader (self , name ):
423+ reader_combo = self .widget .reader_combo
424+ len_with_qname = len (reader_combo )
425+ for i in range (len_with_qname ):
426+ text = reader_combo .itemText (i )
427+ if text .startswith (name ):
428+ break
429+ else :
430+ assert f"No reader starts with { name !r} "
431+ reader_combo .setCurrentIndex (i )
432+ reader_combo .activated .emit (i )
433+
434+ def _select_tab_reader (self ):
435+ self ._select_reader ("Tab-separated" )
436+
421437 def test_select_reader (self ):
422438 filename = FileFormat .locate ("iris.tab" , dataset_dirs )
423439
@@ -436,12 +452,7 @@ def test_select_reader(self):
436452 self .assertEqual (self .widget .reader_combo .currentText (), "not.a.file.reader.class" )
437453 self .assertEqual (self .widget .reader , None )
438454
439- # select the tab reader
440- for i in range (len_with_qname ):
441- text = self .widget .reader_combo .itemText (i )
442- if text .startswith ("Tab-separated" ):
443- break
444- self .widget .reader_combo .activated .emit (i )
455+ self ._select_tab_reader ()
445456 self .assertEqual (len (self .widget .reader_combo ), len_with_qname - 1 )
446457 self .assertTrue (self .widget .reader_combo .currentText ().startswith ("Tab-separated" ))
447458 self .assertIsInstance (self .widget .reader , TabReader )
@@ -452,6 +463,105 @@ def test_select_reader(self):
452463 self .assertEqual (self .widget .reader_combo .currentText (), DEFAULT_READER_TEXT )
453464 self .assertIsInstance (self .widget .reader , TabReader )
454465
466+ def test_auto_detect_and_override (self ):
467+ tab_as_xlsx = FileFormat .locate ("actually-a-tab-file.xlsx" , dataset_dirs )
468+ iris = FileFormat .locate ("iris" , dataset_dirs )
469+
470+ reader_combo = self .widget .reader_combo
471+
472+ reader_combo .setCurrentIndex (0 )
473+ reader_combo .activated .emit (0 )
474+ assert (self .widget .reader_combo .currentText ()
475+ == "Determine type from the file extension" )
476+
477+ def open_file (_a , _b , _c , filters , _e ):
478+ return filename , filters .split (";;" )[0 ]
479+
480+ with patch ("AnyQt.QtWidgets.QFileDialog.getOpenFileName" ,
481+ open_file ):
482+
483+ # Loading a tab file with extension xlsx fails with auto-detect
484+ filename = tab_as_xlsx
485+ self .widget .browse_file ()
486+
487+ self .assertEqual (self .widget .reader_combo .currentText (),
488+ "Determine type from the file extension" )
489+ self .assertTrue (self .widget .Error .unknown_select .is_shown ())
490+ self .assertIsNone (self .get_output (self .widget .Outputs .data ))
491+
492+ # Select the tab reader: it should work
493+ self ._select_tab_reader ()
494+ assert "Tab-separated" in self .widget .reader_combo .currentText ()
495+
496+ self .assertFalse (self .widget .Error .unknown_select .is_shown ())
497+ self .assertIsInstance (self .widget .reader , TabReader )
498+ self .assertIsNotNone (self .get_output (self .widget .Outputs .data ))
499+
500+ # Switching to iris resets the combo to auto-detect
501+ filename = iris
502+ self .widget .browse_file ()
503+ self .assertEqual (self .widget .reader_combo .currentText (),
504+ "Determine type from the file extension" )
505+ self .assertIsNotNone (self .get_output (self .widget .Outputs .data ))
506+
507+ # Taking the tab-as-xlsx file from recent paths should restore
508+ # the file type for that file
509+ self .widget .file_combo .setCurrentIndex (1 )
510+ self .widget .file_combo .activated .emit (1 )
511+ self .assertIn ("Tab-separated" , self .widget .reader_combo .currentText ())
512+ self .assertIsNotNone (self .get_output (self .widget .Outputs .data ))
513+
514+ # Reloading should work
515+ self .widget .load_data ()
516+ self .assertIn ("Tab-separated" , self .widget .reader_combo .currentText ())
517+ self .assertIsNotNone (self .get_output (self .widget .Outputs .data ))
518+
519+ # Loading this file - not from history - should fail
520+ filename = tab_as_xlsx
521+ self .widget .browse_file ()
522+ self .assertTrue (self .widget .Error .unknown_select .is_shown ())
523+ self .assertIsNone (self .get_output (self .widget .Outputs .data ))
524+
525+ # Set the correct type again (preparation for the next text block)
526+ self ._select_tab_reader ()
527+ assert not self .widget .Error .unknown_select .is_shown ()
528+ assert isinstance (self .widget .reader , TabReader )
529+ assert self .get_output (self .widget .Outputs .data ) is not None
530+
531+ # Now load a real Excel file: this is a known excention so the combo
532+ # should return to auto-detect
533+ filename = FileFormat .locate ("an_excel_file.xlsx" , dataset_dirs )
534+ self .widget .browse_file ()
535+ self .assertEqual (self .widget .reader_combo .currentText (),
536+ "Determine type from the file extension" )
537+ self .assertFalse (self .widget .Error .unknown_select .is_shown ())
538+ self .assertIsNotNone (self .get_output (self .widget .Outputs .data ))
539+
540+ # Load iris to prepare for the next test block
541+ filename = iris
542+ self .widget .browse_file ()
543+ assert (self .widget .reader_combo .currentText ()
544+ == "Determine type from the file extension" )
545+ assert self .get_output (self .widget .Outputs .data ) is not None
546+
547+ # Files with unknown extensions require manual selection
548+ filename = FileFormat .locate ("an_excel_file.foo" , dataset_dirs )
549+ self .widget .browse_file ()
550+ self .assertTrue (self .widget .Error .select_file_type .is_shown ())
551+ self .assertIsNone (self .get_output (self .widget .Outputs .data ))
552+
553+ self ._select_reader ("Excel" )
554+ self .assertFalse (self .widget .Error .unknown_select .is_shown ())
555+ self .assertFalse (self .widget .Error .select_file_type .is_shown ())
556+ self .assertIsNotNone (self .get_output (self .widget .Outputs .data ))
557+
558+ # Consecutive loading of files with the same extension keeps selection
559+ filename = FileFormat .locate ("an_excel_file-too.foo" , dataset_dirs )
560+ self .widget .browse_file ()
561+ self .assertFalse (self .widget .Error .unknown_select .is_shown ())
562+ self .assertFalse (self .widget .Error .select_file_type .is_shown ())
563+ self .assertIsNotNone (self .get_output (self .widget .Outputs .data ))
564+
455565 def test_select_reader_errors (self ):
456566 filename = FileFormat .locate ("iris.tab" , dataset_dirs )
457567
0 commit comments