/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.util.xml.stubs;

import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.psi.stubs.ObjectStubTree;
import com.intellij.psi.stubs.StubTreeLoader;
import com.intellij.psi.xml.XmlFile;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.util.xml.DomFileElement;
import com.intellij.util.xml.DomManager;
import com.intellij.util.xml.XmlName;
import com.intellij.util.xml.reflect.DomExtender;
import com.intellij.util.xml.reflect.DomExtenderEP;
import com.intellij.util.xml.reflect.DomExtensionsRegistrar;
import com.intellij.util.xml.stubs.model.Bar;
import com.intellij.util.xml.stubs.model.Custom;
import com.intellij.util.xml.stubs.model.Foo;
import org.jetbrains.annotations.NotNull;

/**
 * @author Dmitry Avdeev
 *         Date: 8/3/12
 */
public class DomStubBuilderTest extends DomStubTest {

  public void testDomLoading() throws Exception {
    getRootStub("foo.xml");
  }

  public void testFoo() throws Exception {
    doBuilderTest("foo.xml", "File:foo\n" +
                             "  Element:foo\n" +
                             "    Element:bar\n" +
                             "      Attribute:string:xxx\n" +
                             "      Attribute:int:666\n" +
                             "    Element:bar\n");
  }

  public void testIncompleteAttribute() throws Exception {
    doBuilderTest("incompleteAttribute.xml", "File:foo\n" +
                                             "  Element:foo\n" +
                                             "    Element:bar\n" +
                                             "      Attribute:string:\n");
  }

  public void testDomExtension() throws Exception {
    DomExtenderEP ep = new DomExtenderEP();
    ep.domClassName = Bar.class.getName();
    ep.extenderClassName = TestExtender.class.getName();
    PlatformTestUtil.registerExtension(Extensions.getRootArea(), DomExtenderEP.EP_NAME, ep, myTestRootDisposable);

    doBuilderTest("extender.xml", "File:foo\n" +
                                  "  Element:foo\n" +
                                  "    Element:bar\n" +
                                  "      Attribute:extend:xxx\n" +
                                  "    Element:bar\n");
  }

  public void testNullTag() throws Exception {
    VirtualFile virtualFile = myFixture.copyFileToProject("nullTag.xml");
    assertNotNull(virtualFile);
    PsiFile psiFile = ((PsiManagerEx)getPsiManager()).getFileManager().findFile(virtualFile);

    StubTreeLoader loader = StubTreeLoader.getInstance();
    VirtualFile file = psiFile.getVirtualFile();
    assertTrue(loader.canHaveStub(file));
    ObjectStubTree stubTree = loader.readFromVFile(getProject(), file);
    assertNull(stubTree); // no stubs for invalid XML
  }

  public void testInclusion() throws Exception {
    myFixture.copyFileToProject("include.xml");
    doBuilderTest("inclusion.xml", "File:foo\n" +
                                   "  Element:foo\n" +
                                   "    Element:bar\n" +
                                   "      Attribute:string:xxx\n" +
                                   "      Attribute:int:666\n" +
                                   "    Element:bar\n");

    PsiFile file = myFixture.getFile();
    DomFileElement<Foo> element = DomManager.getDomManager(getProject()).getFileElement((XmlFile)file, Foo.class);
    assert element != null;
    assertEquals(2, element.getRootElement().getBars().size());
  }

  public static class TestExtender extends DomExtender<Bar> {

    @Override
    public void registerExtensions(@NotNull Bar bar, @NotNull DomExtensionsRegistrar registrar) {
      registrar.registerAttributeChildExtension(new XmlName("extend"), Custom.class);
    }

    @Override
    public boolean supportsStubs() {
      return true;
    }
  }
}

@@ -1779,32 +1779,82 @@
 lement:foo%5Cn%22 +%0A
+                             %22    Element:id%5Cn%22 +%0A
                 

test fixed