from org.transcrypt.stubs.browser import __pragma__

def run (autoTester):
	def repeat3 (bareFunc):
		__pragma__ ('kwargs')
		def innerFunc (*args, **kwargs):
			autoTester.check ('BEGIN repeat3')
			for i in range (3):
				bareFunc (*args, **kwargs)
			autoTester.check ('END repeat3')
		__pragma__ ('nokwargs')
		return innerFunc
		
	def repeatN (n):
		def repeat (bareFunc):
			__pragma__ ('kwargs')
			def innerFunc (*args, **kwargs):
				autoTester.check ('BEGIN repeatN ({})'.format (n))
				for i in range (n):
					bareFunc (*args, **kwargs)
				autoTester.check ('END repeatN ({})'.format (n))
			__pragma__ ('nokwargs')
			return innerFunc
		return repeat

	class Repeater:
		def __init__ (self, n):
			self.n = n
			
		def __call__ (self, bareFunc):
			__pragma__ ('kwargs')
			def innerFunc (*args, **kwargs):
				autoTester.check ('BEGIN repeat3')
				for i in range (self.n):
					bareFunc (*args, **kwargs)
				autoTester.check ('END repeat3')
			__pragma__ ('nokwargs')
			return innerFunc
		
	@repeatN (4)
	@repeat3
	def funcNoArg ():
		autoTester.check ('spam')
		
	funcNoArg ()
	autoTester.check ()

	__pragma__ ('kwargs')
	@repeat3
	@repeatN (2)
	def funcArg (a):
		autoTester.check ('eggs', a)
	__pragma__ ('nokwargs')
		
	funcArg (3)
	autoTester.check ()

	funcArg (a = 4)
	autoTester.check ()

	__pragma__ ('opov')
	@Repeater (3)
	def funcNoArg2 ():
		autoTester.check ('toast')
	__pragma__ ('noopov')

	funcNoArg2 ()
	autoTester.check ()

	__pragma__ ('opov')
	__pragma__ ('kwargs')
	@Repeater (5)
	def funcArg2 (a):
		autoTester.check ('jam', a)
	__pragma__ ('nokwargs')
	__pragma__ ('noopov')

	funcArg2 (3)
	autoTester.check ()

	funcArg2 (a = 4)
	autoTester.check ()

	def next (bareFunc):
		def innerFunc (value):
			return bareFunc (value + 1)
		return innerFunc
		
	@next
	class Number:
		def __init__ (self, value):
			self.value = value
			
	autoTester.check ('two', Number (1) .value)
	
	class Test:	
		@classmethod
		def f (cls, x, y):
			autoTester.check (cls.__name__, x, y)
			
		def g (self, x, y):
			autoTester.check (self.__class__.__name__, x, y)
			
	test = Test ()

	test.f (1, 2)
	test.g (3, 4)
	
	