text: from stograde.specs.file_options import FileOptions
  from stograde.specs.spec_file import create_spec_file
  
  
  def check_file_options_has_defaults(options: FileOptions,
                                      *,
                                      test_compile_optional: bool = True,
                                      test_hide_contents: bool = True,
                                      test_optional: bool = True,
                                      test_timeout: bool = True,
                                      test_truncate_output: bool = True,
                                      test_truncate_contents: bool = True,
                                      test_web_file: bool = True,
                                      ):
      defaults = FileOptions()
  
      if test_compile_optional:
          assert options.compile_optional == defaults.compile_optional
      if test_hide_contents:
          assert options.hide_contents == defaults.hide_contents
      if test_optional:
          assert options.optional == defaults.optional
      if test_timeout:
          assert options.timeout == defaults.timeout
      if test_truncate_output:
          assert options.truncate_output == defaults.truncate_output
      if test_truncate_contents:
          assert options.truncate_contents == defaults.truncate_contents
      if test_web_file:
          assert options.web_file == defaults.web_file
  
  
  def test_create_spec_file_no_file_tag():
      try:
          create_spec_file({
              'some_other_key': 5,
          })
      except AssertionError:
          pass
  
  
  def test_create_spec_file_filename_only():
      new_file = create_spec_file({
          'file': 'test_file1.txt',
      })
  
      assert new_file.file_name == 'test_file1.txt'
      assert not new_file.compile_commands
      assert not new_file.test_commands
      check_file_options_has_defaults(new_file.options)
  
  
  def test_create_spec_file_with_commands_str():
      new_file = create_spec_file({
          'file': 'test_file2.txt',
          'commands': 'compile command',
      })
  
      assert new_file.file_name == 'test_file2.txt'
      assert new_file.compile_commands == ['compile command']
      assert not new_file.test_commands
      check_file_options_has_defaults(new_file.options)
  
  
  def test_create_spec_file_with_commands_list():
      new_file = create_spec_file({
          'file': 'test_file3.txt',
          'commands': ['compile command', 'other command'],
      })
  
      assert new_file.file_name == 'test_file3.txt'
      assert new_file.compile_commands == ['compile command', 'other command']
      assert not new_file.test_commands
      check_file_options_has_defaults(new_file.options)
  
  
  def test_create_spec_file_with_tests_str():
      new_file = create_spec_file({
          'file': 'test_file4.txt',
          'tests': 'test command',
      })
  
      assert new_file.file_name == 'test_file4.txt'
      assert not new_file.compile_commands
      assert new_file.test_commands == ['test command']
      check_file_options_has_defaults(new_file.options)
  
  
  def test_create_spec_file_with_tests_list():
      new_file = create_spec_file({
          'file': 'test_file5.txt',
          'tests': ['test command', 'other test command'],
      })
  
      assert new_file.file_name == 'test_file5.txt'
      assert not new_file.compile_commands
      assert new_file.test_commands == ['test command', 'other test command']
      check_file_options_has_defaults(new_file.options)
  
  
  def test_create_spec_file_with_compile_optional():
      new_file = create_spec_file({
          'file': 'test_file6.txt',
          'options': {
              'optional_compile': True
          }
      })
  
      assert new_file.file_name == 'test_file6.txt'
      assert not new_file.compile_commands
      assert not new_file.test_commands
      assert new_file.options.compile_optional is True
      check_file_options_has_defaults(new_file.options,
                                      test_compile_optional=False)
  
  
  def test_create_spec_file_with_hide_contents():
      new_file = create_spec_file({
          'file': 'test_file7.txt',
          'options': {
              'hide_contents': True
          }
      })
  
      assert new_file.file_name == 'test_file7.txt'
      assert not new_file.compile_commands
      assert not new_file.test_commands
      assert new_file.options.hide_contents is True
      check_file_options_has_defaults(new_file.options,
                                      test_hide_contents=False)
  
  
  def test_create_spec_file_with_optional():
      new_file = create_spec_file({
          'file': 'test_file8.txt',
          'options': {
              'optional': True
          }
      })
  
      assert new_file.file_name == 'test_file8.txt'
      assert not new_file.compile_commands
      assert not new_file.test_commands
      assert new_file.options.optional is True
      check_file_options_has_defaults(new_file.options,
                                      test_optional=False)
  
  
  def test_create_spec_file_with_timeout():
      new_file = create_spec_file({
          'file': 'test_file9.txt',
          'options': {
              'timeout': 50
          }
      })
  
      assert new_file.file_name == 'test_file9.txt'
      assert not new_file.compile_commands
      assert not new_file.test_commands
      assert new_file.options.timeout == 50
      check_file_options_has_defaults(new_file.options,
                                      test_timeout=False)
  
  
  def test_create_spec_file_with_truncate_contents():
      new_file = create_spec_file({
          'file': 'test_file10.txt',
          'options': {
              'truncate_contents': 200
          }
      })
  
      assert new_file.file_name == 'test_file10.txt'
      assert not new_file.compile_commands
      assert not new_file.test_commands
      assert new_file.options.truncate_contents == 200
      check_file_options_has_defaults(new_file.options,
                                      test_truncate_contents=False)
  
  
  def test_create_spec_file_with_truncate_output():
      new_file = create_spec_file({
          'file': 'test_file11.txt',
          'options': {
              'truncate_output': 200
          }
      })
  
      assert new_file.file_name == 'test_file11.txt'
      assert not new_file.compile_commands
      assert not new_file.test_commands
      assert new_file.options.truncate_output == 200
      check_file_options_has_defaults(new_file.options,
                                      test_truncate_output=False)
  
  
  def test_create_spec_file_with_web_file():
      new_file = create_spec_file({
          'file': 'test_file12.txt',
          'options': {
              'web': True
          }
      })
  
      assert new_file.file_name == 'test_file12.txt'
      assert not new_file.compile_commands
      assert not new_file.test_commands
      assert new_file.options.web_file is True
      check_file_options_has_defaults(new_file.options,
                                      test_web_file=False)
  
  
  def test_create_spec_file_with_legacy_list():
      new_file = create_spec_file([
          'test_file13.txt',
          'compile command',
          'other compile command',
          {'truncate_contents': 500},
          {'web': True},
      ])
  
      assert new_file.file_name == 'test_file13.txt'
      assert new_file.compile_commands == ['compile command', 'other compile command']
      assert not new_file.test_commands
      assert new_file.options.truncate_contents == 500
      assert new_file.options.web_file is True
      check_file_options_has_defaults(new_file.options,
                                      test_truncate_contents=False,
                                      test_web_file=False)
  
  
  def test_create_spec_file_bad_type():
      try:
          # noinspection PyTypeChecker
          create_spec_file(15)
      except TypeError:
          pass
  
  
  def test_add_from_tests_list():
      new_file = create_spec_file({
          'file': 'test_file14.txt',
          'tests': ['test command', 'other test command'],
      }).add_from_tests([['test_file14.txt',
                          'yet another test command',
                          'another command',
                          {'not_a_command': True},
                          ],
                         ['not_the_file.txt',
                          'bad command',
                          'another bad command',
                          ],
                         ['test_file14.txt'],  # Testing when name is present but no tests
                         ])
  
      assert new_file.file_name == 'test_file14.txt'
      assert not new_file.compile_commands
      assert new_file.test_commands == ['test command',
                                        'other test command',
                                        'yet another test command',
                                        'another command']
      check_file_options_has_defaults(new_file.options)
  
  
  def test_add_from_tests_dict_str():
      new_file = create_spec_file({
          'file': 'test_file15.txt',
          'tests': ['test command', 'other test command'],
      }).add_from_tests([{
          'file': 'test_file15.txt',
          'commands': 'another command'
      }])
  
      assert new_file.file_name == 'test_file15.txt'
      assert not new_file.compile_commands
      assert new_file.test_commands == ['test command',
                                        'other test command',
                                        'another command']
      check_file_options_has_defaults(new_file.options)
  
  
  def test_add_from_tests_dict_list():
      new_file = create_spec_file({
          'file': 'test_file16.txt',
          'tests': ['test command', 'other test command'],
      }).add_from_tests([{
          'file': 'test_file16.txt',
          'commands': ['another command', 'more command']
      }])
  
      assert new_file.file_name == 'test_file16.txt'
      assert not new_file.compile_commands
      assert new_file.test_commands == ['test command',
                                        'other test command',
                                        'another command',
                                        'more command']
      check_file_options_has_defaults(new_file.options)
  
  
  def test_add_from_tests_bad_type():
      try:
          create_spec_file({
              'file': 'test_file17.txt'
          }).add_from_tests([15])
      except TypeError:
          pass
  