Tests

The Test Suite below is used to verify functionalities, as well as to validate compatibility across different platforms. These tests below have been executed without failures on:

  • Revit 2015
  • Revit 2016
  • Revit 2017
  • Dynamo 1.2

The Test Suite also provides a many examples of how the library is intended to be used.


Test Suite

"""
Globals

Passes:
 * 2017.1

Revit Python Wrapper
github.com/gtalarico/revitpythonwrapper
revitpythonwrapper.readthedocs.io

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Copyright 2017 Gui Talarico

"""

import sys
import unittest
import os


######################
# Globals
######################


class Globals(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        import rpw

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_doc(self):
        from rpw import revit
        self.assertEqual(revit.doc.__class__.__name__, 'Document')

    def test_db(self):
        from rpw import revit, DB
        Wall = getattr(DB, 'Wall', None)
        self.assertIsInstance(Wall, type)

    def test_ui(self):
        from rpw import revit, UI
        TaskDialog = getattr(UI, 'TaskDialog', None)
        self.assertIsInstance(TaskDialog, type)

    def test_uidoc(self):
        from rpw import revit
        self.assertEqual(revit.uidoc.Application.__class__.__name__, 'UIApplication')

    def test_logger(self):
        from rpw.utils.logger import logger
        from rpw.utils.logger import LoggerWrapper
        self.assertIsInstance(logger, LoggerWrapper)

    #TODO: test version
    #TODO: test built



"""
Collector Tests

Passes:
 * 2017.1

Revit Python Wrapper
github.com/gtalarico/revitpythonwrapper
revitpythonwrapper.readthedocs.io

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Copyright 2017 Gui Talarico

"""

import sys
import unittest
import os

parent = os.path.dirname

script_dir = parent(__file__)
panel_dir = parent(script_dir)
sys.path.append(script_dir)

import rpw
from rpw import revit, DB, UI

doc, uidoc = revit.doc, revit.uidoc

from rpw.utils.dotnet import List
from rpw.exceptions import RpwParameterNotFound, RpwWrongStorageType
from rpw.utils.logger import logger

import test_utils

def setUpModule():
    logger.title('SETTING UP COLLECTOR TESTS...')
    logger.title('REVIT {}'.format(revit.version))
    uidoc.Application.OpenAndActivateDocument(os.path.join(panel_dir, 'collector.rvt'))
    test_utils.delete_all_walls()
    test_utils.make_wall()

def tearDownModule():
    test_utils.delete_all_walls()

######################
# COLLECTOR
######################


class CollectorTests(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING COLLECTOR...')
        collector = DB.FilteredElementCollector(doc)
        cls.family_loaded = collector.OfCategory(DB.BuiltInCategory.OST_Furniture).ToElements()

    @staticmethod
    def collector_helper(filters):
        logger.debug('{}'.format(filters))
        collector = rpw.db.Collector(**filters)
        elements = collector.elements
        logger.debug(collector)
        if collector:
            logger.debug(collector[0])
        return collector

    def setUp(self):
        self.collector_helper = CollectorTests.collector_helper

    def test_collector_elements(self):
        x = self.collector_helper({'of_class': DB.View})
        assert isinstance(x.elements[0], DB.View)

    def test_collector_elements_view_element(self):
        x = self.collector_helper({'of_class': DB.Wall, 'view': uidoc.ActiveView})
        self.assertEqual(len(x), 1)

    def test_collector_elements_view_element_another(self):
        # Id of view where everything is hidden
        view_hidden = doc.GetElement(DB.ElementId(12531))
        x = self.collector_helper({'of_class': DB.Wall, 'view': view_hidden})
        self.assertEqual(len(x), 0)

    def test_collector_elements_view_id(self):
        x = self.collector_helper({'of_class': DB.Wall, 'view': uidoc.ActiveView.Id})
        self.assertEqual(len(x), 1)

    def test_collector_len(self):
        x = self.collector_helper({'of_class': DB.View})
        assert len(x) > 1

    def test_collector_first(self):
        x = self.collector_helper({'of_class': DB.View})
        assert isinstance(x.first, DB.View)

    def test_collector_caster(self):
        x = self.collector_helper({'of_class': DB.Wall}).elements[0]
        assert isinstance(x, DB.Wall)
        y = self.collector_helper({'of_class': 'Wall'}).elements[0]
        assert isinstance(y, DB.Wall)

    def test_collector_is_element(self):
        walls = self.collector_helper({'of_category': 'OST_Walls',
                                       'is_not_type': True})
        assert all([isinstance(x, DB.Wall) for x in walls.elements])

    def test_collector_is_element_false(self):
        walls = self.collector_helper({'of_category': 'OST_Walls',
                                       'is_not_type': False})
        assert all([isinstance(x, DB.WallType) for x in walls.elements])

    def test_collector_is_element_type(self):
        walls = self.collector_helper({'of_category': 'OST_Walls',
                                       'is_type': True})
        assert all([isinstance(x, DB.WallType) for x in walls.elements])

    def test_collector_is_element_type_false(self):
        walls = self.collector_helper({'of_category': 'OST_Walls',
                                       'is_type': False})
        assert all([isinstance(x, DB.Wall) for x in walls.elements])

    def test_collector_is_view_dependent(self):
        fregions = self.collector_helper({'of_category': 'OST_FilledRegion'})
        assert all([f.ViewSpecific for f in fregions.elements])
        view_dependent = self.collector_helper({'is_view_independent': True})
        assert not all([f.ViewSpecific for f in view_dependent.elements])

    # def test_collector_chained_calls(self):
    #     wall_collector = self.collector_helper({'of_category': DB.BuiltInCategory.OST_Walls})
    #     walls_category = len(wall_collector)
    #     wall_collector.filter(is_not_type=True)
    #     walls_elements = len(wall_collector)
    #     wall_collector.filter(is_type=True)
    #     walls_element_type = len(wall_collector)
    #     assert walls_category > walls_elements > walls_element_type

    def tests_collect_rooms(self):
        collector = rpw.db.Collector(of_category='OST_Rooms')
        if collector:
            self.assertIsInstance(collector.first, DB.SpatialElement)
            collector = rpw.db.Collector(of_class='SpatialElement')
            self.assertIsInstance(collector.first, DB.Architecture.Room)

    def test_collector_scope_elements(self):
        """ If Collector scope is list of elements, should not find View"""
        wall = rpw.db.Collector(of_class='Wall').first
        collector = rpw.db.Collector(elements=[wall], of_class='View')
        self.assertEqual(len(collector), 0)

    def test_collector_scope_element_ids(self):
        wall = rpw.db.Collector(of_class='Wall').first
        collector = rpw.db.Collector(element_ids=[wall.Id], of_class='View')
        self.assertEqual(len(collector), 0)

    def test_collector_symbol_filter(self):
        desk_types = rpw.db.Collector(of_class='FamilySymbol',
                                      of_category="OST_Furniture").elements
        self.assertEqual(len(desk_types), 3)

        all_symbols = rpw.db.Collector(of_class='FamilySymbol').elements
        self.assertGreater(len(all_symbols), 3)
        all_symbols = rpw.db.Collector(of_class='FamilySymbol').elements

        #Placed Twice
        first_symbol = rpw.db.Collector(symbol=desk_types[0]).elements
        self.assertEqual(len(first_symbol), 2)

        #Placed Once
        second_symbol = rpw.db.Collector(symbol=desk_types[1]).elements
        self.assertEqual(len(second_symbol), 1)

        second_symbol = rpw.db.Collector(of_class='Wall', symbol=desk_types[1]).elements
        self.assertEqual(len(second_symbol), 0)

##############################
# Built in Element Collector #
##############################

class BuiltInCollectorTests(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING ELEMENT COLLECTOR...')

    def test_element_collector_wall(self):
        walls = rpw.db.Wall.collect()
        self.assertEqual(len(walls), 1)
        self.assertIsInstance(walls.first, DB.Wall)

    def test_element_collector_wallsymbols(self):
        wallsymbols = rpw.db.WallType.collect()
        self.assertEqual(len(wallsymbols), 4)
        self.assertIsInstance(wallsymbols.first, DB.WallType)

    def test_element_collector_Room(self):
        rooms = rpw.db.Room.collect()
        self.assertEqual(len(rooms), 2)
        self.assertIsInstance(rooms.first, DB.Architecture.Room)

    def test_element_collector_Area(self):
        areas = rpw.db.Area.collect()
        self.assertEqual(len(areas), 1)
        self.assertIsInstance(areas.first, DB.Area)

    def test_element_collector_AreaScheme(self):
        areas = rpw.db.AreaScheme.collect()
        self.assertEqual(len(areas), 2)
        self.assertIsInstance(areas.first, DB.AreaScheme)


############################
# COLLECTOR PARAMETER FILTER
############################

class ParameterFilterTests(unittest.TestCase):

    @classmethod
    def setUpClass(self):
        logger.title('TESTING PARAMETER FILTER...')

    def setUp(self):
        self.wall = rpw.db.Collector(of_class='Wall').first
        self.wrapped_wall = rpw.db.Element(self.wall)
        with rpw.db.Transaction('Set Comment'):
            self.wrapped_wall.parameters['Comments'].value = 'Tests'
            self.wrapped_wall.parameters['Unconnected Height'].value = 12.0

        # BIP Ids

        self.param_id_height = rpw.db.builtins.BipEnum.get_id('WALL_USER_HEIGHT_PARAM')
        self.param_id_location = rpw.db.builtins.BipEnum.get_id('WALL_KEY_REF_PARAM')
        self.param_id_comments = rpw.db.builtins.BipEnum.get_id('ALL_MODEL_INSTANCE_COMMENTS')
        self.param_id_level_name = rpw.db.builtins.BipEnum.get_id('DATUM_TEXT')

    def tearDown(self):
        pass

    def test_param_filter_float_less_no(self):
        parameter_filter = rpw.db.ParameterFilter(self.param_id_height, less=10.0)
        col = rpw.db.Collector(of_class="Wall", parameter_filter=parameter_filter)
        self.assertEqual(len(col), 0)

    def test_param_filter_float_less_yes(self):
        parameter_filter = rpw.db.ParameterFilter(self.param_id_height, less=15.0)
        col = rpw.db.Collector(of_class="Wall", parameter_filter=parameter_filter)
        self.assertEqual(len(col), 1)

    def test_param_filter_float_equal(self):
        parameter_filter = rpw.db.ParameterFilter(self.param_id_height, equals=12.0)
        col = rpw.db.Collector(of_class="Wall", parameter_filter=parameter_filter)
        self.assertEqual(len(col), 1)

    def test_param_filter_float_not_equal(self):
        parameter_filter = rpw.db.ParameterFilter(self.param_id_height, not_equals=12.0)
        col = rpw.db.Collector(of_class="Wall", parameter_filter=parameter_filter)
        self.assertEqual(len(col), 0)

    def test_param_filter_float_greater(self):
        parameter_filter = rpw.db.ParameterFilter(self.param_id_height, greater=10.0)
        col = rpw.db.Collector(of_class="Wall", parameter_filter=parameter_filter)
        self.assertEqual(len(col), 1)

    def test_param_filter_float_multi_filter(self):
        parameter_filter = rpw.db.ParameterFilter(self.param_id_height, greater=10.0, less=14.0)
        col = rpw.db.Collector(of_class="Wall", parameter_filter=parameter_filter)
        self.assertEqual(len(col), 1)

    def test_param_filter_float_multi_filter(self):
        parameter_filter = rpw.db.ParameterFilter(self.param_id_height, greater=10.0, not_less=14.0)
        col = rpw.db.Collector(of_class="Wall", parameter_filter=parameter_filter)
        self.assertEqual(len(col), 0)

    def test_param_filter_int_equal(self):
        parameter_filter = rpw.db.ParameterFilter(self.param_id_location, equals=0)
        col = rpw.db.Collector(of_class="Wall", parameter_filter=parameter_filter)
        self.assertEqual(len(col), 1)

    def test_param_filter_int_less(self):
        parameter_filter = rpw.db.ParameterFilter(self.param_id_location, less=3)
        col = rpw.db.Collector(of_class="Wall", parameter_filter=parameter_filter)

        self.assertEqual(len(col), 1)

    def test_param_comments_equals(self):
        parameter_filter = rpw.db.ParameterFilter(self.param_id_comments, equals='Tests')
        col = rpw.db.Collector(of_class="Wall", parameter_filter=parameter_filter)
        self.assertEqual(len(col), 1)

    def test_param_comments_not_equals(self):
        parameter_filter = rpw.db.ParameterFilter(self.param_id_comments, equals='Blaa')
        col = rpw.db.Collector(of_class="Wall", parameter_filter=parameter_filter)
        self.assertEqual(len(col), 0)

    def test_param_comments_begins(self):
        parameter_filter = rpw.db.ParameterFilter(self.param_id_comments, begins='Tes')
        col = rpw.db.Collector(of_class="Wall", parameter_filter=parameter_filter)
        self.assertEqual(len(col), 1)

    def test_param_comments_not_begins(self):
        parameter_filter = rpw.db.ParameterFilter(self.param_id_comments, equals='Bla bla')
        col = rpw.db.Collector(of_class="Wall", parameter_filter=parameter_filter)
        self.assertEqual(len(col), 0)

    def test_param_comments_not_begins(self):
        parameter_filter = rpw.db.ParameterFilter(self.param_id_comments, not_begins='Bla bla')
        col = rpw.db.Collector(of_class="Wall", parameter_filter=parameter_filter)
        self.assertEqual(len(col), 1)

    # FAILS - CASE SENSITIVE FLAG IS NOT WORKING
    # def test_param_comments_equal_case(self):
        # parameter_filter = rpw.db.ParameterFilter(self.param_id_comments, contains='tests')
        # col = rpw.db.Collector(of_class="Wall", parameter_filter=parameter_filter)
        # self.assertEqual(len(col), 0)

    def tests_param_name_contains(self):
        parameter_filter = rpw.db.ParameterFilter(self.param_id_level_name, contains='1')
        col = rpw.db.Collector(of_category="OST_Levels", parameter_filter=parameter_filter)
        self.assertEqual(len(col), 1)

    def tests_param_name_ends(self):
        parameter_filter = rpw.db.ParameterFilter(self.param_id_level_name, ends='1')
        col = rpw.db.Collector(of_category="OST_Levels", parameter_filter=parameter_filter)
        self.assertEqual(len(col), 1)

    def tests_param_id_coerce(self):
        """ Uses Param Name instead of Param Id. Works only for BIP """
        param_name = 'DATUM_TEXT'
        parameter_filter = rpw.db.ParameterFilter(param_name, ends='1')
        col = rpw.db.Collector(of_category="OST_Levels", parameter_filter=parameter_filter)
        self.assertEqual(len(col), 1)

    def test_from_parameter_name(self):
        """ Uses LooksUp Parameter from sample element """
        level = rpw.db.Collector(of_category="OST_Levels", is_type=False).first
        parameter_filter = rpw.db.ParameterFilter.from_element_and_parameter(level, 'Name', ends='1')
        col = rpw.db.Collector(of_category="OST_Levels", parameter_filter=parameter_filter)
        self.assertEqual(len(col), 1)


class FilteredCollectorCompareTests(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING COLLECTOR...')

    def test_category(self):
        rv = DB.FilteredElementCollector(doc).OfCategory(DB.BuiltInCategory.OST_Levels).WhereElementIsElementType().ToElements()
        rv2 = rpw.db.Collector(of_category="Levels", is_type=True)
        self.assertEqual(len(rv), len(rv2))

    def test_category2(self):
        rv = DB.FilteredElementCollector(doc).OfCategory(DB.BuiltInCategory.OST_Levels).WhereElementIsNotElementType().ToElements()
        rv2 = rpw.db.Collector(of_category="Levels", is_type=False)
        self.assertEqual(len(rv), len(rv2))

    def test_class(self):
        rv = DB.FilteredElementCollector(doc).OfClass(DB.View).ToElements()
        rv2 = rpw.db.Collector(of_class="View")
        self.assertEqual(len(rv), len(rv2))

        #TODO: Fo all FilteredElementCollector

"""
Collector Tests

Passes:
 * 2017.1

Revit Python Wrapper
github.com/gtalarico/revitpythonwrapper
revitpythonwrapper.readthedocs.io

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Copyright 2017 Gui Talarico

"""

import sys
import unittest
import os

parent = os.path.dirname

script_dir = parent(__file__)
panel_dir = parent(script_dir)
sys.path.append(script_dir)

import rpw
from rpw import revit, DB, UI

doc, uidoc = revit.doc, revit.uidoc

from rpw.utils.dotnet import List
from rpw.db.xyz import XYZ
from rpw.exceptions import RpwParameterNotFound, RpwWrongStorageType
from rpw.utils.logger import logger

import test_utils

def setUpModule():
    logger.title('SETTING UP COLLECTION TESTS...')

def tearDownModule():
    test_utils.delete_all_walls()

######################
# ElementSet
######################

class ElementSetTests(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING ElementSetTests...')
        collector = DB.FilteredElementCollector(doc)
        cls.views = collector.OfClass(DB.View).ToElements()

    # def setUp(self):
        # self.collector_helper = CollectorTests.collector_helper


    def test_element_set_element_add(self):
        rv = rpw.db.ElementSet()
        rv.add(self.views)
        self.assertEqual(len(rv), len(self.views))

    def test_element_set_unique(self):
        rv = rpw.db.ElementSet()
        rv.add(self.views)
        rv.add(self.views)
        self.assertEqual(len(rv), len(self.views))

    def test_element_set_init__bool(self):
        x = rpw.db.ElementSet(self.views)
        self.assertTrue(x)

    def test_element_set_elements(self):
        x = rpw.db.ElementSet(self.views)
        self.assertIsInstance(x.elements[0], DB.View)

    def test_element_set_element_ids(self):
        x = rpw.db.ElementSet(self.views)
        self.assertIsInstance(x.element_ids[0], DB.ElementId)

    def test_element_set_len(self):
        rv = len(rpw.db.ElementSet(self.views))
        self.assertGreater(rv, 2)

    def test_element_set_element_clear(self):
        rv = rpw.db.ElementSet(self.views)
        rv.clear()
        self.assertEqual(len(rv), 0)

    def test_element_set_as_element_list(self):
        rv = rpw.db.ElementSet(self.views)
        l = rv.as_element_list
        self.assertTrue(hasattr(l, 'Count'))
        self.assertEqual(len(l), len(self.views))

    def test_element_set_as_element_id_list(self):
        rv = rpw.db.ElementSet(self.views)
        l = rv.as_element_id_list
        self.assertTrue(hasattr(l, 'Count'))
        self.assertEqual(len(l), len(self.views))

    def test_element_set_select(self):
        rv = rpw.db.ElementSet(self.views)
        rv.select()

    def test_element_set_first(self):
        rv = rpw.db.ElementSet(self.views)
        self.assertEqual(rv.first.Id, self.views[0].Id)

    def test_element_set_get_item(self):
        rv = rpw.db.ElementSet(self.views)
        self.assertIsInstance(rv[0], DB.View)

    def test_element_set_iter(self):
        rv = rpw.db.ElementSet(self.views)
        self.assertTrue(all([isinstance(v, DB.View) for v in rv]))

    def test_element_set_pop(self):
        rv = rpw.db.ElementSet(self.views)
        first_id = rv.element_ids[0]
        rv.pop(first_id)
        self.assertNotIn(first_id, rv)

    def test_element_set_wrapped_elements(self):
        rv = rpw.db.ElementSet(self.views).wrapped_elements
        self.assertIsInstance(rv[0], rpw.db.Element)



######################
# ElementCollection
######################

class ElementCollectionTests(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING ElementCollection...')
        collector = DB.FilteredElementCollector(doc)
        cls.views = collector.OfClass(DB.View).ToElements()

    def test_element_collection_element_add(self):
        rv = rpw.db.ElementCollection()
        rv.append(self.views)
        self.assertEqual(len(rv), len(self.views))

    def test_element_collection_unique(self):
        rv = rpw.db.ElementCollection()
        rv.append(self.views)
        rv.append(self.views)
        self.assertEqual(len(rv), len(self.views)*2)

    def test_element_collection_init__bool(self):
        x = rpw.db.ElementCollection(self.views)
        self.assertTrue(x)

    def test_element_collection_elements(self):
        x = rpw.db.ElementCollection(self.views)
        self.assertIsInstance(x.elements[0], DB.View)

    def test_element_collection_element_ids(self):
        x = rpw.db.ElementCollection(self.views)
        self.assertIsInstance(x.element_ids[0], DB.ElementId)

    def test_element_collection_len(self):
        rv = len(rpw.db.ElementCollection(self.views))
        self.assertGreater(rv, 2)

    def test_element_collection_element_clear(self):
        rv = rpw.db.ElementCollection(self.views)
        rv.clear()
        self.assertEqual(len(rv), 0)

    def test_element_collection_as_element_list(self):
        rv = rpw.db.ElementCollection(self.views)
        l = rv.as_element_list
        self.assertTrue(hasattr(l, 'Count'))
        self.assertEqual(len(l), len(self.views))

    def test_element_collection_as_element_id_list(self):
        rv = rpw.db.ElementCollection(self.views)
        l = rv.as_element_id_list
        self.assertTrue(hasattr(l, 'Count'))
        self.assertEqual(len(l), len(self.views))

    def test_element_collection_select(self):
        rv = rpw.db.ElementCollection(self.views)
        rv.select()

    def test_element_collection_first(self):
        rv = rpw.db.ElementCollection(self.views)
        self.assertEqual(rv.first.Id, self.views[0].Id)

    def test_element_collection_get_item(self):
        rv = rpw.db.ElementCollection(self.views)
        self.assertIsInstance(rv[0], DB.View)

    def test_element_collection_iter(self):
        rv = rpw.db.ElementCollection(self.views)
        self.assertTrue(all([isinstance(v, DB.View) for v in rv]))

    def test_element_collection_pop(self):
        col = rpw.db.ElementCollection(self.views)
        size = len(col)
        e = col.pop(0)

        self.assertIsInstance(e, DB.View)
        self.assertEqual(len(col), size - 1)

    def test_element_collection_wrapped_elements(self):
        rv = rpw.db.ElementSet(self.views).wrapped_elements
        self.assertIsInstance(rv[0], rpw.db.Element)


######################
# XYZCollection
######################

class XyzCollectionTests(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING XYZ Collection...')
        cls.points = [XYZ(0,0,0), XYZ(10,10,0), XYZ(5,5,0)]

    def test_xyz_add_len(self):
        xyz_collection = rpw.db.XyzCollection(self.points)
        self.assertEqual(len(xyz_collection), 3)

    def test_xyz_max(self):
        xyz_collection = rpw.db.XyzCollection(self.points)
        mx = xyz_collection.max
        self.assertEqual(mx, XYZ(10,10,0))

    def test_xyz_min(self):
        xyz_collection = rpw.db.XyzCollection(self.points)
        mn = xyz_collection.min
        self.assertEqual(mn, XYZ(0,0,0))

    def test_xyz_average(self):
        xyz_collection = rpw.db.XyzCollection(self.points)
        av = xyz_collection.average
        self.assertEqual(av, XYZ(5,5,0))

    def test_xyz_sorted_by(self):
        xyz_collection = rpw.db.XyzCollection(self.points)
        rv = xyz_collection.sorted_by('x')
        self.assertEqual(rv[0], XYZ(0,0,0))
        self.assertEqual(rv[1], XYZ(5,5,0))
        self.assertEqual(rv[2], XYZ(10,10,0))


"""
Curve Tests

Passes:
 * 2017.1

Revit Python Wrapper
github.com/gtalarico/revitpythonwrapper
revitpythonwrapper.readthedocs.io

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Copyright 2017 Gui Talarico

"""

import sys
import unittest
import os

parent = os.path.dirname

script_dir = parent(__file__)
panel_dir = parent(script_dir)
sys.path.append(script_dir)

import rpw
from rpw import revit, DB, UI, db

doc, uidoc = revit.doc, revit.uidoc

from rpw.db.xyz import XYZ
from rpw.exceptions import RpwParameterNotFound, RpwWrongStorageType
from rpw.utils.logger import logger


def setUpModule():
    logger.title('SETTING UP Curve TESTS...')

def tearDownModule():
    pass

class Line(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING Line...')
        pt1 = DB.XYZ(0,0,0)
        pt2 = DB.XYZ(10,10,0)
        cls.Line = DB.Line.CreateBound(pt1, pt2)
        cls.line = db.Line.new(pt1, pt2)

    def test_line(self):
        Line, line = self.Line, self.line
        self.assertIsInstance(line.unwrap(), DB.Line)
        self.assertTrue(Line.GetEndPoint(1).IsAlmostEqualTo(line.end_point.unwrap()))

    def test_line_start_point(self):
        Line, line = self.Line, self.line
        self.assertTrue(Line.GetEndPoint(0).IsAlmostEqualTo(line.start_point.unwrap()))

    def test_line_end_point(self):
        Line, line = self.Line, self.line
        self.assertTrue(Line.GetEndPoint(1).IsAlmostEqualTo(line.end_point.unwrap()))

    def test_line_end_point(self):
        Line, line = self.Line, self.line
        self.assertTrue(Line.GetEndPoint(0.5).IsAlmostEqualTo(line.mid_point.unwrap()))

    def test_line_end_points(self):
        Line, line = self.Line, self.line
        self.assertIsInstance(line.end_points, tuple)
        self.assertTrue(Line.GetEndPoint(0).IsAlmostEqualTo(line.end_points[0].unwrap()))


class Ellipse(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING Line...')
        pt1 = DB.XYZ(0,0,0)
        pt2 = DB.XYZ(10,10,0)
        cls.Line = DB.Line.CreateBound(pt1, pt2)
        cls.line = db.Line.new(pt1, pt2)

    # def test_line(self):
    #     Line, line = self.Line, self.line
    #     self.assertIsInstance(line.unwrap(), DB.Line)
    #     self.assertTrue(Line.GetEndPoint(1).IsAlmostEqualTo(line.end_point.unwrap()))
    #
    # def test_line_start_point(self):
    #     Line, line = self.Line, self.line
    #     self.assertTrue(Line.GetEndPoint(0).IsAlmostEqualTo(line.start_point.unwrap()))
    #
    # def test_line_end_point(self):
    #     Line, line = self.Line, self.line
    #     self.assertTrue(Line.GetEndPoint(1).IsAlmostEqualTo(line.end_point.unwrap()))
    #
    # def test_line_end_point(self):
    #     Line, line = self.Line, self.line
    #     self.assertTrue(Line.GetEndPoint(0.5).IsAlmostEqualTo(line.mid_point.unwrap()))
    #
    # def test_line_end_points(self):
    #     Line, line = self.Line, self.line
    #     self.assertIsInstance(line.end_points, tuple)
    #     self.assertTrue(Line.GetEndPoint(0).IsAlmostEqualTo(line.end_points[0].unwrap()))


class CurveCreate(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING Curve Create...')

    def setUp(self):
        line = db.Line.new([0,0], [10,10])
        with rpw.db.Transaction():
            self.detail_line = line.create_detail()

    def tearDown(self):
        with rpw.db.Transaction():
            revit.doc.Delete(self.detail_line.Id)

    def test_detail_line(self):
        self.assertIsInstance(self.detail_line, DB.DetailLine)
        curve = self.detail_line.GeometryCurve
        self.assertTrue(curve.GetEndPoint(1).IsAlmostEqualTo(DB.XYZ(10,10,0)))


"""
Collector Tests

Passes:
 * 2017.1

Revit Python Wrapper
github.com/gtalarico/revitpythonwrapper
revitpythonwrapper.readthedocs.io

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Copyright 2017 Gui Talarico

"""

import sys
import unittest
import os

parent = os.path.dirname

script_dir = parent(__file__)
panel_dir = parent(script_dir)
sys.path.append(script_dir)

import rpw
from rpw import revit, DB, UI
from rpw.utils.dotnet import List
from rpw.exceptions import RpwParameterNotFound, RpwWrongStorageType, RpwCoerceError
from rpw.utils.logger import logger

import test_utils

def setUpModule():
    logger.title('SETTING UP ELEMENTS TESTS...')
    revit.uidoc.Application.OpenAndActivateDocument(os.path.join(panel_dir, 'collector.rvt'))
    test_utils.delete_all_walls()
    test_utils.make_wall()

def tearDownModule():
    test_utils.delete_all_walls()


######################
# ELEMENT
######################


class ElementTests(unittest.TestCase):

    @classmethod
    def setUpClass(self):
        logger.title('TESTING ELEMENT...')

    def setUp(self):
        self.wall = DB.FilteredElementCollector(revit.doc).OfClass(DB.Wall).ToElements()[0]
        self.wrapped_wall = rpw.db.Element(self.wall)
        # param = self.wall.LookupParameter('Comments')
        # t = DB.Transaction(doc)
        # t.Start('Clear Comment Param')
        # param.Set('')
        # t.Commit()

    def tearDown(self):
        collector = rpw.db.Collector()
        levels = rpw.db.Collector(of_class=DB.Level).elements
        with rpw.db.Transaction('Delete Test Levels'):
            for level in levels[1:]:
                revit.doc.Delete(level.Id)

    def test_element_repr(self):
        self.assertIn('<RPW_Element:<Autodesk.Revit.DB.Wall', self.wrapped_wall.__repr__())

    def test_element_repr(self):
        self.assertIsInstance(self.wrapped_wall, rpw.db.Element)
        self.assertIsInstance(self.wrapped_wall.unwrap(), DB.Wall)

    def test_element_id(self):
        assert isinstance(self.wrapped_wall.Id, DB.ElementId)

    def test_element_from_id(self):
        element = rpw.db.Element.from_id(self.wall.Id)
        self.assertIsInstance(element, rpw.db.Element)

    def test_element_from_int(self):
        element = rpw.db.Element.from_int(self.wall.Id.IntegerValue)
        self.assertIsInstance(element, rpw.db.Element)

    def test_element_id(self):
        self.assertIsInstance(self.wrapped_wall, rpw.db.Element)

    def test_element_get_parameter_type(self):
        rv = self.wrapped_wall.parameters['Comments'].type
        self.assertEqual(rv, str)
        rv = self.wrapped_wall.parameters['Base Constraint'].type
        self.assertEqual(rv, DB.ElementId)
        rv = self.wrapped_wall.parameters['Unconnected Height'].type
        self.assertEqual(rv, float)
        rv = self.wrapped_wall.parameters['Room Bounding'].type
        self.assertEqual(rv, int)

    def test_element_get_parameter_name(self):
        rv = self.wrapped_wall.parameters['Comments'].name
        self.assertEqual(rv, 'Comments')

    def test_element_get_parameter(self):
        rv = self.wrapped_wall.parameters['Comments'].value
        self.assertEqual(rv, None)

    def tests_element_set_get_parameter_string(self):
        with rpw.db.Transaction('Set String'):
            self.wrapped_wall.parameters['Comments'].value = 'Test String'
        rv = self.wrapped_wall.parameters['Comments'].value
        self.assertEqual(rv, 'Test String')

    def tests_element_set_get_parameter_coerce_string(self):
        with rpw.db.Transaction('Set String'):
            self.wrapped_wall.parameters['Comments'].value = 5
        rv = self.wrapped_wall.parameters['Comments'].value
        self.assertEqual(rv, '5')

    def tests_element_set_get_parameter_float(self):
        with rpw.db.Transaction('Set Integer'):
            self.wrapped_wall.parameters['Unconnected Height'].value = 5.0
        rv = self.wrapped_wall.parameters['Unconnected Height'].value
        self.assertEqual(rv, 5.0)

    def tests_element_set_get_parameter_coerce_int(self):
        with rpw.db.Transaction('Set Coerce Int'):
            self.wrapped_wall.parameters['Unconnected Height'].value = 5
        rv = self.wrapped_wall.parameters['Unconnected Height'].value
        self.assertEqual(rv, 5.0)

    def tests_element_set_get_parameter_element_id(self):
        active_view = revit.uidoc.ActiveView
        wrapped_view = rpw.db.Element(active_view)
        with rpw.db.Transaction('Create and Set Level'):
            try:
                new_level = DB.Level.Create(revit.doc, 10)
            except:
                new_level = revit.doc.Create.NewLevel(10)
            self.wrapped_wall.parameters['Top Constraint'].value = new_level.Id
        self.assertEqual(self.wrapped_wall.parameters['Top Constraint'].value.IntegerValue,
                         new_level.Id.IntegerValue)

    def test_element_get_builtin_parameter_by_strin(self):
        bip = self.wrapped_wall.parameters.builtins['WALL_KEY_REF_PARAM'].value
        self.assertIsInstance(bip, int)

    def test_element_set_get_builtin_parameter_by_strin(self):
        bip = self.wrapped_wall.parameters.builtins['WALL_KEY_REF_PARAM']
        with rpw.db.Transaction('Set Value'):
            bip.value = 0
        bip = self.wrapped_wall.parameters.builtins['WALL_KEY_REF_PARAM']
        self.assertEqual(bip.value, 0)

    def test_element_get_builtin_parameter_caster(self):
        bip = self.wrapped_wall.parameters.builtins['WALL_KEY_REF_PARAM'].value
        BIP_ENUM = DB.BuiltInParameter.WALL_KEY_REF_PARAM
        bip2 = self.wrapped_wall.parameters.builtins[BIP_ENUM].value
        self.assertEqual(bip, bip2)

    def tests_wrong_storage_type(self):
        with self.assertRaises(RpwWrongStorageType) as context:
            with rpw.db.Transaction('Set String'):
                self.wrapped_wall.parameters['Unconnected Height'].value = 'Test'

    def test_parameter_does_not_exist(self):
        with self.assertRaises(RpwParameterNotFound) as context:
            self.wrapped_wall.parameters['Parameter Name']

    def test_built_in_parameter_exception_raised(self):
        with self.assertRaises(RpwCoerceError) as context:
            self.wrapped_wall.parameters.builtins['PARAMETERD_DOES_NOT_EXIST']


#########################
# Parameters / Isolated #
#########################

    def tests_param_class(self):
        param = self.wall.LookupParameter('Comments')
        self.assertIsInstance(param, DB.Parameter)
        wrapped_param = rpw.db.Parameter(param)
        self.assertIs(wrapped_param.type, str)
        self.assertEqual(wrapped_param.builtin, DB.BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS)

################################### INSTANCES / Symbols / Families #
##################################

class InstanceTests(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING INSTANCES...')

    def setUp(self):
        instance = rpw.db.Collector(of_category='OST_Furniture', is_not_type=True).first
        self.instance = rpw.db.FamilyInstance(instance)

    def tearDown(self):
        logger.debug('SELECTION TEST PASSED')

    def test_instance_wrap(self):
        self.assertIsInstance(self.instance, rpw.db.FamilyInstance)
        self.assertIsInstance(self.instance.unwrap(), DB.FamilyInstance)

    def test_instance_symbol(self):
        symbol = self.instance.symbol
        self.assertIsInstance(symbol, rpw.db.FamilySymbol)
        self.assertIsInstance(symbol.unwrap(), DB.FamilySymbol)
        self.assertEqual(symbol.name, '60" x 30"')
        self.assertEqual(len(symbol.instances), 2)
        self.assertEqual(len(symbol.siblings), 3)

    def test_instance_family(self):
        family = self.instance.symbol.family
        self.assertIsInstance(family, rpw.db.Family)
        self.assertEqual(family.name, 'desk')
        self.assertIsInstance(family.unwrap(), DB.Family)
        self.assertEqual(len(family.instances), 3)
        self.assertEqual(len(family.siblings), 1)
        self.assertEqual(len(family.symbols), 3)

    def test_instance_category(self):
        category = self.instance.symbol.family.category
        self.assertIsInstance(category, rpw.db.Category)
        self.assertIsInstance(category.unwrap(), DB.Category)
        self.assertEqual(category.name, 'Furniture')
        self.assertEqual(len(category.instances), 3)
        self.assertEqual(len(category.symbols), 3)
        self.assertEqual(len(category.families), 1)

    def test_element_factory_class(self):
        instance = self.instance
        symbol = instance.symbol
        family = instance.family
        category = instance.category
        self.assertIsInstance(rpw.db.Element.Factory(instance.unwrap()), rpw.db.FamilyInstance)
        self.assertIsInstance(rpw.db.Element.Factory(symbol.unwrap()), rpw.db.FamilySymbol)
        self.assertIsInstance(rpw.db.Element.Factory(family.unwrap()), rpw.db.Family)

        # TODO: Move this. Category No Longer Element
        # self.assertIsInstance(rpw.db.Element.Factory(category.unwrap()), rpw.db.Category)


##################################################
# Wall / Wall Types / Wall Kind / Wall Category  #
##################################################

class WallTests(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING WALL...')

    def setUp(self):
        test_utils.delete_all_walls()
        test_utils.make_wall()
        wall = rpw.db.Collector(of_class='Wall', is_not_type=True).first
        self.wall = rpw.db.wall.Wall(wall)

    def tearDown(self):
        test_utils.delete_all_walls()

    def test_wall_instance_wrap(self):
        self.assertIsInstance(self.wall, rpw.db.wall.Wall)
        self.assertIsInstance(self.wall.unwrap(), DB.Wall)

    def test_wall_factory(self):
        wrapped = rpw.db.Element.Factory(self.wall.unwrap())
        self.assertIsInstance(wrapped, rpw.db.wall.Wall)
        wrapped = rpw.db.Element.Factory(self.wall.symbol.unwrap())
        self.assertIsInstance(wrapped, rpw.db.wall.WallType)
        # TODO: MOVE THESE > No Longer Element
        wrapped = rpw.db.WallKind(self.wall.family.unwrap())
        self.assertIsInstance(wrapped, rpw.db.WallKind)

    def test_wall_instance_symbol(self):
        wall_symbol = self.wall.symbol
        self.assertIsInstance(wall_symbol, rpw.db.wall.WallType)
        self.assertIsInstance(wall_symbol.unwrap(), DB.WallType)
        self.assertEqual(wall_symbol.name, 'Wall 1')
        self.assertEqual(len(wall_symbol.instances), 1)
        self.assertEqual(len(wall_symbol.siblings), 2)

    def test_wall_instance_family(self):
        wall_family = self.wall.family
        self.assertIsInstance(wall_family, rpw.db.wall.WallKind)
        self.assertEqual(wall_family.unwrap(), DB.WallKind.Basic)
        self.assertEqual(wall_family.name, 'Basic')
        self.assertEqual(len(wall_family.instances), 1)
        self.assertEqual(len(wall_family.symbols), 2)

    def test_wall_instance_category(self):
        wall_category = self.wall.category
        self.assertIsInstance(wall_category, rpw.db.wall.WallCategory)
        self.assertIsInstance(wall_category.unwrap(), DB.Category)
        self.assertEqual(wall_category.name, 'Walls')

    def test_wall_instance_category(self):
        wall_category = self.wall.category
        self.assertIsInstance(wall_category, rpw.db.wall.WallCategory)
        self.assertIsInstance(wall_category.unwrap(), DB.Category)
        self.assertEqual(wall_category.name, 'Walls')

    def test_wall_change_type_by_name(self):
        wall = self.wall
        with rpw.db.Transaction():
            wall.change_type('Wall 2')
        self.assertEqual(wall.wall_type.name, 'Wall 2')

    def test_wall_change_type(self):
        wall = self.wall
        wall_type = rpw.db.Collector(of_class='WallType', where=lambda w: w.name == 'Wall 2').first
        with rpw.db.Transaction():
            wall.change_type('Wall 2')
        self.assertEqual(wall.wall_type.name, 'Wall 2')

##################
# Rooms / Areas  #
##################

class RoomTests(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        pass
        # t = DB.Transaction(doc)
        # t.Start('Add Room')


    def setUp(self):
        room = rpw.db.Collector(os_category='OST_Rooms', is_not_type=True).first
        self.wall = rpw.db.wall.Wall(wall)
    #
    # def test_wall_instance_wrap(self):
    #     self.assertIsInstance(self.wall, rpw.db.wall.Wall)
    #     self.assertIsInstance(self.wall.unwrap(), DB.Wall)



"""
Selection Tests

Passes:
 * 2017.1

Revit Python Wrapper
github.com/gtalarico/revitpythonwrapper
revitpythonwrapper.readthedocs.io

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Copyright 2017 Gui Talarico

"""

import sys
import unittest
import os

parent = os.path.dirname
script_dir = parent(__file__)
panel_dir = parent(script_dir)
sys.path.append(script_dir)

import rpw
from rpw import DB, UI
doc, uidoc = rpw.revit.doc, rpw.revit.uidoc
from rpw.utils.logger import logger

import test_utils

def setUpModule():
    logger.title('SETTING UP SELECTION TESTS...')
    # uidoc.Application.OpenAndActivateDocument(os.path.join(panel_dir, 'collector.rvt'))

def tearDownModule():
    pass


######################
# SELECTION
######################


class SelectionTests(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING SELECTION...')
        test_utils.delete_all_walls()
        wall = test_utils.make_wall()
        cls.wall = wall

    @classmethod
    def tearDownClass(cls):
        test_utils.delete_all_walls()

    def setUp(self):
        self.wall = SelectionTests.wall
        self.selection = rpw.ui.Selection([self.wall.Id])

    def tearDown(self):
        self.selection.clear()
        logger.debug('SELECTION TEST PASSED')

    def test_selection_element_ids(self):
        ids = self.selection.element_ids
        self.assertTrue(all(
                        [isinstance(eid, DB.ElementId) for eid in ids]
                        ))

    def test_selection_elements(self):
        elements = self.selection.elements
        self.assertTrue(all(
                        [isinstance(e, DB.Element) for e in elements]
                        ))

    def test_selection_by_index(self):
        wall = self.selection[0]
        self.assertIsInstance(wall, DB.Wall)

    def test_selection_length(self):
        self.assertEqual(len(self.selection), 1)

    def test_selection_boolean(self):
        self.assertTrue(self.selection)

    def test_selection_boolean_false(self):
        self.selection.clear()
        self.assertFalse(self.selection)

    def test_selection_clear(self):
        self.selection.clear()
        self.assertEqual(len(self.selection), 0)
        self.selection = rpw.ui.Selection([self.wall.Id])

    def test_selection_add(self):
        selection = rpw.ui.Selection()
        selection.add([self.wall])
        self.assertIsInstance(selection[0], DB.Wall)

    def test_selection_contains(self):
        selection = rpw.ui.Selection()
        selection.add([self.wall])
        self.assertIn(self.wall, selection)

    def test_selection_updates_does_not_lose(self):
        selection = rpw.ui.Selection()
        selection2 = rpw.ui.Selection()
        selection2.update()
        self.assertEqual(selection[0].Id, selection2[0].Id)

    def test_selection_update(self):
        selection = rpw.ui.Selection()
        selection.update()

"""
Utils Tests

Passes:
 * 2017.1

Revit Python Wrapper
github.com/gtalarico/revitpythonwrapper
revitpythonwrapper.readthedocs.io

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Copyright 2017 Gui Talarico

"""

import sys
import unittest
import os

parent = os.path.dirname

script_dir = parent(__file__)
panel_dir = parent(script_dir)
sys.path.append(script_dir)

import rpw
from rpw import revit, DB, UI
from rpw.db import Element
from rpw.db import View, ViewPlan, ViewSection
from rpw.db import ViewSheet, ViewSchedule, View3D
from rpw.db import ViewFamilyType
from rpw.db import ViewType, ViewPlanType

from rpw.utils.logger import logger

# from rpw.utils.dotnet import List
# from rpw.exceptions import RpwParameterNotFound, RpwWrongStorageType

import test_utils

def setUpModule():
    logger.title('SETTING UP VIEW TESTS...')
    # test_utils.delete_all_walls()
    # test_utils.make_wall()

def tearDownModule():
    pass
    # test_utils.delete_all_walls()

class TestViewWrappers(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING View Classes...')
        cls.view = DB.FilteredElementCollector(revit.doc).OfClass(DB.View).FirstElement()
        cls.view_plan = DB.FilteredElementCollector(revit.doc).OfClass(DB.ViewPlan).FirstElement()
        cls.view_sheet = DB.FilteredElementCollector(revit.doc).OfClass(DB.ViewSheet).FirstElement()
        cls.view_schedule = DB.FilteredElementCollector(revit.doc).OfClass(DB.ViewSchedule).FirstElement()
        cls.view_section = DB.FilteredElementCollector(revit.doc).OfClass(DB.ViewSection).FirstElement()
        cls.view_3d = DB.FilteredElementCollector(revit.doc).OfClass(DB.View3D).FirstElement()
        cls.view_family_type = DB.FilteredElementCollector(revit.doc).OfClass(DB.ViewFamilyType).FirstElement()

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_view_wrapper(self):
        wrapped_view = Element(self.view)
        self.assertIsInstance(wrapped_view, View)
        wrapped_view = View(self.view)
        self.assertIsInstance(wrapped_view, View)

    def test_view_plan_wrapper(self):
        wrapped_view_plan = Element(self.view_plan)
        self.assertIsInstance(wrapped_view_plan, ViewPlan)
        wrapped_view_plan = ViewPlan(self.view_plan)
        self.assertIsInstance(wrapped_view_plan, ViewPlan)

    def test_view_section_wrapper(self):
        wrapped_view_section = Element(self.view_section)
        self.assertIsInstance(wrapped_view_section, ViewSection)
        wrapped_view_section = ViewSection(self.view_section)
        self.assertIsInstance(wrapped_view_section, ViewSection)

    def test_view_sheet_wrapper(self):
        wrapped_view_sheet = Element(self.view_sheet)
        self.assertIsInstance(wrapped_view_sheet, ViewSheet)
        wrapped_view_sheet = ViewSheet(self.view_sheet)
        self.assertIsInstance(wrapped_view_sheet, ViewSheet)

    def test_view_schedule_wrapper(self):
        wrapped_view_schedule = Element(self.view_schedule)
        self.assertIsInstance(wrapped_view_schedule, ViewSchedule)
        wrapped_view_schedule = ViewSchedule(self.view_schedule)
        self.assertIsInstance(wrapped_view_schedule, ViewSchedule)

    def test_view_3D(self):
        wrapped_view_3d = Element(self.view_3d)
        self.assertIsInstance(wrapped_view_3d, View3D)
        wrapped_view_3d = View3D(self.view_3d)
        self.assertIsInstance(wrapped_view_3d, View3D)

    def test_view_family_type(self):
        wrapped_view_family_type = Element(self.view_family_type)
        self.assertIsInstance(wrapped_view_family_type, ViewFamilyType)
        wrapped_view_family_type = ViewFamilyType(self.view_family_type)
        self.assertIsInstance(wrapped_view_family_type, ViewFamilyType)

class TestViewRelationships(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING View Classes...')
        cls.view = DB.FilteredElementCollector(revit.doc).OfClass(DB.View).FirstElement()
        cls.view_plan = DB.FilteredElementCollector(revit.doc).OfClass(DB.ViewPlan).FirstElement()
        cls.view_sheet = DB.FilteredElementCollector(revit.doc).OfClass(DB.ViewSheet).FirstElement()
        cls.view_schedule = DB.FilteredElementCollector(revit.doc).OfClass(DB.ViewSchedule).FirstElement()
        cls.view_section = DB.FilteredElementCollector(revit.doc).OfClass(DB.ViewSection).FirstElement()
        cls.view_3d = DB.FilteredElementCollector(revit.doc).OfClass(DB.View3D).FirstElement()
        cls.view_family_type = DB.FilteredElementCollector(revit.doc).OfClass(DB.ViewFamilyType).FirstElement()

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_view_type(self):
        wrapped_view = Element(self.view_3d)
        view_type = wrapped_view.view_type
        self.assertIsInstance(view_type.unwrap(), DB.ViewType)
        self.assertEqual(view_type.unwrap(), DB.ViewType.ThreeD)
        self.assertEqual(view_type.name, 'ThreeD')

    def test_view_plan_level(self):
        wrapped_view = Element(self.view_plan)
        level = wrapped_view.level
        self.assertIsInstance(level, DB.Level)

    def test_view_family_type(self):
        wrapped_view = Element(self.view_3d)
        view_type = wrapped_view.view_family_type
        self.assertIsInstance(view_type.unwrap(), DB.ViewFamilyType)

    def test_view_family(self):
        wrapped_view = Element(self.view_3d)
        view_family = wrapped_view.view_family
        self.assertIsInstance(view_family.unwrap(), DB.ViewFamily)

    def test_view_type_aggregator(self):
        wrapped_view_plan = Element(self.view_plan)
        same_view_type_views = wrapped_view_plan.view_type.views
        for view in same_view_type_views:
            self.assertEqual(view.view_type.unwrap(), wrapped_view_plan.view_type.unwrap())

    def test_view_family_aggregator(self):
        wrapped_view_plan = Element(self.view_plan)
        same_family_views = wrapped_view_plan.view_family.views
        for view in same_family_views:
            self.assertEqual(view.view_family.unwrap(), wrapped_view_plan.view_family.unwrap())

    def test_view_family_aggregator(self):
        wrapped_view_plan = Element(self.view_plan)
        same_view_family_type_views = wrapped_view_plan.view_family_type.views
        for view in same_view_family_type_views:
            self.assertEqual(view.view_family_type.unwrap(), wrapped_view_plan.view_family_type.unwrap())

    def test_view_family_type_name(self):
        wrapped_view = rpw.db.ViewPlan.collect(where=lambda x: x.view_family_type.name == 'Floor Plan').wrapped_elements[0]
        self.assertEqual(wrapped_view.view_family_type.name, 'Floor Plan')

    # def test_view_family_type_name_get_setter(self):
    #     wrapped_view = rpw.db.ViewPlan.collect(where=lambda x: x.view_family_type.name == 'My Floor Plan').wrapped_elements[0]
    #     # self.assertEqual(wrapped_view.view_family_type.name, 'My Floor Plan')
    #     with rpw.db.Transaction('Set Name'):
    #         wrapped_view.view_family_type.name = 'ABC'
    #     self.assertEqual(wrapped_view.view_family_type.name, 'ABC')
        # with rpw.db.Transaction('Set Name'):
            # wrapped_view.view_family_type.name = 'My Floor Plan'
        # rpw.ui.forms.Console()

class TestViewOverrides(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING View Classes...')
        cls.view_plan = revit.active_view.unwrap()
        # cls.view_plan = DB.FilteredElementCollector(revit.doc).OfClass(DB.ViewPlan).FirstElement()
        cls.wrapped_view = revit.active_view
        cls.element = DB.FilteredElementCollector(revit.doc).OfClass(DB.FamilyInstance).WhereElementIsNotElementType().FirstElement()

        linepattern = rpw.db.Collector(of_class='LinePatternElement', where=lambda x: x.Name == 'Dash').first
        cls.line_pattern_id = linepattern.Id
        fillpattern = rpw.db.Collector(of_class='FillPatternElement', where=lambda x: x.Name == 'Horizontal').first
        cls.fillpattern_id = fillpattern.Id

    def tearDown(cls):
        """ Resets Element after each test """
        with rpw.db.Transaction():
            cls.view_plan.SetElementOverrides(cls.element.Id, DB.OverrideGraphicSettings())

    def test_match(self):
        e1 = DB.FilteredElementCollector(revit.doc).OfClass(DB.FamilyInstance).WhereElementIsNotElementType().ToElements()[0]
        e2 = DB.FilteredElementCollector(revit.doc).OfClass(DB.FamilyInstance).WhereElementIsNotElementType().ToElements()[1]
        o = DB.OverrideGraphicSettings()
        o.SetHalftone(True)
        o.SetSurfaceTransparency(30)
        with rpw.db.Transaction():
            self.view_plan.SetElementOverrides(e1.Id, o)

        with rpw.db.Transaction():
            self.wrapped_view.override.match_element(e2, e1)
        rv = self.view_plan.GetElementOverrides(e2.Id)
        self.assertTrue(rv.Halftone)
        self.assertEqual(rv.Transparency, 30)

    def test_halftone(self):
        with rpw.db.Transaction():
            self.wrapped_view.override.halftone(self.element, True)
        rv = self.view_plan.GetElementOverrides(self.element.Id)
        self.assertTrue(rv.Halftone)

    def test_halftone(self):
        with rpw.db.Transaction():
            self.wrapped_view.override.halftone(self.element, True)
        rv = self.view_plan.GetElementOverrides(self.element.Id)
        self.assertTrue(rv.Halftone)

    def test_transparency(self):
        with rpw.db.Transaction():
            self.wrapped_view.override.transparency(self.element, 40)
        rv = self.view_plan.GetElementOverrides(self.element.Id)
        self.assertEqual(rv.Transparency, 40)

    def test_detail_level_by_enum(self):
        with rpw.db.Transaction():
            self.wrapped_view.override.detail_level(self.element, DB.ViewDetailLevel.Fine)
        rv = self.view_plan.GetElementOverrides(self.element.Id)
        self.assertEqual(rv.DetailLevel, DB.ViewDetailLevel.Fine)

    def test_detail_level_by_name(self):
        with rpw.db.Transaction():
            self.wrapped_view.override.detail_level(self.element, 'Fine')
        rv = self.view_plan.GetElementOverrides(self.element.Id)
        self.assertEqual(rv.DetailLevel, DB.ViewDetailLevel.Fine)

    def test_projection_line(self):
        with rpw.db.Transaction():
            self.wrapped_view.override.projection_line(self.element,
                                                       color=(0,120,255),
                                                       weight=5,
                                                       pattern=self.line_pattern_id)

        rv = self.view_plan.GetElementOverrides(self.element.Id)
        self.assertEqual(rv.ProjectionLineColor.Red, 0)
        self.assertEqual(rv.ProjectionLineColor.Green, 120)
        self.assertEqual(rv.ProjectionLineColor.Blue, 255)
        self.assertEqual(rv.ProjectionLineWeight, 5)
        self.assertEqual(rv.ProjectionLinePatternId, self.line_pattern_id)

    def test_projection_line_pattern_by_name(self):
        with rpw.db.Transaction():
            self.wrapped_view.override.projection_line(self.element, pattern='Dash')
            rv = self.view_plan.GetElementOverrides(self.element.Id)
            self.assertEqual(rv.ProjectionLinePatternId, self.line_pattern_id)

    def test_cut_line(self):
        with rpw.db.Transaction():
            self.wrapped_view.override.cut_line(self.element,
                                                color=(0,80,150),
                                                weight=7,
                                                pattern=self.line_pattern_id)

        rv = self.view_plan.GetElementOverrides(self.element.Id)
        self.assertEqual(rv.CutLineColor.Red, 0)
        self.assertEqual(rv.CutLineColor.Green, 80)
        self.assertEqual(rv.CutLineColor.Blue, 150)
        self.assertEqual(rv.CutLineWeight, 7)
        self.assertEqual(rv.CutLinePatternId, self.line_pattern_id)

    def test_cut_line_pattern_by_name(self):
        with rpw.db.Transaction():
            self.wrapped_view.override.cut_line(self.element, pattern='Dash')
            rv = self.view_plan.GetElementOverrides(self.element.Id)
            self.assertEqual(rv.CutLinePatternId, self.line_pattern_id)

    def test_projection_fill(self):
        with rpw.db.Transaction():
            self.wrapped_view.override.projection_fill(self.element,
                                                       color=(0,40,190),
                                                       pattern=self.fillpattern_id,
                                                       visible=False)

        rv = self.view_plan.GetElementOverrides(self.element.Id)
        self.assertEqual(rv.ProjectionFillColor.Red, 0)
        self.assertEqual(rv.ProjectionFillColor.Green, 40)
        self.assertEqual(rv.ProjectionFillColor.Blue, 190)
        self.assertEqual(rv.IsProjectionFillPatternVisible, False)
        self.assertEqual(rv.ProjectionFillPatternId, self.fillpattern_id)

    def test_projection_fill_pattern_by_name(self):
        with rpw.db.Transaction():
            self.wrapped_view.override.projection_fill(self.element, pattern='Horizontal')
            rv = self.view_plan.GetElementOverrides(self.element.Id)
            self.assertEqual(rv.ProjectionFillPatternId, self.fillpattern_id)

    def test_cut_fill(self):
        with rpw.db.Transaction():
            self.wrapped_view.override.cut_fill(self.element,
                                                color=(0,30,200),
                                                pattern=self.fillpattern_id,
                                                visible=False)

        rv = self.view_plan.GetElementOverrides(self.element.Id)
        self.assertEqual(rv.CutFillColor.Red, 0)
        self.assertEqual(rv.CutFillColor.Green, 30)
        self.assertEqual(rv.CutFillColor.Blue, 200)
        self.assertEqual(rv.IsCutFillPatternVisible, False)
        self.assertEqual(rv.CutFillPatternId, self.fillpattern_id)


    def test_cut_fill_pattern_by_name(self):
        with rpw.db.Transaction():
            self.wrapped_view.override.cut_fill(self.element, pattern='Horizontal')
            rv = self.view_plan.GetElementOverrides(self.element.Id)
            self.assertEqual(rv.CutFillPatternId, self.fillpattern_id)

    def test_halftone_category(self):
        with rpw.db.Transaction():
            self.wrapped_view.override.halftone('Furniture', True)
        rv = self.view_plan.GetCategoryOverrides(DB.ElementId(DB.BuiltInCategory.OST_Furniture))
        self.assertTrue(rv.Halftone)

    def test_halftone_category_bi(self):
        with rpw.db.Transaction():
            self.wrapped_view.override.halftone(DB.BuiltInCategory.OST_Furniture, True)
        rv = self.view_plan.GetCategoryOverrides(DB.ElementId(DB.BuiltInCategory.OST_Furniture))
        self.assertTrue(rv.Halftone)


"""
XYZ Tests

Passes:
 * 2017.1

Revit Python Wrapper
github.com/gtalarico/revitpythonwrapper
revitpythonwrapper.readthedocs.io

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Copyright 2017 Gui Talarico

"""

import sys
import unittest
import os

parent = os.path.dirname

script_dir = parent(__file__)
panel_dir = parent(script_dir)
sys.path.append(script_dir)

import rpw
from rpw import revit, DB, UI

doc, uidoc = revit.doc, revit.uidoc

from rpw.db.xyz import XYZ
from rpw.exceptions import RpwParameterNotFound, RpwWrongStorageType
from rpw.utils.logger import logger

# import test_utils

def setUpModule():
    logger.title('SETTING UP COLLECTION TESTS...')

def tearDownModule():
    pass
    # test_utils.delete_all_walls()

######################
# XYZTests
######################

class XYZInitTests(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING XYZ...')

    def test_xyz_from_2args(self):
        pt = XYZ(2,4)
        self.assertEqual(pt.X, 2)
        self.assertEqual(pt.Y, 4)
        self.assertEqual(pt.Z, 0)

    def test_xyz_from_3args(self):
        pt = XYZ(2,4,6)
        self.assertEqual(pt.X, 2)
        self.assertEqual(pt.Y, 4)
        self.assertEqual(pt.Z, 6)

    def test_xyz_from_tuple2(self):
        pt = XYZ([2,4])
        self.assertEqual(pt.X, 2)
        self.assertEqual(pt.Y, 4)
        self.assertEqual(pt.Z, 0)

    def test_xyz_from_tuple3(self):
        pt = XYZ([2,4,6])
        self.assertEqual(pt.X, 2)
        self.assertEqual(pt.Y, 4)
        self.assertEqual(pt.Z, 6)

    def test_xyz_from_DB_XYZ(self):
        pt = XYZ(DB.XYZ(2,4,6))
        self.assertEqual(pt.X, 2)
        self.assertEqual(pt.Y, 4)
        self.assertEqual(pt.Z, 6)

    def test_xyz_from_XYZ(self):
        pt = XYZ(XYZ(2,4,6))
        self.assertEqual(pt.X, 2)
        self.assertEqual(pt.Y, 4)
        self.assertEqual(pt.Z, 6)

class XYZUsageTests(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING XYZ Usage...')
        cls.pt = XYZ(1,2,3)
        cls.pt2 = XYZ(4,5,6)

    def test_xyz_get_properties(self):
        pt = XYZ(1,2,3)
        self.assertEqual(pt.x, 1)
        self.assertEqual(pt.y, 2)
        self.assertEqual(pt.z, 3)

    def test_xyz_set_properties(self):
        pt = XYZ(1,2,3)
        pt.x = 5
        pt.y = 6
        pt.z = 7
        self.assertEqual(pt.x, 5)
        self.assertEqual(pt.y, 6)
        self.assertEqual(pt.z, 7)

    def test_xyz_at_z(self):
        pt = XYZ(1,2,3).at_z(10)
        self.assertEqual(pt.z, 10)

    def test_xyz_as_tuple(self):
        pt_tuple = XYZ(1,2,3).as_tuple
        self.assertEqual(pt_tuple, (1,2,3))
        self.assertIsInstance(pt_tuple, tuple)

    def test_xyz_as_dict(self):
        pt_dict = XYZ(1,2,3).as_dict
        self.assertIsInstance(pt_dict, dict)
        self.assertEqual(pt_dict, {'x':1, 'y':2, 'z':3})

    def test_xyz_repr(self):
        self.assertIn('<rpw:XYZ', XYZ(0,0,0).__repr__())

    def test_xyz_add(self):
        pt = XYZ(1,2,3) + XYZ(4,5,6)
        self.assertEqual(pt.x, 5)
        self.assertEqual(pt.y, 7)
        self.assertEqual(pt.z, 9)

    def test_xyz_sub(self):
        pt = XYZ(1,2,3) - XYZ(1,1,1)
        self.assertEqual(pt.x, 0)
        self.assertEqual(pt.y, 1)
        self.assertEqual(pt.z, 2)

    def test_xyz_mul(self):
        pt = XYZ(1,2,3) * 2
        self.assertEqual(pt.x, 2)
        self.assertEqual(pt.y, 4)
        self.assertEqual(pt.z, 6)

    def test_xyz_eq(self):
        self.assertEqual(XYZ(1,2,3), XYZ(1,2,3))
        self.assertNotEqual(XYZ(1,2,3), XYZ(2,2,3))

    def test_xyz_rotate_90(self):
        pt = XYZ(1,0,0)
        rotate_pt = (0,1,0)
        self.assertEqual(pt.rotate(90), rotate_pt)

    def test_xyz_rotate_180(self):
        pt = XYZ(1,0,0)
        rotate_pt = (-1,0,0)
        self.assertEqual(pt.rotate(180), rotate_pt)

    def test_xyz_rotate_radians(self):
        import math
        pt = XYZ(1,0,0)
        rotate_pt = (-1,0,0)
        self.assertEqual(pt.rotate(math.pi, radians=True), rotate_pt)

    def test_xyz_rotate_radians(self):
        import math
        pt = XYZ(1,0,0)
        rotate_pt = (-1,0,0)
        self.assertEqual(pt.rotate(math.pi, radians=True), rotate_pt)

    def test_xyz_rotate_axis(self):
        import math
        pt = XYZ(1,0,0)
        axis = XYZ(0,-1,0)
        rotate_pt = (0,0,1)
        self.assertEqual(pt.rotate(90, axis=axis), rotate_pt)


"""
Transaction Tests

Passes:
 * 2017.1

Revit Python Wrapper
github.com/gtalarico/revitpythonwrapper
revitpythonwrapper.readthedocs.io

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Copyright 2017 Gui Talarico

"""

import sys
import unittest
import os

parent = os.path.dirname

script_dir = parent(__file__)
panel_dir = parent(script_dir)
sys.path.append(script_dir)

import rpw
from rpw import revit, DB, UI
from rpw.utils.dotnet import List
from rpw.utils.logger import logger
doc = rpw.revit.doc

import test_utils

def setUpModule():
    logger.title('SETTING UP TRANSACTION TESTS...')

def tearDownModule():
    pass


class TransactionsTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        logger.title('TESTING TRANSACTIONS...')
        test_utils.delete_all_walls()
        wall = test_utils.make_wall()
        cls.wall = wall

    @classmethod
    def tearDownClass(cls):
        test_utils.delete_all_walls()

    def setUp(self):
        wall = DB.FilteredElementCollector(doc).OfClass(DB.Wall).ToElements()[0]
        self.wall = rpw.db.Wall(wall)
        with rpw.db.Transaction('Reset Comment') as t:
            self.wall.parameters['Comments'] = ''

    def test_transaction_instance(self):
        with rpw.db.Transaction('Test Is Instance') as t:
            self.wall.parameters['Comments'].value = ''
            self.assertIsInstance(t.unwrap(), DB.Transaction)

    def test_transaction_started(self):
        with rpw.db.Transaction('Has Started') as t:
            self.wall.parameters['Comments'].value = ''
            self.assertTrue(t.HasStarted())

    def test_transaction_has_ended(self):
        with rpw.db.Transaction('Add Comment') as t:
            self.wall.parameters['Comments'].value = ''
            self.assertFalse(t.HasEnded())

    def test_transaction_get_name(self):
        with rpw.db.Transaction('Named Transaction') as t:
            self.assertEqual(t.GetName(), 'Named Transaction')

    def test_transaction_commit_status_success(self):
        with rpw.db.Transaction('Set String') as t:
            self.wall.parameters['Comments'].value = ''
            self.assertEqual(t.GetStatus(), DB.TransactionStatus.Started)
        self.assertEqual(t.GetStatus(), DB.TransactionStatus.Committed)

    def test_transaction_commit_status_rollback(self):
        with self.assertRaises(Exception):
            with rpw.db.Transaction('Set String') as t:
                self.wall.parameters['Top Constraint'].value = DB.ElementId('a')
        self.assertEqual(t.GetStatus(), DB.TransactionStatus.RolledBack)

    def test_transaction_group(self):
        with rpw.db.TransactionGroup('Multiple Transactions') as tg:
            self.assertEqual(tg.GetStatus(), DB.TransactionStatus.Started)
            with rpw.db.Transaction('Set String') as t:
                self.assertEqual(t.GetStatus(), DB.TransactionStatus.Started)
                self.wall.parameters['Comments'].value = '1'
            self.assertEqual(t.GetStatus(), DB.TransactionStatus.Committed)
        self.assertEqual(tg.GetStatus(), DB.TransactionStatus.Committed)

    def test_transaction_decorator(self):
        @rpw.db.Transaction.ensure('Transaction Name')
        def somefunction():
            param = self.wall.parameters['Comments'].value = '1'
            return param
        self.assertTrue(somefunction())


"""
Utils Tests

Passes:
 * 2017.1

Revit Python Wrapper
github.com/gtalarico/revitpythonwrapper
revitpythonwrapper.readthedocs.io

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Copyright 2017 Gui Talarico

"""

import sys
import unittest
import os

parent = os.path.dirname

script_dir = parent(__file__)
panel_dir = parent(script_dir)
sys.path.append(script_dir)

import rpw
from rpw import revit, DB, UI
from rpw.utils.dotnet import List
from rpw.exceptions import RpwParameterNotFound, RpwWrongStorageType
from rpw.utils.logger import logger

import test_utils

def setUpModule():
    logger.title('SETTING UP UTILS TESTS...')
    test_utils.delete_all_walls()
    test_utils.make_wall()

def tearDownModule():
    test_utils.delete_all_walls()

class CoerceTests(unittest.TestCase):

    @classmethod
    def setUpClass(self):
        logger.title('TESTING COERCE FUNCITONS...')

    def setUp(self):
        self.wall = rpw.db.Collector(of_class='Wall').first

    def tearDown(self):
        pass

    def test_corce_into_id(self):
        id_ = rpw.utils.coerce.to_element_id(self.wall)
        self.assertIsInstance(id_, DB.ElementId)

    def test_corce_into_ids(self):
        ids = rpw.utils.coerce.to_element_ids([self.wall])
        all_id = all([isinstance(i, DB.ElementId) for i in ids])
        self.assertTrue(all_id)

    def test_corce_element_ref_int(self):
        element = rpw.utils.coerce.to_element(self.wall.Id.IntegerValue)
        self.assertIsInstance(element, DB.Element)

    def test_corce_element_ref_id(self):
        wall_id = DB.ElementId(self.wall.Id.IntegerValue)
        elements = rpw.utils.coerce.to_elements([wall_id])
        self.assertTrue(all([isinstance(e, DB.Element) for e in elements]))

    def test_corce_to_element_diverse(self):
        elements = rpw.utils.coerce.to_elements([self.wall, self.wall.Id, self.wall.Id.IntegerValue])
        self.assertTrue(all([isinstance(e, DB.Element) for e in elements]))

    def test_to_class_wall(self):
        self.assertIs(rpw.utils.coerce.to_class('Wall'), DB.Wall)

    def test_to_class_view(self):
        self.assertIs(rpw.utils.coerce.to_class('View'), DB.View)

    def test_to_category_walls(self):
        self.assertIs(rpw.utils.coerce.to_category('Walls'), DB.BuiltInCategory.OST_Walls)
        self.assertIs(rpw.utils.coerce.to_category('walls'), DB.BuiltInCategory.OST_Walls)
        self.assertIs(rpw.utils.coerce.to_category('ost_walls'), DB.BuiltInCategory.OST_Walls)

    def test_to_category_id_walls(self):
        self.assertEqual(rpw.utils.coerce.to_category_id('Walls'), DB.ElementId(DB.BuiltInCategory.OST_Walls))
        self.assertEqual(rpw.utils.coerce.to_category_id('walls'), DB.ElementId(DB.BuiltInCategory.OST_Walls))
        self.assertEqual(rpw.utils.coerce.to_category_id('ost_walls'), DB.ElementId(DB.BuiltInCategory.OST_Walls))

    def test_to_category_stacked_walls(self):
        self.assertIs(rpw.utils.coerce.to_category('ost_StackedWalls'), DB.BuiltInCategory.OST_StackedWalls)
        self.assertIs(rpw.utils.coerce.to_category('StackedWalls'), DB.BuiltInCategory.OST_StackedWalls)
        self.assertIs(rpw.utils.coerce.to_category('stackedwalls'), DB.BuiltInCategory.OST_StackedWalls)
        self.assertIs(rpw.utils.coerce.to_category('stacked walls'), DB.BuiltInCategory.OST_StackedWalls)

    def test_to_iterable(self):
        self.assertTrue([w for w in rpw.utils.coerce.to_iterable(self.wall)])

    def test_to_iterable_element_id(self):
        self.assertTrue([w for w in rpw.utils.coerce.to_element_ids(self.wall)])

    def test_to_iterable_element(self):
        self.assertTrue([w for w in rpw.utils.coerce.to_elements(self.wall)])


    # TODO: Add BuiltInCategory Tests
    # CATEGORY COERCE
    # >>> with rpw.db.Transaction():
    # ... 	rpw.revit.active_view.override.projection_line(BuiltInCategory.OST_Furniture, color=[255,0,255])
    # ...
    # >>> with rpw.db.Transaction():
    # ... 	rpw.revit.active_view.override.projection_line(ElementId(BuiltInCategory.OST_Furniture), color=[255,0,255])
    # ...
    # >>> with rpw.db.Transaction():
    # ... 	rpw.revit.active_view.override.projection_line(ElementId(BuiltInCategory.OST_Furniture), color=[255,0,120])
    # ...
    # >>>

"""
Selection Tests

Passes:
 * 2017.1

Revit Python Wrapper
github.com/gtalarico/revitpythonwrapper
revitpythonwrapper.readthedocs.io

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Copyright 2017 Gui Talarico

"""

import sys
import unittest
import os

parent = os.path.dirname
script_dir = parent(__file__)
panel_dir = parent(script_dir)
sys.path.append(script_dir)

import rpw
from rpw import DB, UI
doc, uidoc = rpw.revit.doc, rpw.revit.uidoc
from rpw.utils.logger import logger
from rpw.ui.selection import Pick
from rpw.db.reference import Reference
from rpw.db.xyz import XYZ
from rpw.db.element import Element

import test_utils

def setUpModule():
    logger.title('SETTING UP PICK TESTS...')

def tearDownModule():
    pass


######################
# SELECTION
######################


class PickTests(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        logger.title('TESTING PICK...')
        test_utils.delete_all_walls()
        wall = test_utils.make_wall()
        cls.wall = wall

    @classmethod
    def tearDownClass(cls):
        test_utils.delete_all_walls()

    def setUp(self):
        self.wall = PickTests.wall
        # Pick().clear()

    def tearDown(self):
        # Pick().clear()
        logger.debug('SELECTION TEST PASSED')

    def test_pick_element(self):
        selection = Pick()
        desk = selection.pick_element('Pick a Desk')
        self.assertIsInstance(desk, Reference)

    def test_pick_elements(self):
        selection = Pick()
        desks = selection.pick_element('Pick 2 Desks', multiple=True)
        self.assertIsInstance(desks[0], Reference)

    def test_pick_element_point(self):
        selection = Pick()
        rv = selection.pick_pt_on_element('pick_pt_on_element')
        self.assertIsInstance(rv, Reference)
        rv = selection.pick_pt_on_element('pick_pt_on_element', multiple=True)
        self.assertIsInstance(rv[0], Reference)

    def test_pick_element_edge(self):
        selection = Pick()
        rv = selection.pick_edge('pick_edge')
        self.assertIsInstance(rv, Reference)
        rv = selection.pick_edge('pick_edges', multiple=True)
        self.assertIsInstance(rv[0], Reference)

    def test_pick_element_face(self):
        selection = Pick()
        rv = selection.pick_face('pick_face')
        self.assertIsInstance(rv, Reference)
        rv = selection.pick_face('pick_faces', multiple=True)
        self.assertIsInstance(rv[0], Reference)

    def test_pick_pt(self):
        selection = Pick()
        rv = selection.pick_pt('pick_pt')
        self.assertIsInstance(rv, XYZ)

    def test_pick_snaps(self):
        selection = Pick()
        rv = selection.pick_pt('pick_pt', snap='endpoints')
        self.assertIsInstance(rv, XYZ)

    def test_pick_box(self):
        selection = Pick()
        rv = selection.pick_box('PickBox')
        self.assertIsInstance(rv[0], XYZ)

    def test_pick_by_rectangle(self):
        selection = Pick()
        rv = selection.pick_by_rectangle('Pick By Rectangle')
        self.assertIsInstance(rv[0], Element)

    # def test_pick_linked(self):
    #     selection = Pick()
    #     rv = selection.pick_linked_element('pick_linked_element')
    #     rpw.ui.Console()



""" Revit Python Wrapper Tests - Forms

Passes:
2017

"""

import sys
import unittest
import os

test_dir = os.path.dirname(__file__)
root_dir = os.path.dirname(test_dir)
sys.path.append(root_dir)

import rpw
from rpw import revit, DB, UI
doc, uidoc = rpw.revit.doc, rpw.revit.uidoc

from rpw.utils.dotnet import List
from rpw.exceptions import RpwParameterNotFound, RpwWrongStorageType
from rpw.utils.logger import logger

data = ['A', 'B', 'C']

######################
# FORMS
######################


class FormSelectFromListTests(unittest.TestCase):

    def test_get_value(self):
        value = rpw.ui.forms.SelectFromList('Select From List Test', data,
                                        description='Select A and click select',
                                        exit_on_close=False)
        self.assertEqual(value, 'A')

    def test_get_dict_value(self):
        value = rpw.ui.forms.SelectFromList('Select From List Test', {'A':10},
                                            description='Select A and click select',
                                            exit_on_close=False)
        self.assertEqual(value, 10)

    def test_cancel(self):
        value = rpw.ui.forms.SelectFromList('Test Cancel', data,
                                        description='CLOSE WITHOUT SELECTING',
                                        exit_on_close=False)
        self.assertIsNone(value)

    def test_close_exit(self):
        with self.assertRaises(SystemExit):
            rpw.ui.forms.SelectFromList('Text Exit on Close', data,
                                        description='CLOSE WITHOUT SELECTING',
                                        exit_on_close=True)


class FormTextInputTests(unittest.TestCase):

    def test_get_value(self):
        value = rpw.ui.forms.TextInput('Text Input', default='A',
                                       description='select with letter A',
                                       exit_on_close=False)
        self.assertEqual(value, 'A')

    def test_cancel(self):
        value = rpw.ui.forms.TextInput('Test Cancel', default='A',
                                   description='CLOSE FORM',
                                   exit_on_close=False)
        self.assertIsNone(value)

    def test_close_exit(self):
        with self.assertRaises(SystemExit):
            rpw.ui.forms.TextInput('Test Exit on Close', default='A',
                                    description='CLOSE FORM',
                                    exit_on_close=True)


class FlexFormTests(unittest.TestCase):

    def test_flex_form_launch(self):
        components = [rpw.ui.forms.Label('Test'), rpw.ui.forms.Button('Click Here')]
        form = rpw.ui.forms.FlexForm('Text Input', components)
        form_result = form.show()
        self.assertTrue(form_result)

    def test_flex_form(self):
        components = [rpw.ui.forms.Label('Test'),
                      rpw.ui.forms.TextBox('textbox', default='Default Value'),
                      rpw.ui.forms.ComboBox('combo', {'A':0, 'B':1}, default='B'),
                      rpw.ui.forms.CheckBox('checkbox', 'SELECTED', default=True),
                      rpw.ui.forms.Separator(),
                      rpw.ui.forms.Button('Click Here'),
                      ]
        form = rpw.ui.forms.FlexForm('Text Input', components)
        form_result = form.show()
        self.assertTrue(form_result)
        self.assertEqual(form.values['checkbox'], True)
        self.assertEqual(form.values['combo'], 1)
        self.assertEqual(form.values['textbox'], 'Default Value')