# Path: cinje/inline/use.py
# class Use(object):
# 	"""Consume the result of calling another template function, extending the local buffer.
# 	
# 	This is meant to consume non-wrapping template functions.  For wrapping functions see ": using" instead.
# 	
# 	Syntax:
# 	
# 		: use <name-constant> [<arguments>]
# 	
# 	The name constant must resolve to a generator function that participates in the cinje "yielded buffer" protocol.
# 	
# 	"""
# 	
# 	priority = 25
# 	
# 	def match(self, context, line):
# 		"""Match code lines prefixed with a "use" keyword."""
# 		return line.kind == 'code' and line.partitioned[0] == "use"
# 	
# 	def __call__(self, context):
# 		"""Wrap the expression in a `_buffer.extend()` call."""
# 		
# 		input = context.input
# 		
# 		try:
# 			declaration = input.next()
# 		except StopIteration:
# 			return
# 		
# 		parts = declaration.partitioned[1]  # Ignore the "use" part, we care about the name and arguments.
# 		name, _, args = parts.partition(' ')
# 		
# 		for i in ensure_buffer(context):
# 			yield i
# 		
# 		name = name.rstrip()
# 		args = args.lstrip()
# 		
# 		if 'buffer' in context.flag:
# 			yield declaration.clone(line=PREFIX + name + "(" + args + "))")
# 			context.flag.add('dirty')
# 			return
# 		
# 		if py == 3:  # We can use the more efficient "yield from" syntax. Wewt!
# 			yield declaration.clone(line="yield from " + name + "(" + args + ")")
# 		else:
# 			yield declaration.clone(line="for _chunk in " + name + "(" + args + "):")
# 			yield declaration.clone(line="yield _chunk", scope=context.scope + 1)
# 
# Path: cinje/util.py
# def flatten(input, file=None, encoding=None, errors='strict'):
# 	"""Return a flattened representation of a cinje chunk stream.
# 	
# 	This has several modes of operation.  If no `file` argument is given, output will be returned as a string.
# 	The type of string will be determined by the presence of an `encoding`; if one is given the returned value is a
# 	binary string, otherwise the native unicode representation.  If a `file` is present, chunks will be written
# 	iteratively through repeated calls to `file.write()`, and the amount of data (characters or bytes) written
# 	returned.  The type of string written will be determined by `encoding`, just as the return value is when not
# 	writing to a file-like object.  The `errors` argument is passed through when encoding.
# 	
# 	We can highly recommend using the various stremaing IO containers available in the
# 	[`io`](https://docs.python.org/3/library/io.html) module, though
# 	[`tempfile`](https://docs.python.org/3/library/tempfile.html) classes are also quite useful.
# 	"""
# 	
# 	input = stream(input, encoding, errors)
# 	
# 	if file is None:  # Exit early if we're not writing to a file.
# 		return b''.join(input) if encoding else ''.join(input)
# 	
# 	counter = 0
# 	
# 	for chunk in input:
# 		file.write(chunk)
# 		counter += len(chunk)
# 	
# 	return counter
# 
# def fragment(string, name="anonymous", **context):
# 	"""Translate a template fragment into a callable function.
# 	
# 	**Note:** Use of this function is discouraged everywhere except tests, as no caching is implemented at this time.
# 	
# 	Only one function may be declared, either manually, or automatically. If automatic defintition is chosen the
# 	resulting function takes no arguments.  Additional keyword arguments are passed through as global variables.
# 	"""
# 	
# 	if isinstance(string, bytes):
# 		string = string.decode('utf-8')
# 	
# 	if ": def" in string or ":def" in string:
# 		code = string.encode('utf8').decode('cinje')
# 		name = None
# 	else:
# 		code = ": def {name}\n\n{string}".format(
# 				name = name,
# 				string = string,
# 			).encode('utf8').decode('cinje')
# 	
# 	environ = dict(context)
# 	
# 	exec(code, environ)
# 	
# 	if name is None:  # We need to dig it out of the `__tmpl__` list.
# 		if __debug__ and not environ.get('__tmpl__', None):
# 			raise RuntimeError("Template fragment does not contain a function: " + repr(environ.get('__tmpl__', None)) + \
# 					"\n\n" + code)
# 		
# 		return environ[environ['__tmpl__'][-1]]  # Super secret sauce: you _can_ define more than one function...
# 	
# 	return environ[name]


import pytest
import json
import os.path
from cinje.inline.use import Use
from cinje.util import flatten, fragment
# encoding: utf-8




def producer(*args, **kw):
	return [", ".join(str(i) for i in args) + "\n" + json.dumps(kw, sort_keys=True)]


@pytest.fixture
def tmpl():
	return fragment(': def consumer arg, *args, **kw\n\t: use arg *args, **kw')


class TestInlineUse(object):
	def test_simple(self, tmpl):

# Path: cinje/inline/use.py
# class Use(object):
# 	"""Consume the result of calling another template function, extending the local buffer.
# 	
# 	This is meant to consume non-wrapping template functions.  For wrapping functions see ": using" instead.
# 	
# 	Syntax:
# 	
# 		: use <name-constant> [<arguments>]
# 	
# 	The name constant must resolve to a generator function that participates in the cinje "yielded buffer" protocol.
# 	
# 	"""
# 	
# 	priority = 25
# 	
# 	def match(self, context, line):
# 		"""Match code lines prefixed with a "use" keyword."""
# 		return line.kind == 'code' and line.partitioned[0] == "use"
# 	
# 	def __call__(self, context):
# 		"""Wrap the expression in a `_buffer.extend()` call."""
# 		
# 		input = context.input
# 		
# 		try:
# 			declaration = input.next()
# 		except StopIteration:
# 			return
# 		
# 		parts = declaration.partitioned[1]  # Ignore the "use" part, we care about the name and arguments.
# 		name, _, args = parts.partition(' ')
# 		
# 		for i in ensure_buffer(context):
# 			yield i
# 		
# 		name = name.rstrip()
# 		args = args.lstrip()
# 		
# 		if 'buffer' in context.flag:
# 			yield declaration.clone(line=PREFIX + name + "(" + args + "))")
# 			context.flag.add('dirty')
# 			return
# 		
# 		if py == 3:  # We can use the more efficient "yield from" syntax. Wewt!
# 			yield declaration.clone(line="yield from " + name + "(" + args + ")")
# 		else:
# 			yield declaration.clone(line="for _chunk in " + name + "(" + args + "):")
# 			yield declaration.clone(line="yield _chunk", scope=context.scope + 1)
# 
# Path: cinje/util.py
# def flatten(input, file=None, encoding=None, errors='strict'):
# 	"""Return a flattened representation of a cinje chunk stream.
# 	
# 	This has several modes of operation.  If no `file` argument is given, output will be returned as a string.
# 	The type of string will be determined by the presence of an `encoding`; if one is given the returned value is a
# 	binary string, otherwise the native unicode representation.  If a `file` is present, chunks will be written
# 	iteratively through repeated calls to `file.write()`, and the amount of data (characters or bytes) written
# 	returned.  The type of string written will be determined by `encoding`, just as the return value is when not
# 	writing to a file-like object.  The `errors` argument is passed through when encoding.
# 	
# 	We can highly recommend using the various stremaing IO containers available in the
# 	[`io`](https://docs.python.org/3/library/io.html) module, though
# 	[`tempfile`](https://docs.python.org/3/library/tempfile.html) classes are also quite useful.
# 	"""
# 	
# 	input = stream(input, encoding, errors)
# 	
# 	if file is None:  # Exit early if we're not writing to a file.
# 		return b''.join(input) if encoding else ''.join(input)
# 	
# 	counter = 0
# 	
# 	for chunk in input:
# 		file.write(chunk)
# 		counter += len(chunk)
# 	
# 	return counter
# 
# def fragment(string, name="anonymous", **context):
# 	"""Translate a template fragment into a callable function.
# 	
# 	**Note:** Use of this function is discouraged everywhere except tests, as no caching is implemented at this time.
# 	
# 	Only one function may be declared, either manually, or automatically. If automatic defintition is chosen the
# 	resulting function takes no arguments.  Additional keyword arguments are passed through as global variables.
# 	"""
# 	
# 	if isinstance(string, bytes):
# 		string = string.decode('utf-8')
# 	
# 	if ": def" in string or ":def" in string:
# 		code = string.encode('utf8').decode('cinje')
# 		name = None
# 	else:
# 		code = ": def {name}\n\n{string}".format(
# 				name = name,
# 				string = string,
# 			).encode('utf8').decode('cinje')
# 	
# 	environ = dict(context)
# 	
# 	exec(code, environ)
# 	
# 	if name is None:  # We need to dig it out of the `__tmpl__` list.
# 		if __debug__ and not environ.get('__tmpl__', None):
# 			raise RuntimeError("Template fragment does not contain a function: " + repr(environ.get('__tmpl__', None)) + \
# 					"\n\n" + code)
# 		
# 		return environ[environ['__tmpl__'][-1]]  # Super secret sauce: you _can_ define more than one function...
# 	
# 	return environ[name]


# Path: test/test_inline/test_use.py
import pytest
import json
import os.path
from cinje.inline.use import Use
from cinje.util import flatten, fragment

# encoding: utf-8




def producer(*args, **kw):
	return [", ".join(str(i) for i in args) + "\n" + json.dumps(kw, sort_keys=True)]


@pytest.fixture
def tmpl():
	return fragment(': def consumer arg, *args, **kw\n\t: use arg *args, **kw')


class TestInlineUse(object):
	def test_simple(self, tmpl):

		assert flatten(tmpl(producer)) == '\n{}'