text: 
  import unittest
  import darwin
  
  import darwin_test_utils
  
  
  class ExperimentTestCase(unittest.TestCase):
      def test_new_experiment(self):
          path = darwin_test_utils.reserve_universe('python_bindings.darwin')
          with darwin.create_universe(path) as universe:
              p = darwin.Population('neat')
              d = darwin.Domain('unicycle')
              exp = universe.new_experiment(population=p, domain=d)
              self.assertRegex(repr(exp), p.name)
              self.assertRegex(repr(exp), d.name)
              self.assertIs(exp.population, p)
              self.assertIs(exp.domain, d)
              self.assertIs(exp.universe, universe)
  
      def test_experiment_name(self):
          path = darwin_test_utils.reserve_universe('python_bindings.darwin')
          universe = darwin.create_universe(path)
          population = darwin.Population('neat')
          domain = darwin.Domain('unicycle')
  
          experiment = universe.new_experiment(domain, population, name='foo')
          self.assertEqual(experiment.name, 'foo')
          self.assertRegex(repr(experiment), "'foo'")
  
          experiment.name = ' a new  name  with  lots of  spaces! '
          self.assertRegex(repr(experiment), "' a new  name  with  lots of  spaces! '")
  
          experiment.name = None
          self.assertRegex(repr(experiment), 'Unnamed')
  
          # invalid name (empty)
          with self.assertRaises(RuntimeError):
              experiment.name = ''
  
          experiment.name = 'final'
  
          experiment.initialize_population()
  
          # can't set the name after the experiment is initialized
          with self.assertRaises(RuntimeError):
              experiment.name = 'baz'
  
          second_population = darwin.Population('cne.lstm')
          second_domain = darwin.Domain('tic_tac_toe')
  
          # duplicate name
          with self.assertRaises(RuntimeError):
              second_experiment = universe.new_experiment(
                  domain=second_domain, population=second_population, name='final')
  
          second_experiment = universe.new_experiment(
              domain=second_domain, population=second_population, name='baz')
  
          # ok...
          second_experiment.name = 'new name'
  
          # duplicate name
          with self.assertRaises(RuntimeError):
              second_experiment.name = 'final'
  
      def test_reuse_checks(self):
          path = darwin_test_utils.reserve_universe('python_bindings.darwin')
          universe = darwin.create_universe(path)
          population = darwin.Population('neat')
          domain = darwin.Domain('unicycle')
  
          experiment_a = universe.new_experiment(domain, population, name='A')
  
          # currently, once a population or a domain _instance_ is used by an experiment,
          # it cannot be reused in other experiments
  
          new_population = darwin.Population('neat')
          with self.assertRaises(RuntimeError):
              experiment_b = universe.new_experiment(domain, new_population, name='B')
  
          new_domain = darwin.Domain('unicycle')
          with self.assertRaises(RuntimeError):
              experiment_c = universe.new_experiment(new_domain, population, name='C')
  
          # after the experiment is disposed, we can reuse the population and domain
          experiment_a = None
          experiment_d = universe.new_experiment(domain, population, name='D')
  
      def test_experiment_reset(self):
          path = darwin_test_utils.reserve_universe('python_bindings.darwin')
          universe = darwin.create_universe(path)
          population = darwin.Population('neat')
          domain = darwin.Domain('unicycle')
  
          population.size = 5
          experiment_a = universe.new_experiment(domain, population)
  
          for i in range(3):
              experiment_a.name = f'A{i}' # name must be unique
              experiment_a.initialize_population();
              experiment_a.evaluate_population();
              experiment_a.create_next_generation();
              experiment_a.reset()
  
      def test_sealed_state(self):
          path = darwin_test_utils.reserve_universe('python_bindings.darwin')
          universe = darwin.create_universe(path)
          population = darwin.Population('neat')
          domain = darwin.Domain('unicycle')
          experiment = universe.new_experiment(domain, population)
  
          # changes are ok
          population.size = 10
          population.config.normalize_input = False
          domain.config.gravity = 10.5
          experiment.config.save_genealogy = True
          experiment.core_config.mutation_std_dev = 0.5
  
          d_config = domain.config
          d_config.max_torque = 100
  
          # initializing the population will seal all configuration values
          experiment.initialize_population()
  
          # shouldn't be able to change sealed state
          with self.assertRaises(RuntimeError):
              population.size = 10
          with self.assertRaises(RuntimeError):
              population.config.normalize_input = True
          with self.assertRaises(RuntimeError):
              domain.config.gravity = 0
          with self.assertRaises(RuntimeError):
              experiment.config.save_genealogy = False
          with self.assertRaises(RuntimeError):
              experiment.core_config.mutation_std_dev = 0
          with self.assertRaises(RuntimeError):
              d_config.max_torque = 0
  
          # make sure the values were not changed
          self.assertEqual(population.size, 10)
          self.assertEqual(population.config.normalize_input.auto, False)
          self.assertEqual(domain.config.gravity.auto, 10.5)
          self.assertEqual(experiment.config.save_genealogy.auto, True)
          self.assertEqual(experiment.core_config.mutation_std_dev.auto, 0.5)
          self.assertEqual(d_config.max_torque.auto, 100)
  
          # resetting the experiment allows configuration changes again
          experiment.reset()
  
          population.size = 1
          population.config.normalize_input = 'true'
          domain.config.gravity = 0.1
          experiment.config.save_genealogy = False
          experiment.core_config.mutation_std_dev = '0.1'
          d_config.max_torque = 1.5
  
          universe.close()
  
  
  if __name__ == '__main__':
      unittest.main()
  