bebraw
1/5/2010 - 7:13 PM

file.py

from mock import Mock, patch, sentinel
from placidity.file import File

def mock_with(mock, file_mock):
    mock.return_value = Mock()
    mock.return_value.__enter__ = Mock()
    mock.return_value.__enter__.return_value = file_mock
    mock.return_value.__exit__ = Mock()

def mock_with_read(mock, read_return=sentinel.file_contents):
    file_mock = Mock()
    file_mock.read.return_value = read_return

    mock_with(mock, file_mock)

class TestFile:

    @patch('__builtin__.open')
    def test_get_file_name(self, open_mock):
        mock_with_read(open_mock)

        file = File('/path/to/file')

        assert file.name == 'file'

    @patch('__builtin__.open')
    def test_get_file_parent(self, open_mock):
        mock_with_read(open_mock)

        file = File('/path/to/file')

        assert file.parent.name == 'to'
        assert file.parent.parent.name == 'path'

    @patch('__builtin__.open')
    def test_get_directory_children(self, open_mock):
        mock_with_read(open_mock)

        file = File('/path/to/file')

        directory = file.parent

        assert directory.children == [file, ]

    @patch('__builtin__.open')
    def test_find_child_by_name(self, open_mock):
        mock_with_read(open_mock)

        file = File('/path/to/file')

        directory = file.parent

        assert directory.find(name='file') == file

    @patch('__builtin__.open')
    def test_load_python_file(self, open_mock):
        read_return_value = '''
class Bar: flag = True
class Foo: flag = False
        '''
        
        mock_with_read(open_mock, read_return_value)

        file = File(sentinel.filepath)

        assert 'bar' in file.classes
        assert file.classes['bar'].flag == True
        assert 'foo' in file.classes
        assert file.classes['foo'].flag == False
import inspect
import imp
import os
import tempfile

class File:

    def __init__(self, path=None):
        self.classes = {}

        self.__init_classes(path)
        self.__init_structure(path)

    def __init_classes(self, path):
        with open(path, 'r') as f:
            file_content = f.read()

            # http://docs.python.org/library/tempfile.html#tempfile.mktemp
            temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.py')
            temp_file.write(file_content)
            temp_file.close()

            try:
                module = imp.load_source('', temp_file.name)
            except Exception, e:
                print e

            module_classes = inspect.getmembers(module, inspect.isclass)

            for name, klass in module_classes:
                self.classes[name.lower()] = klass

            os.unlink(temp_file.name)
            os.unlink(temp_file.name + 'c')

    def __init_structure(self, path):
        if not isinstance(path, str) or not path:
            return

        current_node = self
        parts = path.split('/')

        for part in reversed(parts):
            current_node.name = part
            current_node.parent = File()
            current_node.parent.children = [current_node, ]
            current_node = current_node.parent

    def find(self, name):
        for child in self.children:
            if child.name == name:
                return child