75 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			75 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Python
		
	
	
	
class MonkeypatchPlugin:
 | 
						|
    """ setattr-monkeypatching with automatical reversal after test. """
 | 
						|
    def pytest_pyfuncarg_monkeypatch(self, pyfuncitem):
 | 
						|
        monkeypatch = MonkeyPatch()
 | 
						|
        pyfuncitem.addfinalizer(monkeypatch.finalize)
 | 
						|
        return monkeypatch
 | 
						|
 | 
						|
notset = object()
 | 
						|
 | 
						|
class MonkeyPatch:
 | 
						|
    def __init__(self):
 | 
						|
        self._setattr = []
 | 
						|
        self._setitem = []
 | 
						|
 | 
						|
    def setattr(self, obj, name, value):
 | 
						|
        self._setattr.insert(0, (obj, name, getattr(obj, name, notset)))
 | 
						|
        setattr(obj, name, value)
 | 
						|
 | 
						|
    def setitem(self, dictionary, name, value):
 | 
						|
        self._setitem.insert(0, (dictionary, name, dictionary.get(name, notset)))
 | 
						|
        dictionary[name] = value
 | 
						|
 | 
						|
    def finalize(self):
 | 
						|
        for obj, name, value in self._setattr:
 | 
						|
            if value is not notset:
 | 
						|
                setattr(obj, name, value)
 | 
						|
            else:
 | 
						|
                delattr(obj, name)
 | 
						|
        for dictionary, name, value in self._setitem:
 | 
						|
            if value is notset:
 | 
						|
                del dictionary[name]
 | 
						|
            else:
 | 
						|
                dictionary[name] = value
 | 
						|
 | 
						|
 | 
						|
def test_setattr():
 | 
						|
    class A:
 | 
						|
        x = 1
 | 
						|
    monkeypatch = MonkeyPatch()
 | 
						|
    monkeypatch.setattr(A, 'x', 2)
 | 
						|
    assert A.x == 2
 | 
						|
    monkeypatch.setattr(A, 'x', 3)
 | 
						|
    assert A.x == 3
 | 
						|
    monkeypatch.finalize()
 | 
						|
    assert A.x == 1
 | 
						|
 | 
						|
    monkeypatch.setattr(A, 'y', 3)
 | 
						|
    assert A.y == 3
 | 
						|
    monkeypatch.finalize()
 | 
						|
    assert not hasattr(A, 'y')
 | 
						|
     
 | 
						|
 | 
						|
def test_setitem():
 | 
						|
    d = {'x': 1}
 | 
						|
    monkeypatch = MonkeyPatch()
 | 
						|
    monkeypatch.setitem(d, 'x', 2)
 | 
						|
    monkeypatch.setitem(d, 'y', 1700)
 | 
						|
    assert d['x'] == 2
 | 
						|
    assert d['y'] == 1700
 | 
						|
    monkeypatch.setitem(d, 'x', 3)
 | 
						|
    assert d['x'] == 3
 | 
						|
    monkeypatch.finalize()
 | 
						|
    assert d['x'] == 1
 | 
						|
    assert 'y' not in d
 | 
						|
 | 
						|
def test_monkeypatch_plugin(testdir):
 | 
						|
    sorter = testdir.inline_runsource("""
 | 
						|
        pytest_plugins = 'pytest_monkeypatch', 
 | 
						|
        def test_method(monkeypatch):
 | 
						|
            assert monkeypatch.__class__.__name__ == "MonkeyPatch"
 | 
						|
    """)
 | 
						|
    res = sorter.countoutcomes()
 | 
						|
    assert tuple(res) == (1, 0, 0), res
 | 
						|
        
 |