Repository: mozilla/nunjucks (js)

Issue:
Set blocks prints its content
In 3.0.0 set block for some reason immediately prints it content.

``` jinja2
{% set test %}
TEST
{% endset %}

result: {{ test }}
```

outputs

``` html
TEST

result:
```

As you can see, set print itself immediately, and `{{ test }}` call doesn't work.

Should it be like that?

Pull request:
Addresses 914; capture blocks in macros now write to temporary output buffer
## Summary

Proposed change: Fixes a bug that led the capture block compiler to write to the main buffer instead of the temporary one. Previously, the following code would (incorrectly) write "foobar".

```jinja
{%- macro foo(bar) -%}
  {%- set test -%}
    foo
  {%- endset -%}
  {{ bar }}{{ test }}
{%- endmacro -%}
{{ foo("bar") }}
```

Now it writes "barfoo."

Closes #914.

## Checklist

~I've completed the checklist below to ensure I didn't forget anything.~
( I accidentally hit enter before finishing the checklist.)

* [x] Proposed change helps towards [*purpose of this project*](https://github.com/mozilla/nunjucks/blob/master/CONTRIBUTING.md#purpose).
* [ ] [*Documentation*](https://github.com/mozilla/nunjucks/tree/master/docs/) is added / updated to describe proposed change.
* [x] [*Tests*](https://github.com/mozilla/nunjucks/tree/master/tests) are added / updated to cover proposed change.
* [ ] [*Changelog*](https://github.com/mozilla/nunjucks/blob/master/CHANGELOG.md) has an entry for proposed change (if user-facing fix or feature).

<!-- Tick of items by replacing `[ ]` by `[x]` -->

Patch:
diff --git a/src/compiler.js b/src/compiler.js
index d94cd0a..09e7aa2 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -1059,6 +1059,10 @@ var Compiler = Object.extend({
     },
 
     compileCapture: function(node, frame) {
+        // we need to temporarily override the current buffer id as 'output'
+        // so the set block writes to the capture output instead of the buffer
+        var buffer = this.buffer;
+        this.buffer = 'output';
         this.emitLine('(function() {');
         this.emitLine('var output = "";');
         this.withScopedSyntax(function () {
@@ -1066,6 +1070,8 @@ var Compiler = Object.extend({
         });
         this.emitLine('return output;');
         this.emitLine('})()');
+        // and of course, revert back to the old buffer id
+        this.buffer = buffer;
     },
 
     compileOutput: function(node, frame) {


Test patch:
diff --git a/tests/compiler.js b/tests/compiler.js
index ffa33bc..0c3913a 100644
--- a/tests/compiler.js
+++ b/tests/compiler.js
@@ -1153,6 +1153,18 @@
                   ''
                   );
 
+            /**
+             * Capture blocks inside macros were printing to the main buffer instead of
+             * the temporary one, see https://github.com/mozilla/nunjucks/issues/914.
+             **/
+            equal('{%- macro foo(bar) -%}'+
+                  '{%- set test -%}foo{%- endset -%}'+
+                  '{{ bar }}{{ test }}'+
+                  '{%- endmacro -%}'+
+                  '{{ foo("bar") }}',
+                  'barfoo'
+                  );
+
             equal('{% set block_content %}test string{% endset %}'+
                   '{{ block_content }}',
                   'test string'