1- # Copyright 2015-2016 Facundo Batista, Nicolás Demarchi
1+ # Copyright 2015-2017 Facundo Batista, Nicolás Demarchi
22#
33# This program is free software: you can redistribute it and/or modify it
44# under the terms of the GNU General Public License version 3, as published
2525from threading import Thread
2626from unittest .mock import patch
2727
28- from pkg_resources import parse_requirements
28+ from pkg_resources import parse_requirements , Distribution
2929
3030from fades import cache , helpers , parsing
3131
@@ -35,6 +35,11 @@ def get_req(text):
3535 return list (parse_requirements (text ))
3636
3737
38+ def get_distrib (* dep_ver_pairs ):
39+ """Build some Distributions with indicated info."""
40+ return [Distribution (project_name = dep , version = ver ) for dep , ver in dep_ver_pairs ]
41+
42+
3843class TempfileTestCase (unittest .TestCase ):
3944 """Basic functionality tests."""
4045
@@ -359,6 +364,32 @@ def test_middle_match(self):
359364 'interpreter' : 'pythonX.Y' ,
360365 'options' : {'foo' : 'bar' }
361366 })
367+ venv3 = json .dumps ({
368+ 'metadata' : 'venv3' ,
369+ 'installed' : {'pypi' : {'dep' : '7' }},
370+ 'interpreter' : 'pythonX.Y' ,
371+ 'options' : {'foo' : 'bar' }
372+ })
373+ resp = self .venvscache ._select ([venv1 , venv2 , venv3 ], reqs , interpreter , uuid = '' ,
374+ options = options )
375+ self .assertEqual (resp , 'venv2' )
376+
377+ def test_multiple_match_bigger_version (self ):
378+ reqs = {'pypi' : get_req ('dep' )}
379+ interpreter = 'pythonX.Y'
380+ options = {'foo' : 'bar' }
381+ venv1 = json .dumps ({
382+ 'metadata' : 'venv1' ,
383+ 'installed' : {'pypi' : {'dep' : '3' }},
384+ 'interpreter' : 'pythonX.Y' ,
385+ 'options' : {'foo' : 'bar' }
386+ })
387+ venv2 = json .dumps ({
388+ 'metadata' : 'venv2' ,
389+ 'installed' : {'pypi' : {'dep' : '7' }},
390+ 'interpreter' : 'pythonX.Y' ,
391+ 'options' : {'foo' : 'bar' }
392+ })
362393 venv3 = json .dumps ({
363394 'metadata' : 'venv3' ,
364395 'installed' : {'pypi' : {'dep' : '5' }},
@@ -367,6 +398,8 @@ def test_middle_match(self):
367398 })
368399 resp = self .venvscache ._select ([venv1 , venv2 , venv3 ], reqs , interpreter , uuid = '' ,
369400 options = options )
401+ # matches venv2 because it has the bigger version for 'dep' (even if it's not the
402+ # latest virtualenv created)
370403 self .assertEqual (resp , 'venv2' )
371404
372405 def test_multiple_deps_ok (self ):
@@ -582,3 +615,88 @@ def test_crazy_picky(self):
582615 self .assertEqual (self .check ('>1.6,<1.9,!=1.9.6' , '1.6.7' ), 'ok' )
583616 self .assertEqual (self .check ('>1.6,<1.9,!=1.8.6' , '1.8.7' ), 'ok' )
584617 self .assertEqual (self .check ('>1.6,<1.9,!=1.9.6' , '1.9.6' ), None )
618+
619+
620+ class BestFitTestCase (TempfileTestCase ):
621+ """Check the venv best fitting decissor."""
622+
623+ def setUp (self ):
624+ super ().setUp ()
625+ self .venvscache = cache .VEnvsCache (self .tempfile )
626+
627+ def check (self , possible_venvs ):
628+ """Assert that the selected venv is the best fit one."""
629+ self .assertEqual (self .venvscache ._select_better_fit (possible_venvs ), 'venv_best_fit' )
630+
631+ def test_one_simple (self ):
632+ self .check ([
633+ (get_distrib (('dep' , '3' )), 'venv_best_fit' ),
634+ ])
635+
636+ def test_one_double (self ):
637+ self .check ([
638+ (get_distrib (('dep1' , '3' ), ('dep2' , '3' )), 'venv_best_fit' ),
639+ ])
640+
641+ def test_two_simple (self ):
642+ self .check ([
643+ (get_distrib (('dep' , '5' )), 'venv_best_fit' ),
644+ (get_distrib (('dep' , '3' )), 'venv_1' ),
645+ ])
646+
647+ def test_two_double_evident (self ):
648+ self .check ([
649+ (get_distrib (('dep1' , '5' ), ('dep2' , '7' )), 'venv_best_fit' ),
650+ (get_distrib (('dep1' , '3' ), ('dep2' , '6' )), 'venv_1' ),
651+ ])
652+
653+ def test_two_double_mixed_1 (self ):
654+ # tie! the one chosen is the last one
655+ self .check ([
656+ (get_distrib (('dep1' , '3' ), ('dep2' , '9' )), 'venv_1' ),
657+ (get_distrib (('dep1' , '5' ), ('dep2' , '7' )), 'venv_best_fit' ),
658+ ])
659+
660+ def test_two_double_mixed_2 (self ):
661+ # tie! the one chosen is the last one
662+ self .check ([
663+ (get_distrib (('dep1' , '5' ), ('dep2' , '7' )), 'venv_1' ),
664+ (get_distrib (('dep1' , '3' ), ('dep2' , '9' )), 'venv_best_fit' ),
665+ ])
666+
667+ def test_two_triple (self ):
668+ self .check ([
669+ (get_distrib (('dep1' , '3' ), ('dep2' , '9' ), ('dep3' , '4' )), 'venv_best_fit' ),
670+ (get_distrib (('dep1' , '5' ), ('dep2' , '7' ), ('dep3' , '2' )), 'venv_1' ),
671+ ])
672+
673+ def test_unordered (self ):
674+ # assert it compares each dependency with its equivalent
675+ self .check ([
676+ (get_distrib (('dep2' , '3' ), ('dep1' , '2' ), ('dep3' , '8' )), 'venv_best_fit' ),
677+ (get_distrib (('dep1' , '7' ), ('dep3' , '5' ), ('dep2' , '2' )), 'venv_1' ),
678+ ])
679+
680+ def test_big (self ):
681+ self .check ([
682+ (get_distrib (('dep1' , '3' ), ('dep2' , '2' )), 'venv_1' ),
683+ (get_distrib (('dep1' , '4' ), ('dep2' , '2' )), 'venv_2' ),
684+ (get_distrib (('dep1' , '5' ), ('dep2' , '7' )), 'venv_best_fit' ),
685+ (get_distrib (('dep1' , '5' ), ('dep2' , '6' )), 'venv_3' ),
686+ ])
687+
688+ def test_vcs_alone (self ):
689+ self .check ([
690+ ([parsing .VCSDependency ('someurl' )], 'venv_best_fit' ),
691+ ])
692+
693+ def test_vcs_mixed_simple (self ):
694+ self .check ([
695+ ([parsing .VCSDependency ('someurl' )] + get_distrib (('dep' , '3' )), 'venv_best_fit' ),
696+ ])
697+
698+ def test_vcs_mixed_multiple (self ):
699+ self .check ([
700+ ([parsing .VCSDependency ('someurl' )] + get_distrib (('dep' , '3' )), 'venv_best_fit' ),
701+ ([parsing .VCSDependency ('someurl' )] + get_distrib (('dep' , '1' )), 'venv_1' ),
702+ ])
0 commit comments