/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you 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
 *  
 *    https://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 org.apache.directory.api.ldap.model.schema;


import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

import org.apache.directory.api.ldap.model.schema.parsers.AttributeTypeDescriptionSchemaParser;
import org.apache.directory.api.ldap.model.schema.parsers.DitContentRuleDescriptionSchemaParser;
import org.apache.directory.api.ldap.model.schema.parsers.DitStructureRuleDescriptionSchemaParser;
import org.apache.directory.api.ldap.model.schema.parsers.OpenLdapSchemaParser;
import org.apache.directory.api.ldap.model.schema.parsers.LdapSyntaxDescriptionSchemaParser;
import org.apache.directory.api.ldap.model.schema.parsers.MatchingRuleDescriptionSchemaParser;
import org.apache.directory.api.ldap.model.schema.parsers.MatchingRuleUseDescriptionSchemaParser;
import org.apache.directory.api.ldap.model.schema.parsers.NameFormDescriptionSchemaParser;
import org.apache.directory.api.ldap.model.schema.parsers.ObjectClassDescriptionSchemaParser;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;


/**
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
@Execution(ExecutionMode.CONCURRENT)
public class SchemaObjectRendererTest
{

    private ObjectClass objectClassSimple;
    private ObjectClass objectClassComplex;

    private AttributeType attributeTypeSimple;
    private AttributeType attributeTypeComplex;

    private MatchingRule matchingRule;
    private MatchingRuleUse matchingRuleUse;
    private LdapSyntax ldapSyntax;
    private DitContentRule ditContentRule;
    private DitStructureRule ditStructureRule;
    private NameForm nameForm;


    @BeforeEach
    public void setUp()
    {
        objectClassSimple = new ObjectClass( "1.2.3.4" );
        objectClassSimple.setNames( "name0" );
        objectClassSimple.setMustAttributeTypeOids( Arrays.asList( "att0" ) );
        objectClassSimple.setSchemaName( "dummy" );

        objectClassComplex = new ObjectClass( "1.2.3.4" );
        objectClassComplex.setNames( "name1", "name2" );
        objectClassComplex.setDescription( "description with 'quotes'" );
        objectClassComplex.setObsolete( true );
        objectClassComplex.setSuperiorOids( Collections.singletonList( "1.3.5.7" ) );
        objectClassComplex.setType( ObjectClassTypeEnum.AUXILIARY );
        objectClassComplex.setMustAttributeTypeOids( Arrays.asList( "att1", "att2" ) );
        objectClassComplex.setMayAttributeTypeOids( Arrays.asList( "att3", "att4" ) );
        objectClassComplex.setSchemaName( "dummy" );

        attributeTypeSimple = new AttributeType( "1.2.3.4" );
        attributeTypeSimple.setNames( "name0" );
        attributeTypeSimple.setEqualityOid( "matchingRule0" );
        attributeTypeSimple.setSyntaxOid( "2.3.4.5" );
        attributeTypeSimple.setSyntaxLength( 512 );
        attributeTypeSimple.setCollective( true );
        attributeTypeSimple.setSchemaName( "dummy" );

        attributeTypeComplex = new AttributeType( "1.2.3.4" );
        attributeTypeComplex.setNames( "name1", "name2" );
        attributeTypeComplex.setDescription( "description with 'quotes'" );
        attributeTypeComplex.setObsolete( true );
        attributeTypeComplex.setSuperiorOid( "superAttr" );
        attributeTypeComplex.setEqualityOid( "matchingRule1" );
        attributeTypeComplex.setOrderingOid( "matchingRule2" );
        attributeTypeComplex.setSubstringOid( "matchingRule3" );
        attributeTypeComplex.setSingleValued( true );
        attributeTypeComplex.setUserModifiable( false );
        attributeTypeComplex.setUsage( UsageEnum.DIRECTORY_OPERATION );
        attributeTypeComplex.setSchemaName( "dummy" );

        matchingRule = new MatchingRule( "1.2.3.4" );
        matchingRule.setNames( "name0" );
        matchingRule.setDescription( "description with 'quotes'" );
        matchingRule.setObsolete( true );
        matchingRule.setSyntaxOid( "2.3.4.5" );
        matchingRule.setSchemaName( "dummy" );

        matchingRuleUse = new MatchingRuleUse( "1.2.3.4" );
        matchingRuleUse.setNames( "name0" );
        matchingRuleUse.setDescription( "description with 'quotes'" );
        matchingRuleUse.setObsolete( true );
        matchingRuleUse.setApplicableAttributeOids( Arrays.asList( "2.3.4.5", "1.3.4.5.6" ) );
        matchingRuleUse.setSchemaName( "dummy" );

        ldapSyntax = new LdapSyntax( "1.2.3.4" );
        ldapSyntax.setDescription( "description with 'quotes'" );
        ldapSyntax.setHumanReadable( false );
        ldapSyntax.setSchemaName( "dummy" );

        ditContentRule = new DitContentRule( "1.2.3.4" );
        ditContentRule.setNames( "name1", "name2" );
        ditContentRule.setDescription( "description with 'quotes'" );
        ditContentRule.setObsolete( true );
        ditContentRule.setAuxObjectClassOids( Arrays.asList( "oc1", "oc2" ) );
        ditContentRule.setMustAttributeTypeOids( Arrays.asList( "must1", "must2" ) );
        ditContentRule.setMayAttributeTypeOids( Arrays.asList( "may1", "may2" ) );
        ditContentRule.setNotAttributeTypeOids( Arrays.asList( "not1", "not2" ) );
        ditContentRule.setSchemaName( "dummy" );

        ditStructureRule = new DitStructureRule( 1234 );
        ditStructureRule.setNames( "name1", "name2" );
        ditStructureRule.setDescription( "description with 'quotes'" );
        ditStructureRule.setObsolete( true );
        ditStructureRule.setForm( "form1" );
        ditStructureRule.setSuperRules( Arrays.asList( 111, 222, 333 ) );
        ditStructureRule.setSchemaName( "dummy" );

        nameForm = new NameForm( "1.2.3.4" );
        nameForm.setNames( "name1", "name2" );
        nameForm.setDescription( "description with 'quotes'" );
        nameForm.setObsolete( true );
        nameForm.setStructuralObjectClassOid( "oc1" );
        nameForm.setMustAttributeTypeOids( Arrays.asList( "must1", "must2" ) );
        nameForm.setMayAttributeTypeOids( Arrays.asList( "may0" ) );
        nameForm.setSchemaName( "dummy" );
    }


    @Test
    public void testOpenLdapSchemaRendererObjectClassMinimal()
    {
        String actual = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( new ObjectClass( "1.2.3" ) );
        String expected = "objectclass ( 1.2.3\n\tSTRUCTURAL )";
        assertEquals( expected, actual );
    }


    @Test
    public void testOpenLdapSchemaRendererObjectClassSimple()
    {
        String actual = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( objectClassSimple );
        String expected = "objectclass ( 1.2.3.4 NAME 'name0'\n\tSTRUCTURAL\n\tMUST att0 )";
        assertEquals( expected, actual );
    }


    @Test
    public void testOpenLdapSchemaRendererObjectClassComplex()
    {
        String actual = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( objectClassComplex );
        String expected = "objectclass ( 1.2.3.4 NAME ( 'name1' 'name2' )\n\tDESC 'description with \\27quotes\\27'\n\tOBSOLETE\n\tSUP 1.3.5.7\n\tAUXILIARY\n\tMUST ( att1 $ att2 )\n\tMAY ( att3 $ att4 ) )";
        assertEquals( expected, actual );
    }


    @Test
    public void testOpenLdapSchemaRendererAndParserRoundtripObjectClassSimple() throws Exception
    {
        testOpenLdapSchemaRendererAndParserRountrip( objectClassSimple );
    }


    @Test
    public void testOpenLdapSchemaRendererAndParserRoundtripObjectClassComplex() throws Exception
    {
        testOpenLdapSchemaRendererAndParserRountrip( objectClassComplex );
    }


    private void testOpenLdapSchemaRendererAndParserRountrip( ObjectClass original ) throws Exception
    {
        // must unset schema name because OpenLdapSchemaParser doesn't know about schema name
        original.setSchemaName( null );

        String renderedOriginal = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( original );
        ObjectClass parsed = ( ObjectClass ) new OpenLdapSchemaParser().parse( renderedOriginal );
        String renderedParsed = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( parsed );

        assertTrue( original.equals( parsed ) );
        assertTrue( renderedOriginal.equals( renderedParsed ) );
    }


    @Test
    public void testSubschemSubentryRendererObjectClassMinimal()
    {
        String actual = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( new ObjectClass( "1.2.3" ) );
        String expected = "( 1.2.3 STRUCTURAL X-SCHEMA 'null' )";
        assertEquals( expected, actual );
    }


    @Test
    public void testSubschemSubentryRendererObjectClassSimple()
    {
        String actual = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( objectClassSimple );
        String expected = "( 1.2.3.4 NAME 'name0' STRUCTURAL MUST att0 X-SCHEMA 'dummy' )";
        assertEquals( expected, actual );
    }


    @Test
    public void testSubschemSubentryRendererObjectClassComplex()
    {
        String actual = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( objectClassComplex );
        String expected = "( 1.2.3.4 NAME ( 'name1' 'name2' ) DESC 'description with \\27quotes\\27' OBSOLETE SUP 1.3.5.7 AUXILIARY MUST ( att1 $ att2 ) MAY ( att3 $ att4 ) X-SCHEMA 'dummy' )";
        assertEquals( expected, actual );
    }


    @Test
    public void testSubschemSubentryRendererAndParserRoundtripObjectClassSimple() throws ParseException
    {
        testSubschemSubentryRendererAndParserRoundtrip( objectClassSimple );
    }


    @Test
    public void testSubschemSubentryRendererAndParserRoundtripObjectClassComplex() throws ParseException
    {
        testSubschemSubentryRendererAndParserRoundtrip( objectClassComplex );
    }


    private void testSubschemSubentryRendererAndParserRoundtrip( ObjectClass original ) throws ParseException
    {
        String renderedOriginal = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( original );
        ObjectClass parsed = new ObjectClassDescriptionSchemaParser().parse( renderedOriginal );
        String renderedParsed = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( parsed );

        assertTrue( original.equals( parsed ) );
        assertTrue( renderedOriginal.equals( renderedParsed ) );
    }


    @Test
    public void testOpenLdapSchemaRendererAttributeTypeSimple()
    {
        String actual = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( attributeTypeSimple );
        String expected = "attributetype ( 1.2.3.4 NAME 'name0'\n\tEQUALITY matchingRule0\n\tSYNTAX 2.3.4.5{512}\n\tCOLLECTIVE\n\tUSAGE userApplications )";
        assertEquals( expected, actual );
    }


    @Test
    public void testOpenLdapSchemaRendererAttributeTypeComplex()
    {
        String actual = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( attributeTypeComplex );
        String expected = "attributetype ( 1.2.3.4 NAME ( 'name1' 'name2' )\n\tDESC 'description with \\27quotes\\27'\n\tOBSOLETE\n\tSUP superAttr\n\tEQUALITY matchingRule1\n\tORDERING matchingRule2\n\tSUBSTR matchingRule3\n\tSINGLE-VALUE\n\tNO-USER-MODIFICATION\n\tUSAGE directoryOperation )";
        assertEquals( expected, actual );
    }


    @Test
    public void testOpenLdapSchemaRendererAndParserRoundtripAttributeTypeSimple() throws Exception
    {
        testOpenLdapSchemaRendererAndParserRountrip( attributeTypeSimple );
    }


    @Test
    public void testOpenLdapSchemaRendererAndParserRoundtripAttributeTypeComplex() throws Exception
    {
        testOpenLdapSchemaRendererAndParserRountrip( attributeTypeComplex );
    }


    private void testOpenLdapSchemaRendererAndParserRountrip( AttributeType original ) throws Exception
    {
        // must unset schema name because OpenLdapSchemaParser doesn't know about schema name
        original.setSchemaName( null );

        String renderedOriginal = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( original );
        AttributeType parsed = ( AttributeType ) new OpenLdapSchemaParser().parse( renderedOriginal );
        String renderedParsed = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( parsed );

        assertTrue( original.equals( parsed ) );
        assertTrue( renderedOriginal.equals( renderedParsed ) );
    }


    @Test
    public void testSubschemSubentryRendererAttributeTypeSimple()
    {
        String actual = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( attributeTypeSimple );
        String expected = "( 1.2.3.4 NAME 'name0' EQUALITY matchingRule0 SYNTAX 2.3.4.5{512} COLLECTIVE USAGE userApplications X-SCHEMA 'dummy' )";
        assertEquals( expected, actual );
    }


    @Test
    public void testSubschemSubentryRendererAttributeTypeComplex()
    {
        String actual = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( attributeTypeComplex );
        String expected = "( 1.2.3.4 NAME ( 'name1' 'name2' ) DESC 'description with \\27quotes\\27' OBSOLETE SUP superAttr EQUALITY matchingRule1 ORDERING matchingRule2 SUBSTR matchingRule3 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-SCHEMA 'dummy' )";
        assertEquals( expected, actual );
    }


    @Test
    public void testSubschemSubentryRendererAndParserRoundtripAttributeTypeSimple() throws ParseException
    {
        testSubschemSubentryRendererAndParserRoundtrip( attributeTypeSimple );
    }


    @Test
    public void testSubschemSubentryRendererAndParserRoundtripAttributeTypeComplex() throws ParseException
    {
        testSubschemSubentryRendererAndParserRoundtrip( attributeTypeComplex );
    }


    private void testSubschemSubentryRendererAndParserRoundtrip( AttributeType original ) throws ParseException
    {
        String renderedOriginal = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( original );
        AttributeType parsed = new AttributeTypeDescriptionSchemaParser().parse( renderedOriginal );
        String renderedParsed = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( parsed );

        assertTrue( original.equals( parsed ) );
        assertTrue( renderedOriginal.equals( renderedParsed ) );
    }


    @Test
    public void testOpenLdapSchemaRendererMatchingRule()
    {
        String actual = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( matchingRule );
        String expected = "matchingrule ( 1.2.3.4 NAME 'name0'\n\tDESC 'description with \\27quotes\\27'\n\tOBSOLETE\n\tSYNTAX 2.3.4.5 )";
        assertEquals( expected, actual );
    }


    @Test
    public void testSubschemSubentryRendererMatchingRule()
    {
        String actual = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( matchingRule );
        String expected = "( 1.2.3.4 NAME 'name0' DESC 'description with \\27quotes\\27' OBSOLETE SYNTAX 2.3.4.5 X-SCHEMA 'dummy' )";
        assertEquals( expected, actual );
    }


    @Test
    public void testSubschemSubentryRendererAndParserRoundtripMatchingRule() throws ParseException
    {
        testSubschemSubentryRendererAndParserRoundtrip( matchingRule );
    }


    private void testSubschemSubentryRendererAndParserRoundtrip( MatchingRule original ) throws ParseException
    {
        String renderedOriginal = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( original );
        MatchingRule parsed = new MatchingRuleDescriptionSchemaParser().parse( renderedOriginal );
        String renderedParsed = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( parsed );

        assertTrue( original.equals( parsed ) );
        assertTrue( renderedOriginal.equals( renderedParsed ) );
    }


    @Test
    public void testOpenLdapSchemaRendererLdapSyntax()
    {
        String actual = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( ldapSyntax );
        String expected = "ldapsyntax ( 1.2.3.4\n\tDESC 'description with \\27quotes\\27'\n\tX-NOT-HUMAN-READABLE 'true' )";
        assertEquals( expected, actual );
    }


    @Test
    public void testSubschemSubentryRendererLdapSyntax()
    {
        String actual = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( ldapSyntax );
        String expected = "( 1.2.3.4 DESC 'description with \\27quotes\\27' X-SCHEMA 'dummy' X-NOT-HUMAN-READABLE 'true' )";
        assertEquals( expected, actual );
    }


    @Test
    public void testSubschemSubentryRendererAndParserRoundtripLdapSyntax() throws ParseException
    {
        testSubschemSubentryRendererAndParserRoundtrip( ldapSyntax );
    }


    private void testSubschemSubentryRendererAndParserRoundtrip( LdapSyntax original ) throws ParseException
    {
        String renderedOriginal = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( original );
        LdapSyntax parsed = new LdapSyntaxDescriptionSchemaParser().parse( renderedOriginal );
        String renderedParsed = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( parsed );

        assertTrue( original.equals( parsed ) );
        assertTrue( renderedOriginal.equals( renderedParsed ) );
    }


    @Test
    public void testOpenLdapSchemaRendererMatchingRuleUse()
    {
        String actual = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( matchingRuleUse );
        String expected = "matchingruleuse ( 1.2.3.4 NAME 'name0'\n\tDESC 'description with \\27quotes\\27'\n\tOBSOLETE\n\tAPPLIES ( 2.3.4.5 $ 1.3.4.5.6 ) )";
        assertEquals( expected, actual );
    }


    @Test
    public void testSubschemSubentryRendererMatchingRuleUse()
    {
        String actual = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( matchingRuleUse );
        String expected = "( 1.2.3.4 NAME 'name0' DESC 'description with \\27quotes\\27' OBSOLETE APPLIES ( 2.3.4.5 $ 1.3.4.5.6 ) X-SCHEMA 'dummy' )";
        assertEquals( expected, actual );
    }


    @Test
    public void testSubschemSubentryRendererAndParserRoundtripMatchingRuleUse() throws ParseException
    {
        testSubschemSubentryRendererAndParserRoundtrip( matchingRuleUse );
    }


    private void testSubschemSubentryRendererAndParserRoundtrip( MatchingRuleUse original ) throws ParseException
    {
        String renderedOriginal = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( original );
        MatchingRuleUse parsed = new MatchingRuleUseDescriptionSchemaParser().parse( renderedOriginal );
        String renderedParsed = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( parsed );

        assertTrue( original.equals( parsed ) );
        assertTrue( renderedOriginal.equals( renderedParsed ) );
    }


    @Test
    public void testOpenLdapSchemaRendererDitContentRule()
    {
        String actual = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( ditContentRule );
        String expected = "ditcontentrule ( 1.2.3.4 NAME ( 'name1' 'name2' )\n\tDESC 'description with \\27quotes\\27'\n\tOBSOLETE\n\tAUX ( oc1 $ oc2 )\n\tMUST ( must1 $ must2 )\n\tMAY ( may1 $ may2 )\n\tNOT ( not1 $ not2 ) )";
        assertEquals( expected, actual );
    }


    @Test
    public void testSubschemSubentryRendererDitContentRule()
    {
        String actual = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( ditContentRule );
        String expected = "( 1.2.3.4 NAME ( 'name1' 'name2' ) DESC 'description with \\27quotes\\27' OBSOLETE AUX ( oc1 $ oc2 ) MUST ( must1 $ must2 ) MAY ( may1 $ may2 ) NOT ( not1 $ not2 ) X-SCHEMA 'dummy' )";
        assertEquals( expected, actual );
    }


    @Test
    public void testSubschemSubentryRendererAndParserRoundtripDitContentRule() throws ParseException
    {
        testSubschemSubentryRendererAndParserRoundtrip( ditContentRule );
    }


    private void testSubschemSubentryRendererAndParserRoundtrip( DitContentRule original ) throws ParseException
    {
        String renderedOriginal = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( original );
        DitContentRule parsed = new DitContentRuleDescriptionSchemaParser().parse( renderedOriginal );
        String renderedParsed = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( parsed );

        assertTrue( original.equals( parsed ) );
        assertTrue( renderedOriginal.equals( renderedParsed ) );
    }


    @Test
    public void testOpenLdapSchemaRendererDitStructureRule()
    {
        String actual = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( ditStructureRule );
        String expected = "ditstructurerule ( 1234 NAME ( 'name1' 'name2' )\n\tDESC 'description with \\27quotes\\27'\n\tOBSOLETE\n\tFORM form1\n\tSUP ( 111 222 333 ) )";
        assertEquals( expected, actual );
    }


    @Test
    public void testSubschemSubentryRendererDitStructureRule()
    {
        String actual = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( ditStructureRule );
        String expected = "( 1234 NAME ( 'name1' 'name2' ) DESC 'description with \\27quotes\\27' OBSOLETE FORM form1 SUP ( 111 222 333 ) X-SCHEMA 'dummy' )";
        assertEquals( expected, actual );

        ditStructureRule.setSuperRules( null );
        String actual2 = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( ditStructureRule );
        String expected2 = "( 1234 NAME ( 'name1' 'name2' ) DESC 'description with \\27quotes\\27' OBSOLETE FORM form1 X-SCHEMA 'dummy' )";
        assertEquals( expected2, actual2 );
    }


    @Test
    public void testSubschemSubentryRendererAndParserRoundtripDitStructureRule() throws ParseException
    {
        testSubschemSubentryRendererAndParserRoundtrip( ditStructureRule );
    }


    private void testSubschemSubentryRendererAndParserRoundtrip( DitStructureRule original ) throws ParseException
    {
        String renderedOriginal = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( original );
        DitStructureRule parsed = new DitStructureRuleDescriptionSchemaParser().parse( renderedOriginal );
        String renderedParsed = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( parsed );

        assertTrue( original.equals( parsed ) );
        assertTrue( renderedOriginal.equals( renderedParsed ) );
    }


    @Test
    public void testOpenLdapSchemaRendererNameForm()
    {
        String actual = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( nameForm );
        String expected = "nameform ( 1.2.3.4 NAME ( 'name1' 'name2' )\n\tDESC 'description with \\27quotes\\27'\n\tOBSOLETE\n\tOC oc1\n\tMUST ( must1 $ must2 )\n\tMAY may0 )";
        assertEquals( expected, actual );
    }


    @Test
    public void testSubschemSubentryRendererNameForm()
    {
        String actual = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( nameForm );
        String expected = "( 1.2.3.4 NAME ( 'name1' 'name2' ) DESC 'description with \\27quotes\\27' OBSOLETE OC oc1 MUST ( must1 $ must2 ) MAY may0 X-SCHEMA 'dummy' )";
        assertEquals( expected, actual );

        nameForm.setMayAttributeTypeOids( new ArrayList<String>() );
        String actual2 = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( nameForm );
        String expected2 = "( 1.2.3.4 NAME ( 'name1' 'name2' ) DESC 'description with \\27quotes\\27' OBSOLETE OC oc1 MUST ( must1 $ must2 ) X-SCHEMA 'dummy' )";
        assertEquals( expected2, actual2 );
    }


    @Test
    public void testSubschemSubentryRendererAndParserRoundtripNameForm() throws ParseException
    {
        testSubschemSubentryRendererAndParserRoundtrip( nameForm );
    }


    private void testSubschemSubentryRendererAndParserRoundtrip( NameForm original ) throws ParseException
    {
        String renderedOriginal = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( original );
        NameForm parsed = new NameFormDescriptionSchemaParser().parse( renderedOriginal );
        String renderedParsed = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( parsed );

        assertTrue( original.equals( parsed ) );
        assertTrue( renderedOriginal.equals( renderedParsed ) );
    }
}
