Index: core/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-script/src/test/java/org/xwiki/rendering/macro/script/NestedScriptMacroValidatorTest.java
===================================================================
--- core/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-script/src/test/java/org/xwiki/rendering/macro/script/NestedScriptMacroValidatorTest.java	(revision 0)
+++ core/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-script/src/test/java/org/xwiki/rendering/macro/script/NestedScriptMacroValidatorTest.java	(revision 0)
@@ -0,0 +1,144 @@
+/*
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.xwiki.rendering.macro.script;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.jmock.Expectations;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.xwiki.rendering.block.Block;
+import org.xwiki.rendering.block.MacroBlock;
+import org.xwiki.rendering.block.MacroMarkerBlock;
+import org.xwiki.rendering.block.XDOM;
+import org.xwiki.rendering.internal.macro.script.DefaultScriptMacro;
+import org.xwiki.rendering.internal.macro.script.NestedScriptMacroValidator;
+import org.xwiki.rendering.internal.macro.script.ScriptMacroValidator;
+import org.xwiki.rendering.macro.MacroExecutionException;
+import org.xwiki.rendering.macro.MacroId;
+import org.xwiki.rendering.macro.MacroManager;
+import org.xwiki.rendering.transformation.MacroTransformationContext;
+import org.xwiki.test.AbstractMockingComponentTest;
+import org.xwiki.test.annotation.ComponentTest;
+
+
+/**
+ * Tests nested script macro validator.
+ * 
+ * @version $Id$
+ * @since 2.4M2
+ */
+@ComponentTest(value = NestedScriptMacroValidator.class)
+public class NestedScriptMacroValidatorTest extends AbstractMockingComponentTest
+{
+    /** Nested script validator to test. */
+    private ScriptMacroValidator<?> validator;
+
+    /**
+     * @see org.xwiki.test.AbstractMockingComponentTest#setUp()
+     */
+    @Before
+    @Override
+    public void setUp() throws Exception
+    {
+        super.setUp();
+
+        // fake macro manager returns a script macro for "script" and null else
+        final MacroManager macroManager = getComponentManager().lookup(MacroManager.class);
+        final ScriptMacro scriptMacro = new DefaultScriptMacro();
+        getMockery().checking(new Expectations() {{
+            allowing(macroManager).getMacro(with(new MacroId("script")));
+                will(returnValue(scriptMacro));
+            allowing(macroManager).getMacro(with(any(MacroId.class)));
+                will(returnValue(null));
+        }});
+
+        this.validator = getComponentManager().lookup(ScriptMacroValidator.class, "nested");
+    }
+
+    @Test
+    public void testNoNestedScript()
+    {
+        MacroTransformationContext context = buildContext("script", "script");
+        try {
+            validator.validate(null, null, context);
+            Assert.fail("Nested scripts are allowed");
+        } catch (MacroExecutionException exception) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testNoNestedScriptInHtml()
+    {
+        MacroTransformationContext context = buildContext("script", "html", "script");
+        try {
+            validator.validate(null, null, context);
+            Assert.fail("Nested scripts are allowed inside HTML macro");
+        } catch (MacroExecutionException exception) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testIncludeInterceptsNestedChain()
+    {
+        MacroTransformationContext context = buildContext("script", "include", "script");
+        try {
+            validator.validate(null, null, context);
+        } catch (MacroExecutionException exception) {
+            Assert.fail("Nested scripts are forbidden inside include macro");
+        }
+    }
+
+    /**
+     * Build a chain of nested macros ({@link MacroMarkerBlock} blocks) and put them into a macro transformation
+     * context. The chain will be the only child of a top level XDOM, the last child will be the current
+     * {@link MacroBlock}.
+     * 
+     * @param chain list of nested macro names (starting with parent)
+     * @return an initialized macro transformation context
+     */
+    private MacroTransformationContext buildContext(String... chain)
+    {
+        MacroTransformationContext context = new MacroTransformationContext();
+        if (chain == null || chain.length < 1) {
+            context.setXDOM(new XDOM(new LinkedList<Block>()));
+            return context;
+        }
+
+        Map<String, String> parameters = new HashMap<String, String>();
+        MacroBlock child = new MacroBlock(chain[chain.length-1], parameters, false);
+        Block current = child;
+        for (int i = chain.length-2; i >= 0; i--) {
+            Block parent = new MacroMarkerBlock(chain[i], parameters, Collections.singletonList(current), false);
+            current = parent;
+        }
+        XDOM root = new XDOM(Collections.singletonList(current));
+        context.setXDOM(root);
+        context.setCurrentMacroBlock(child);
+        return context;
+    }
+}
+

Property changes on: core/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-script/src/test/java/org/xwiki/rendering/macro/script/NestedScriptMacroValidatorTest.java
___________________________________________________________________
Added: svn:keywords
   + Author Id Revision HeadURL
Added: svn:eol-style
   + native

Index: core/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-script/src/test/java/org/xwiki/rendering/macro/script/RenderingTests.java
===================================================================
--- core/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-script/src/test/java/org/xwiki/rendering/macro/script/RenderingTests.java	(revision 29501)
+++ core/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-script/src/test/java/org/xwiki/rendering/macro/script/RenderingTests.java	(working copy)
@@ -22,7 +22,11 @@
 import junit.framework.Test;
 import junit.framework.TestCase;
 
+import org.jmock.Expectations;
+import org.xwiki.component.descriptor.DefaultComponentDescriptor;
+import org.xwiki.rendering.internal.macro.script.ScriptMacroValidator;
 import org.xwiki.rendering.scaffolding.RenderingTestSuite;
+import org.xwiki.rendering.transformation.MacroTransformationContext;
 import org.xwiki.test.ComponentManagerTestSetup;
 
 /**
@@ -40,9 +44,24 @@
         suite.addTestsFromResource("macroscript1", true);
         suite.addTestsFromResource("macroscript2", true);
         suite.addTestsFromResource("macroscript3", true);
+        suite.addTestsFromResource("macroscript4", true);
+        suite.addTestsFromResource("macroscript5", true);
 
         ComponentManagerTestSetup testSetup = new ComponentManagerTestSetup(suite);
-        new ScriptMockSetup(testSetup.getComponentManager());
+        ScriptMockSetup setup = new ScriptMockSetup(testSetup.getComponentManager());
+
+        // fake nested script validator never fails
+        final ScriptMacroValidator<ScriptMacroParameters> nestedValidator
+            = setup.mockery.mock(ScriptMacroValidator.class, "nested");
+        setup.mockery.checking(new Expectations() {{
+            allowing(nestedValidator).validate(with(any(ScriptMacroParameters.class)), with(any(String.class)),
+                with(any(MacroTransformationContext.class)));
+        }});
+        DefaultComponentDescriptor<ScriptMacroValidator> validatorDescriptor
+            = new DefaultComponentDescriptor<ScriptMacroValidator>();
+        validatorDescriptor.setRole(ScriptMacroValidator.class);
+        validatorDescriptor.setRoleHint("nested");
+        testSetup.getComponentManager().registerComponent(validatorDescriptor, nestedValidator);
 
         return testSetup;
     }
Index: core/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-script/src/test/resources/macroscript3.test
===================================================================
--- core/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-script/src/test/resources/macroscript3.test	(revision 29501)
+++ core/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-script/src/test/resources/macroscript3.test	(working copy)
@@ -1,52 +1,27 @@
 .#-----------------------------------------------------
 .input|xwiki/2.0
-.# Validate wiki=false option
+.# Validate that inner macro is transformed also
 .#-----------------------------------------------------
 {{script}}
-**bold**
+{{script}}
+script here
 {{/script}}
-
-{{script wiki=false}}
-**not bold**
 {{/script}}
-
-{{script}}**bold**{{/script}}{{script wiki=false}}**not bold**{{/script}}
 .#-----------------------------------------------------
 .expect|event/1.0
 .#-----------------------------------------------------
 beginDocument
-beginMacroMarkerStandalone [script] [] [**bold**]
-beginParagraph
-beginFormat [BOLD]
-onWord [bold]
-endFormat [BOLD]
-endParagraph
-endMacroMarkerStandalone [script] [] [**bold**]
-beginMacroMarkerStandalone [script] [wiki=false] [**not bold**]
-beginParagraph
-onSpecialSymbol [*]
-onSpecialSymbol [*]
-onWord [not]
-onSpace
-onWord [bold]
-onSpecialSymbol [*]
-onSpecialSymbol [*]
-endParagraph
-endMacroMarkerStandalone [script] [wiki=false] [**not bold**]
+beginMacroMarkerStandalone [script] [] [{{script}}
+script here
+{{/script}}]
+beginMacroMarkerStandalone [script] [] [script here]
 beginParagraph
-beginMacroMarkerInline [script] [] [**bold**]
-beginFormat [BOLD]
-onWord [bold]
-endFormat [BOLD]
-endMacroMarkerInline [script] [] [**bold**]
-beginMacroMarkerInline [script] [wiki=false] [**not bold**]
-onSpecialSymbol [*]
-onSpecialSymbol [*]
-onWord [not]
+onWord [script]
 onSpace
-onWord [bold]
-onSpecialSymbol [*]
-onSpecialSymbol [*]
-endMacroMarkerInline [script] [wiki=false] [**not bold**]
+onWord [here]
 endParagraph
+endMacroMarkerStandalone [script] [] [script here]
+endMacroMarkerStandalone [script] [] [{{script}}
+script here
+{{/script}}]
 endDocument
\ No newline at end of file
Index: core/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-script/src/test/resources/macroscript4.test
===================================================================
--- core/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-script/src/test/resources/macroscript4.test	(revision 0)
+++ core/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-script/src/test/resources/macroscript4.test	(revision 0)
@@ -0,0 +1,52 @@
+.#-----------------------------------------------------
+.input|xwiki/2.0
+.# Validate wiki=false option
+.#-----------------------------------------------------
+{{script}}
+**bold**
+{{/script}}
+
+{{script wiki=false}}
+**not bold**
+{{/script}}
+
+{{script}}**bold**{{/script}}{{script wiki=false}}**not bold**{{/script}}
+.#-----------------------------------------------------
+.expect|event/1.0
+.#-----------------------------------------------------
+beginDocument
+beginMacroMarkerStandalone [script] [] [**bold**]
+beginParagraph
+beginFormat [BOLD]
+onWord [bold]
+endFormat [BOLD]
+endParagraph
+endMacroMarkerStandalone [script] [] [**bold**]
+beginMacroMarkerStandalone [script] [wiki=false] [**not bold**]
+beginParagraph
+onSpecialSymbol [*]
+onSpecialSymbol [*]
+onWord [not]
+onSpace
+onWord [bold]
+onSpecialSymbol [*]
+onSpecialSymbol [*]
+endParagraph
+endMacroMarkerStandalone [script] [wiki=false] [**not bold**]
+beginParagraph
+beginMacroMarkerInline [script] [] [**bold**]
+beginFormat [BOLD]
+onWord [bold]
+endFormat [BOLD]
+endMacroMarkerInline [script] [] [**bold**]
+beginMacroMarkerInline [script] [wiki=false] [**not bold**]
+onSpecialSymbol [*]
+onSpecialSymbol [*]
+onWord [not]
+onSpace
+onWord [bold]
+onSpecialSymbol [*]
+onSpecialSymbol [*]
+endMacroMarkerInline [script] [wiki=false] [**not bold**]
+endParagraph
+endDocument
\ No newline at end of file
Index: core/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-script/src/test/resources/macroscript5.test
===================================================================
--- core/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-script/src/test/resources/macroscript5.test	(revision 0)
+++ core/xwiki-rendering/xwiki-rendering-macros/xwiki-rendering-macro-script/src/test/resources/macroscript5.test	(revision 0)
@@ -0,0 +1,23 @@
+.#-----------------------------------------------------
+.input|xwiki/2.0
+.# Validate that inner macro is inline too
+.#-----------------------------------------------------
+text {{script}}{{script}}script here{{/script}}{{/script}} text
+.#-----------------------------------------------------
+.expect|event/1.0
+.#-----------------------------------------------------
+beginDocument
+beginParagraph
+onWord [text]
+onSpace
+beginMacroMarkerInline [script] [] [{{script}}script here{{/script}}]
+beginMacroMarkerInline [script] [] [script here]
+onWord [script]
+onSpace
+onWord [here]
+endMacroMarkerInline [script] [] [script here]
+endMacroMarkerInline [script] [] [{{script}}script here{{/script}}]
+onSpace
+onWord [text]
+endParagraph
+endDocument
\ No newline at end of file
