text: """ Tests Grid Object behavior and properties """
  import unittest
  from typing import Type
  
  import pytest
  
  from gym_gridverse.agent import Agent
  from gym_gridverse.geometry import Orientation, Position
  from gym_gridverse.grid import Grid
  from gym_gridverse.grid_object import (
      Beacon,
      Box,
      Color,
      Door,
      Exit,
      Floor,
      GridObject,
      Hidden,
      Key,
      MovingObstacle,
      NoneGridObject,
      Telepod,
      Wall,
      factory,
  )
  from gym_gridverse.state import State
  
  
  class DummyNonRegisteredObject(GridObject, register=False):
      """Some dummy grid object that is _not_ registered"""
  
  
  @pytest.mark.parametrize(
      'object_type,expected',
      [
          (DummyNonRegisteredObject, False),
          (NoneGridObject, True),
          (Hidden, True),
          (Floor, True),
          (Wall, True),
          (Exit, True),
          (Door, True),
          (Key, True),
          (MovingObstacle, True),
          (Box, True),
          (Telepod, True),
          (Beacon, True),
      ],
  )
  def test_registration(object_type: Type[GridObject], expected: bool):
      assert (object_type in GridObject.object_types) == expected
  
  
  def test_none_grid_object_registration():
      """Tests the registration as a Grid Object"""
      assert NoneGridObject in GridObject.object_types
  
  
  def test_hidden_registration():
      """Tests the registration as a Grid Object"""
      assert Hidden in GridObject.object_types
  
  
  def test_grid_object_registration():
      """Test registration of type indices"""
  
      assert len(GridObject.object_types) == 11
      unittest.TestCase().assertCountEqual(
          [
              NoneGridObject.type_index,
              Hidden.type_index,
              Floor.type_index,
              Wall.type_index,
              Exit.type_index,
              Door.type_index,
              Key.type_index,
              MovingObstacle.type_index,
              Box.type_index,
              Telepod.type_index,
              Beacon.type_index,
          ],
          range(len(GridObject.object_types)),
      )
  
      for obj_cls in [
          NoneGridObject,
          Hidden,
          Floor,
          Wall,
          Exit,
          Door,
          Key,
          MovingObstacle,
          Box,
          Telepod,
          Beacon,
      ]:
          assert GridObject.object_types[obj_cls.type_index] is obj_cls
  
  
  def simple_state_without_object() -> State:
      """Returns a 2x2 (empty) grid with an agent without an item"""
      return State(
          Grid(height=2, width=2),
          Agent(Position(0, 0), Orientation.N, Floor()),
      )
  
  
  def test_none_grid_object_properties():
      """Basic stupid tests for none grid object"""
  
      none = NoneGridObject()
  
      assert none.color == Color.NONE
      assert none.state_index == 0
  
      assert none.can_be_represented_in_state()
      assert none.num_states() == 1
  
  
  def test_hidden_properties():
      """Basic stupid tests for hidden grid object"""
  
      hidden = Hidden()
  
      assert not hidden.transparent
      assert hidden.color == Color.NONE
      assert hidden.state_index == 0
  
      assert not hidden.can_be_represented_in_state()
      assert hidden.num_states() == 1
  
  
  def test_floor_properties():
      """Basic stupid tests for floor grid object"""
  
      floor = Floor()
  
      assert floor.transparent
      assert not floor.blocks
      assert floor.color == Color.NONE
      assert not floor.can_be_picked_up
      assert floor.state_index == 0
  
      assert floor.can_be_represented_in_state()
      assert floor.num_states() == 1
  
  
  def test_wall_properties():
      """Basic property tests"""
  
      wall = Wall()
  
      assert not wall.transparent
      assert wall.blocks
      assert wall.color == Color.NONE
      assert not wall.can_be_picked_up
      assert wall.state_index == 0
  
      assert wall.can_be_represented_in_state()
      assert wall.num_states() == 1
  
  
  def test_exit_properties():
      """Basic property tests"""
  
      exit_ = Exit()
  
      assert exit_.transparent
      assert not exit_.blocks
      assert exit_.color == Color.NONE
      assert not exit_.can_be_picked_up
      assert exit_.state_index == 0
  
      assert exit_.can_be_represented_in_state()
      assert exit_.num_states() == 1
  
  
  def test_door_open_door_properties():
      """Basic property tests"""
  
      color = Color.GREEN
      open_door = Door(Door.Status.OPEN, color)
  
      assert open_door.transparent
      assert open_door.color == color
      assert not open_door.can_be_picked_up
      assert open_door.state_index == Door.Status.OPEN.value
      assert open_door.is_open
      assert not open_door.locked
      assert not open_door.blocks
  
      assert open_door.can_be_represented_in_state()
      assert open_door.num_states() == 3
  
  
  def test_door_closed_door_properties():
      """Basic property tests"""
  
      color = Color.NONE
      closed_door = Door(Door.Status.CLOSED, color)
  
      assert not closed_door.transparent
      assert closed_door.color == color
      assert not closed_door.can_be_picked_up
      assert closed_door.state_index == Door.Status.CLOSED.value
      assert not closed_door.is_open
      assert not closed_door.locked
      assert closed_door.blocks
  
      assert closed_door.can_be_represented_in_state()
  
  
  def test_door_locked_door_properties():
      """Basic property tests"""
  
      color = Color.NONE
      locked_door = Door(Door.Status.LOCKED, color)
  
      assert not locked_door.transparent
      assert locked_door.color == color
      assert not locked_door.can_be_picked_up
      assert locked_door.state_index == Door.Status.LOCKED.value
      assert not locked_door.is_open
      assert locked_door.locked
      assert locked_door.blocks
  
      assert locked_door.can_be_represented_in_state()
  
  
  def test_key_properties():
      """Basic property tests"""
  
      color = Color.YELLOW
      key = Key(color)
  
      assert key.transparent
      assert not key.blocks
      assert key.color == color
      assert key.can_be_picked_up
      assert key.state_index == 0
  
      assert key.can_be_represented_in_state()
      assert key.num_states() == 1
  
  
  def test_moving_obstacle_basic_properties():
      """Tests basic properties of the moving obstacle"""
  
      obstacle = MovingObstacle()
  
      assert obstacle.transparent
      assert not obstacle.blocks
      assert obstacle.color == Color.NONE
      assert not obstacle.can_be_picked_up
      assert obstacle.state_index == 0
  
      assert obstacle.can_be_represented_in_state()
      assert obstacle.num_states() == 1
  
  
  def test_box_basic_properties():
      """Tests basic properties of box"""
  
      box = Box(Floor())
  
      assert box.transparent
      assert box.blocks
      assert box.color == Color.NONE
      assert not box.can_be_picked_up
      assert box.state_index == 0
  
      assert not box.can_be_represented_in_state()
      assert box.num_states() == 1
  
  
  def test_telepod_properties():
      """Basic property tests of telepod"""
  
      color = Color.YELLOW
      telepod = Telepod(color)
  
      assert telepod.transparent
      assert not telepod.blocks
      assert telepod.color == color
      assert not telepod.can_be_picked_up
      assert telepod.state_index == 0
  
      assert telepod.can_be_represented_in_state()
      assert telepod.num_states() == 1
  
  
  def test_beacon_properties():
      """Basic property tests of beacon"""
  
      color = Color.YELLOW
      beacon = Beacon(color)
  
      assert beacon.transparent
      assert not beacon.blocks
      assert beacon.color == color
      assert not beacon.can_be_picked_up
      assert beacon.state_index == 0
  
      assert beacon.can_be_represented_in_state()
      assert beacon.num_states() == 1
  
  
  def test_custom_object():
      """Basic property tests of (newly defined) custom objects"""
  
      class ColoredFloor(GridObject):
          """Most basic _colored_ object in the grid, represents empty cell"""
  
          type_index: int
  
          def __init__(self, color: Color = Color.NONE):
              self._color = color
  
          @classmethod
          def can_be_represented_in_state(cls) -> bool:
              return True
  
          @property
          def state_index(self) -> int:
              return 0
  
          @property
          def color(self) -> Color:
              return self._color
  
          @classmethod
          def num_states(cls) -> int:
              return 1
  
          @property
          def transparent(self) -> bool:
              return True
  
          @property
          def can_be_picked_up(self) -> bool:
              return False
  
          @property
          def blocks(self) -> bool:
              return False
  
          def __repr__(self):
              return f'{self.__class__.__name__}({self.color})'
  
      color = Color.YELLOW
      floor = ColoredFloor(color)
  
      assert floor.transparent
      assert not floor.blocks
      assert floor.color == color
      assert not floor.can_be_picked_up
      assert floor.state_index == 0
  
      assert floor.can_be_represented_in_state()
      assert floor.num_states() == 1
  
      assert floor.type_index == len(GridObject.object_types) - 1
      assert ColoredFloor.type_index == len(GridObject.object_types) - 1
      assert type(floor) in GridObject.object_types
  
  
  @pytest.mark.parametrize(
      'name,kwargs',
      [
          ('NoneGridObject', {}),
          ('none_grid_object', {}),
          ('Hidden', {}),
          ('hidden', {}),
          ('Floor', {}),
          ('floor', {}),
          ('Wall', {}),
          ('wall', {}),
          ('Exit', {}),
          ('exit', {}),
          ('Door', {'status': 'LOCKED', 'color': 'RED'}),
          ('door', {'status': 'LOCKED', 'color': 'RED'}),
          ('Key', {'color': 'RED'}),
          ('key', {'color': 'RED'}),
          ('MovingObstacle', {}),
          ('moving_obstacle', {}),
          ('Box', {'obj': Floor()}),
          ('box', {'obj': Floor()}),
          ('Telepod', {'color': 'RED'}),
          ('telepod', {'color': 'RED'}),
          ('Beacon', {'color': 'RED'}),
          ('beacon', {'color': 'RED'}),
      ],
  )
  def test_factory_valid(name: str, kwargs):
      factory(name, **kwargs)
  
  
  @pytest.mark.parametrize(
      'name,kwargs,exception',
      [
          ('invalid', {}, ValueError),
          ('Door', {}, ValueError),
          ('door', {}, ValueError),
          ('Key', {}, ValueError),
          ('key', {}, ValueError),
          ('Box', {}, ValueError),
          ('box', {}, ValueError),
      ],
  )
  def test_factory_invalid(name: str, kwargs, exception: Type[Exception]):
      with pytest.raises(exception):
          factory(name, **kwargs)
  