mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 01:47:36 +03:00 
			
		
		
		
	Make second round of the refactoring
This commit is contained in:
		
							parent
							
								
									d5fd46b159
								
							
						
					
					
						commit
						59ca0f8ace
					
				| 
						 | 
					@ -2,38 +2,48 @@ Movie lister - a naive example of dependency injection in Python
 | 
				
			||||||
================================================================
 | 
					================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This is a Python implementation of the dependency injection example from Martin Fowler's
 | 
					This is a Python implementation of the dependency injection example from Martin Fowler's
 | 
				
			||||||
article about dependency injection and inversion of control:
 | 
					article:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    http://www.martinfowler.com/articles/injection.html
 | 
					    http://www.martinfowler.com/articles/injection.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Create virtual environment:
 | 
					Run
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Create a virtual environment:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. code-block:: bash
 | 
					.. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   virtualenv venv
 | 
					   virtualenv venv
 | 
				
			||||||
   . venv/bin/activate
 | 
					   . venv/bin/activate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Install requirements:
 | 
					Install the requirements:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. code-block:: bash
 | 
					.. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pip install -r requirements.txt
 | 
					    pip install -r requirements.txt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To create the fixtures do:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   python data/fixtures.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
To run the application do:
 | 
					To run the application do:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. code-block:: bash
 | 
					.. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   MOVIE_STORAGE_TYPE=csv python -m movies
 | 
					   MOVIE_FINDER_TYPE=csv python -m movies
 | 
				
			||||||
   MOVIE_STORAGE_TYPE=sqlite python -m movies
 | 
					   MOVIE_FINDER_TYPE=sqlite python -m movies
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The output should be something like:
 | 
					The output should be something like:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. code-block:: bash
 | 
					.. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   [Movie(name='The Hunger Games: Mockingjay - Part 2', year=2015, director='Francis Lawrence')]
 | 
					   Francis Lawrence movies: [Movie(name='The Hunger Games: Mockingjay - Part 2', year=2015, director='Francis Lawrence')]
 | 
				
			||||||
   [Movie(name='The 33', year=2015, director='Patricia Riggen')]
 | 
					   2016 movies: [Movie(name='Rogue One: A Star Wars Story', year=2016, director='Gareth Edwards'), Movie(name='The Jungle Book', year=2016, director='Jon Favreau')]
 | 
				
			||||||
   [Movie(name='Star Wars: Episode VII - The Force Awakens', year=2015, director='JJ Abrams')]
 | 
					
 | 
				
			||||||
   [Movie(name='The Hunger Games: Mockingjay - Part 2', year=2015, director='Francis Lawrence'), Movie(name='The 33', year=2015, director='Patricia Riggen'), Movie(name='Star Wars: Episode VII - The Force Awakens', year=2015, director='JJ Abrams')]
 | 
					Test
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
To run the tests do:
 | 
					To run the tests do:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,13 +65,11 @@ The output should be something like:
 | 
				
			||||||
   Name                   Stmts   Miss  Cover
 | 
					   Name                   Stmts   Miss  Cover
 | 
				
			||||||
   ------------------------------------------
 | 
					   ------------------------------------------
 | 
				
			||||||
   movies/__init__.py         0      0   100%
 | 
					   movies/__init__.py         0      0   100%
 | 
				
			||||||
   movies/__main__.py        15     15     0%
 | 
					   movies/__main__.py        10     10     0%
 | 
				
			||||||
   movies/containers.py       9      0   100%
 | 
					   movies/containers.py       9      0   100%
 | 
				
			||||||
   movies/finders.py          9      0   100%
 | 
					   movies/entities.py         7      1    86%
 | 
				
			||||||
   movies/fixtures.py         1      0   100%
 | 
					   movies/finders.py         26     13    50%
 | 
				
			||||||
   movies/listers.py          8      0   100%
 | 
					   movies/listers.py          8      0   100%
 | 
				
			||||||
   movies/models.py           7      1    86%
 | 
					 | 
				
			||||||
   movies/storages.py        32     17    47%
 | 
					 | 
				
			||||||
   movies/tests.py           24      0   100%
 | 
					   movies/tests.py           24      0   100%
 | 
				
			||||||
   ------------------------------------------
 | 
					   ------------------------------------------
 | 
				
			||||||
   TOTAL                    105     33    69%
 | 
					   TOTAL                     84     24    71%
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
storage:
 | 
					finder:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  csv:
 | 
					  csv:
 | 
				
			||||||
    path: "data/movies.csv"
 | 
					    path: "data/movies.csv"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
# Ignore everything in this directory
 | 
					# Everything
 | 
				
			||||||
*
 | 
					*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Except this file:
 | 
					# Except this file:
 | 
				
			||||||
!.gitignore
 | 
					!.gitignore
 | 
				
			||||||
 | 
					!fixtures.py
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										43
									
								
								examples/miniapps/movie-lister/data/fixtures.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								examples/miniapps/movie-lister/data/fixtures.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,43 @@
 | 
				
			||||||
 | 
					"""Fixtures module."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import csv
 | 
				
			||||||
 | 
					import sqlite3
 | 
				
			||||||
 | 
					import pathlib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SAMPLE_DATA = [
 | 
				
			||||||
 | 
					    ('The Hunger Games: Mockingjay - Part 2', 2015, 'Francis Lawrence'),
 | 
				
			||||||
 | 
					    ('Rogue One: A Star Wars Story', 2016, 'Gareth Edwards'),
 | 
				
			||||||
 | 
					    ('The Jungle Book', 2016, 'Jon Favreau'),
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FILE = pathlib.Path(__file__)
 | 
				
			||||||
 | 
					DIR = FILE.parent
 | 
				
			||||||
 | 
					CSV_FILE = DIR / 'movies.csv'
 | 
				
			||||||
 | 
					SQLITE_FILE = DIR / 'movies.db'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def create_csv(movies_data, path):
 | 
				
			||||||
 | 
					    with open(path, 'w') as opened_file:
 | 
				
			||||||
 | 
					        writer = csv.writer(opened_file)
 | 
				
			||||||
 | 
					        for row in movies_data:
 | 
				
			||||||
 | 
					            writer.writerow(row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def create_sqlite(movies_data, path):
 | 
				
			||||||
 | 
					    with sqlite3.connect(path) as db:
 | 
				
			||||||
 | 
					        db.execute(
 | 
				
			||||||
 | 
					            'CREATE TABLE IF NOT EXISTS movies '
 | 
				
			||||||
 | 
					            '(name text, year int, director text)'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        db.execute('DELETE FROM movies')
 | 
				
			||||||
 | 
					        db.executemany('INSERT INTO movies VALUES (?,?,?)', movies_data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def main():
 | 
				
			||||||
 | 
					    create_csv(SAMPLE_DATA, CSV_FILE)
 | 
				
			||||||
 | 
					    create_sqlite(SAMPLE_DATA, SQLITE_FILE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    main()
 | 
				
			||||||
| 
						 | 
					@ -5,18 +5,20 @@ from .containers import ApplicationContainer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def main():
 | 
					def main():
 | 
				
			||||||
    container = ApplicationContainer()
 | 
					    container = ApplicationContainer()
 | 
				
			||||||
    container.config.from_yaml('config.yml')
 | 
					 | 
				
			||||||
    container.config.storage.type.from_env('MOVIE_STORAGE_TYPE')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    storage = container.storage()
 | 
					    container.config.from_yaml('config.yml')
 | 
				
			||||||
    fixtures = container.fixtures()
 | 
					    container.config.finder.type.from_env('MOVIE_FINDER_TYPE')
 | 
				
			||||||
    storage.load_all(fixtures)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    lister = container.lister()
 | 
					    lister = container.lister()
 | 
				
			||||||
    print(lister.movies_directed_by('Francis Lawrence'))
 | 
					
 | 
				
			||||||
    print(lister.movies_directed_by('Patricia Riggen'))
 | 
					    print(
 | 
				
			||||||
    print(lister.movies_directed_by('JJ Abrams'))
 | 
					        'Francis Lawrence movies:',
 | 
				
			||||||
    print(lister.movies_released_in(2015))
 | 
					        lister.movies_directed_by('Francis Lawrence'),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    print(
 | 
				
			||||||
 | 
					        '2016 movies:',
 | 
				
			||||||
 | 
					        lister.movies_released_in(2016),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,33 +2,32 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from dependency_injector import containers, providers
 | 
					from dependency_injector import containers, providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from . import finders, listers, storages, models, fixtures
 | 
					from . import finders, listers, entities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ApplicationContainer(containers.DeclarativeContainer):
 | 
					class ApplicationContainer(containers.DeclarativeContainer):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    config = providers.Configuration()
 | 
					    config = providers.Configuration()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fixtures = providers.Object(fixtures.MOVIES_SAMPLE_DATA)
 | 
					    movie = providers.Factory(entities.Movie)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    storage = providers.Selector(
 | 
					    csv_finder = providers.Singleton(
 | 
				
			||||||
        config.storage.type,
 | 
					        finders.CsvMovieFinder,
 | 
				
			||||||
        csv=providers.Singleton(
 | 
					        movie_factory=movie.provider,
 | 
				
			||||||
            storages.CsvMovieStorage,
 | 
					        path=config.finder.csv.path,
 | 
				
			||||||
            options=config.storage[config.storage.type],
 | 
					        delimiter=config.finder.csv.delimiter,
 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        sqlite=providers.Singleton(
 | 
					 | 
				
			||||||
            storages.SqliteMovieStorage,
 | 
					 | 
				
			||||||
            options=config.storage[config.storage.type],
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    movie = providers.Factory(models.Movie)
 | 
					    sqlite_finder = providers.Singleton(
 | 
				
			||||||
 | 
					        finders.SqliteMovieFinder,
 | 
				
			||||||
    finder = providers.Factory(
 | 
					 | 
				
			||||||
        finders.MovieFinder,
 | 
					 | 
				
			||||||
        movie_factory=movie.provider,
 | 
					        movie_factory=movie.provider,
 | 
				
			||||||
        movie_storage=storage,
 | 
					        path=config.finder.sqlite.path,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    finder = providers.Selector(
 | 
				
			||||||
 | 
					        config.finder.type,
 | 
				
			||||||
 | 
					        csv=csv_finder,
 | 
				
			||||||
 | 
					        sqlite=sqlite_finder,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    lister = providers.Factory(
 | 
					    lister = providers.Factory(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,23 +1,50 @@
 | 
				
			||||||
"""Movie finders module."""
 | 
					"""Movie finders module."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import csv
 | 
				
			||||||
 | 
					import sqlite3
 | 
				
			||||||
from typing import Callable, List
 | 
					from typing import Callable, List
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .models import Movie
 | 
					from .entities import Movie
 | 
				
			||||||
from .storages import MovieStorage
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MovieFinder:
 | 
					class MovieFinder:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, movie_factory: Callable[..., Movie]) -> None:
 | 
				
			||||||
 | 
					        self._movie_factory = movie_factory
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def find_all(self) -> List[Movie]:
 | 
				
			||||||
 | 
					        raise NotImplementedError()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CsvMovieFinder(MovieFinder):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(
 | 
					    def __init__(
 | 
				
			||||||
            self,
 | 
					            self,
 | 
				
			||||||
            movie_factory: Callable[..., Movie],
 | 
					            movie_factory: Callable[..., Movie],
 | 
				
			||||||
            movie_storage: MovieStorage,
 | 
					            path: str,
 | 
				
			||||||
 | 
					            delimiter: str,
 | 
				
			||||||
    ) -> None:
 | 
					    ) -> None:
 | 
				
			||||||
        self._movie_factory = movie_factory
 | 
					        self._csv_file_path = path
 | 
				
			||||||
        self._movie_storage = movie_storage
 | 
					        self._delimiter = delimiter
 | 
				
			||||||
 | 
					        super().__init__(movie_factory)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def find_all(self) -> List[Movie]:
 | 
					    def find_all(self) -> List[Movie]:
 | 
				
			||||||
        return [
 | 
					        with open(self._csv_file_path) as csv_file:
 | 
				
			||||||
            self._movie_factory(*row)
 | 
					            csv_reader = csv.reader(csv_file, delimiter=self._delimiter)
 | 
				
			||||||
            for row in self._movie_storage.get_all()
 | 
					            return [self._movie_factory(*row) for row in csv_reader]
 | 
				
			||||||
        ]
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SqliteMovieFinder(MovieFinder):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(
 | 
				
			||||||
 | 
					            self,
 | 
				
			||||||
 | 
					            movie_factory: Callable[..., Movie],
 | 
				
			||||||
 | 
					            path: str,
 | 
				
			||||||
 | 
					    ) -> None:
 | 
				
			||||||
 | 
					        self._database = sqlite3.connect(path)
 | 
				
			||||||
 | 
					        super().__init__(movie_factory)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def find_all(self) -> List[Movie]:
 | 
				
			||||||
 | 
					        with self._database as db:
 | 
				
			||||||
 | 
					            rows = db.execute('SELECT name, year, director FROM movies')
 | 
				
			||||||
 | 
					            return [self._movie_factory(*row) for row in rows]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +0,0 @@
 | 
				
			||||||
"""Fixtures module."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
MOVIES_SAMPLE_DATA = [
 | 
					 | 
				
			||||||
    ('The Hunger Games: Mockingjay - Part 2', 2015, 'Francis Lawrence'),
 | 
					 | 
				
			||||||
    ('The 33', 2015, 'Patricia Riggen'),
 | 
					 | 
				
			||||||
    ('Star Wars: Episode VII - The Force Awakens', 2015, 'JJ Abrams'),
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,55 +0,0 @@
 | 
				
			||||||
"""Movie storages module."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import csv
 | 
					 | 
				
			||||||
import sqlite3
 | 
					 | 
				
			||||||
from typing import List, Tuple, Any
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Row = Tuple[Any]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class MovieStorage:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def load_all(self, movie_data: List[Row]):
 | 
					 | 
				
			||||||
        raise NotImplementedError()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_all(self) -> List[Row]:
 | 
					 | 
				
			||||||
        raise NotImplementedError()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CsvMovieStorage(MovieStorage):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, options) -> None:
 | 
					 | 
				
			||||||
        self._csv_file_path = options.pop('path')
 | 
					 | 
				
			||||||
        self._delimiter = options.pop('delimiter')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def load_all(self, movie_data: List[Row]) -> None:
 | 
					 | 
				
			||||||
        with open(self._csv_file_path, 'w') as csv_file:
 | 
					 | 
				
			||||||
            csv.writer(csv_file, delimiter=self._delimiter).writerows(movie_data)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_all(self) -> List[Row]:
 | 
					 | 
				
			||||||
        with open(self._csv_file_path) as csv_file:
 | 
					 | 
				
			||||||
            csv_reader = csv.reader(csv_file, delimiter=self._delimiter)
 | 
					 | 
				
			||||||
            return [row for row in csv_reader]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SqliteMovieStorage(MovieStorage):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, options) -> None:
 | 
					 | 
				
			||||||
        self._database = sqlite3.connect(database=options.pop('path'))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def load_all(self, movie_data: List[Row]) -> None:
 | 
					 | 
				
			||||||
        with self._database as db:
 | 
					 | 
				
			||||||
            db.execute(
 | 
					 | 
				
			||||||
                'CREATE TABLE IF NOT EXISTS movies '
 | 
					 | 
				
			||||||
                '(name text, year int, director text)',
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            db.execute('DELETE FROM movies')
 | 
					 | 
				
			||||||
            db.executemany('INSERT INTO movies VALUES (?,?,?)', movie_data)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_all(self) -> List[Row]:
 | 
					 | 
				
			||||||
        with self._database as db:
 | 
					 | 
				
			||||||
            rows = db.execute(
 | 
					 | 
				
			||||||
                'SELECT name, year, director '
 | 
					 | 
				
			||||||
                'FROM movies',
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            return [row for row in rows]
 | 
					 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,7 @@ from .containers import ApplicationContainer
 | 
				
			||||||
def container():
 | 
					def container():
 | 
				
			||||||
    container = ApplicationContainer()
 | 
					    container = ApplicationContainer()
 | 
				
			||||||
    container.config.from_dict({
 | 
					    container.config.from_dict({
 | 
				
			||||||
        'storage': {
 | 
					        'finder': {
 | 
				
			||||||
            'type': 'csv',
 | 
					            'type': 'csv',
 | 
				
			||||||
            'csv': {
 | 
					            'csv': {
 | 
				
			||||||
                'path': '/fake-movies.csv',
 | 
					                'path': '/fake-movies.csv',
 | 
				
			||||||
| 
						 | 
					@ -26,13 +26,13 @@ def container():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_movies_directed_by(container):
 | 
					def test_movies_directed_by(container):
 | 
				
			||||||
    storage_mock = mock.Mock()
 | 
					    finder_mock = mock.Mock()
 | 
				
			||||||
    storage_mock.get_all.return_value = [
 | 
					    finder_mock.find_all.return_value = [
 | 
				
			||||||
        ('The 33', 2015, 'Patricia Riggen'),
 | 
					        container.movie('The 33', 2015, 'Patricia Riggen'),
 | 
				
			||||||
        ('The Jungle Book', 2016, 'Jon Favreau'),
 | 
					        container.movie('The Jungle Book', 2016, 'Jon Favreau'),
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    with container.storage.override(storage_mock):
 | 
					    with container.finder.override(finder_mock):
 | 
				
			||||||
        lister = container.lister()
 | 
					        lister = container.lister()
 | 
				
			||||||
        movies = lister.movies_directed_by('Jon Favreau')
 | 
					        movies = lister.movies_directed_by('Jon Favreau')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,13 +41,13 @@ def test_movies_directed_by(container):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_movies_released_in(container):
 | 
					def test_movies_released_in(container):
 | 
				
			||||||
    storage_mock = mock.Mock()
 | 
					    finder_mock = mock.Mock()
 | 
				
			||||||
    storage_mock.get_all.return_value = [
 | 
					    finder_mock.find_all.return_value = [
 | 
				
			||||||
        ('The 33', 2015, 'Patricia Riggen'),
 | 
					        container.movie('The 33', 2015, 'Patricia Riggen'),
 | 
				
			||||||
        ('The Jungle Book', 2016, 'Jon Favreau'),
 | 
					        container.movie('The Jungle Book', 2016, 'Jon Favreau'),
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    with container.storage.override(storage_mock):
 | 
					    with container.finder.override(finder_mock):
 | 
				
			||||||
        lister = container.lister()
 | 
					        lister = container.lister()
 | 
				
			||||||
        movies = lister.movies_released_in(2015)
 | 
					        movies = lister.movies_released_in(2015)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user