from types import ListType
from Foo import Foo
from Bar import Bar


def NoException(codeString):
	raise Exception, 'Failed to raise exception for: ' + codeString


def reset(store):
	store.clear()
	store.executeSQLTransaction(['delete from Foo;', 'delete from Bar;'])


def testAddToBars(store):
	# Test 1: Use addToBars()
	f = Foo()
	store.addObject(f)

	b = Bar()
	f.addToBars(b)
	b.dumpAttrs()
	store.saveChanges()

	store.clear()
	f = store.fetchObjectsOfClass(Foo)[0]
	bars = f.bars()
	assert len(bars) == 1, 'bars=%r' % bars
	assert bars[0].foo() == f
	reset(store)


def test(store):
	# We invoke testAddToBars twice on purpose, just to see that
	# the second time around, things are stable enough to pass again
	testAddToBars(store)
	testAddToBars(store)

	# Test 2: do not use addToBars()
	f = Foo()
	store.addObject(f)
	b = Bar()
	b.setFoo(f)
	b.setX(7)
	store.addObject(b)
	store.saveChanges()
	store.clear()

	f = store.fetchObjectsOfClass(Foo)[0]
	assert f._mk_store
	assert f._mk_inStore
	bars = f.bars()
	assert type(bars) is ListType
	assert len(bars) == 1, 'bars=%r' % bars
	assert bars[0].x() == 7

	# Test addToXYZ() method
	bar = Bar()
	bar.setX(42)
	f.addToBars(bar)
	assert bar.foo() == f
	store.saveChanges()
	store.clear()

	f = store.fetchObjectsOfClass(Foo)[0]
	bars = f.bars()
	assert type(bars) is ListType
	assert len(bars) == 2, 'bars=%r' % bars
	assert bars[0].x() == 7
	assert bars[1].x() == 42

	# Test the assertion checking in addToXYZ()
	try:
		f.addToBars(None)
	except Exception:
		pass
	else:
		NoException('f.addToBars(None) # None not allowed')

	try:
		f.addToBars(5)
	except Exception:
		pass
	else:
		NoException('f.addToBars(5) # not an object')

	try:
		f.addToBars(f)
	except Exception:
		pass
	else:
		NoException('f.addToBars(f) # wrong class')

	try:
		f.addToBars(bar)
	except Exception:
		pass
	else:
		NoException('f.addToBars(bar) # already added')

	# Test delFromXYZ() method
	bar = bars[1]
	f.delFromBars(bar)
	assert len(bars) == 1
	assert bar.foo() is None
	store.saveChanges()
	store.clear()

	f = store.fetchObjectsOfClass(Foo)[0]
	bars = f.bars()
	assert type(bars) is ListType
	assert len(bars) == 1, 'bars=%r' % bars
	assert bars[0].x() == 7

	# Test the assertion checking in delFromXYZ()
	try:
		f.delFromBars(None)
	except Exception:
		pass
	else:
		NoException('f.delFromBars(None) # None not allowed')

	try:
		f.delFromBars(5)
	except Exception:
		pass
	else:
		NoException('f.delFromBars(5) # not an object')

	try:
		f.delFromBars(f)
	except Exception:
		pass
	else:
		NoException('f.delFromBars(f) # wrong class')

	try:
		f.delFromBars(bar)
	except Exception:
		pass
	else:
		NoException('f.delFromBars(bar) # already deleted')
