// Copyright (c) 2007 Omer Rauchwerger (a.k.a rauchy) (omer@rauchy.net) // All rights reserved. // // This file is part of Regionerate. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, // or (at your option) any later version. // // This program 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 General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . using System; using System.Collections.Generic; using NUnit.Framework; using Rauchy.Regionerate.Domain.Entities; using Rhino.Mocks; namespace Rauchy.Regionerate.Shared.Components.Rendering.Tests { /// /// Tests the class. /// public abstract class RegionRendererTests { #region Data Members (10)  private CodeLayout.Configuration _defaultConfiguration; private CodeLayout.RenderingOptions _defaultRenderingOptions; private Symbol _defaultSymbolParameter; private MockRepository _mockRepository; private const bool DefaultShowCountParameter = true; private const int DefaultTabAmountParameter = 2; private const bool DefaultUseTabsParameter = true; private const int DefaultSpaceAmountParameter = 0; protected const string RegionTitle = "My Region"; protected Region Region { get; set; } #endregion Data Members  #region Initialization (2)  // [rgn] Public Methods (10) [ TestFixtureSetUp ] public void Initialize() { _defaultSymbolParameter = new HiddenDragon(); _defaultRenderingOptions = new CodeLayout.RenderingOptions( DefaultShowCountParameter, DefaultTabAmountParameter, DefaultUseTabsParameter, DefaultSpaceAmountParameter); _defaultConfiguration = new CodeLayout.Configuration(_defaultSymbolParameter, _defaultRenderingOptions, null ); } [ SetUp ] public void SetUp() { _mockRepository = new MockRepository(); Region = new Region {Title = RegionTitle, PadFirstChild = 1, PadLastChild = 1}; } #endregion Initialization  #region Tests (8)  /// /// Region children should be counted recursively. In this test, two Field objects /// will be a memebers of an inner region and the result of the outer region count should be 2. /// [ Test ] public void RecursivelyCountsChildrenCorrectly() { const int expectedChildrenCount = 2; Region innerRegion = new Region {Title = "Inner Region", PadFirstChild = 1, PadLastChild = 1}; Field field1 = new Field(); field1.SetStringRepresentation( "public int _myField1;" ); innerRegion.Children.Add( field1 ); Field field2 = new Field(); field2.SetStringRepresentation( "public int _myField2;" ); innerRegion.Children.Add( field2 ); Region.Children.Add( innerRegion ); string renderedRegion = Render( Region, expectedChildrenCount ); IList lines = renderedRegion.GetLines(); VerifyHeader( lines, expectedChildrenCount ); VerifyFooter( lines ); } [ Test ] public void RendersAnEmptyRegion() { const int expectedChildrenCount = 0; string renderedRegion = Render( Region, expectedChildrenCount ); IList lines = renderedRegion.GetLines(); VerifyHeader( lines, expectedChildrenCount ); VerifyFooter( lines ); } [ Test ] public void RendersARegionWithASingleChild() { const int expectedChildrenCount = 1; Field field = new Field(); field.SetStringRepresentation( "public int _myField" ); Region.Children.Add( field ); string renderedRegion = Render( Region, expectedChildrenCount ); IList lines = renderedRegion.GetLines(); VerifyHeader( lines, expectedChildrenCount ); VerifyBody( lines, Region.Children ); VerifyFooter( lines ); } [ Test ] public void RendersARegionWithMultipleChildren() { const int expectedChildrenCount = 2; Field field = new Field(); field.SetStringRepresentation( "public int _myField" ); Region.Children.Add( field ); Property property = new Property(); property.SetStringRepresentation( "public int Foo { get; set; }" ); Region.Children.Add( property ); string renderedRegion = Render( Region, expectedChildrenCount ); IList lines = renderedRegion.GetLines(); VerifyHeader( lines, expectedChildrenCount ); VerifyBody( lines, Region.Children ); VerifyFooter( lines ); } [ Test ] [ ExpectedException( typeof ( ArgumentOutOfRangeException ) ) ] public void ShouldNotAcceptNegativeTabAmount() { CodeLayout.Configuration configuration = new CodeLayout.Configuration( _defaultSymbolParameter, new CodeLayout.RenderingOptions( DefaultShowCountParameter, -1, DefaultUseTabsParameter, DefaultSpaceAmountParameter), null); CreateConcreteRenderer( configuration ); } [ Test ] [ ExpectedException( typeof ( ArgumentNullException ) ) ] public void ShouldNotAttemptToRenderNulls() { RegionRenderer renderer = CreateConcreteRenderer( _defaultConfiguration ); renderer.Render( null ); } /// /// Since non-functional code (such as separators) should not be counted, this test /// adds two code blocks (one functional and the other non-functional) and verifies that /// the counts only the functional one. /// [ Test ] public void ShouldNotCountNonFunctionalCode() { const int expectedChildrenCount = 1; Field field = new Field(); field.SetStringRepresentation( "public int _myField;" ); Region.Children.Add( field ); UnrecognizedCode unrecognizedCode = new UnrecognizedCode(); unrecognizedCode.SetStringRepresentation( "I am so non-functional!" ); Region.Children.Add( unrecognizedCode ); string renderedRegion = Render( Region, expectedChildrenCount ); IList lines = renderedRegion.GetLines(); VerifyHeader( lines, expectedChildrenCount ); VerifyBody( lines, Region.Children ); VerifyFooter( lines ); } [ Test ] public void TabifiesDeclarations() { bool showCount = true; int numberOfTabs = 3; bool useTabs = true; int spaces = 9; CodeLayout.RenderingOptions renderingOptions = new CodeLayout.RenderingOptions( showCount, numberOfTabs, useTabs, spaces ); const int expectedChildrenCount = 0; string renderedRegion = Render(Region, expectedChildrenCount, renderingOptions); IList lines = renderedRegion.GetLines(); VerifyHeader(lines, expectedChildrenCount, renderingOptions); VerifyFooter(lines, renderingOptions); } [Test] public void SpacifiesDeclarations() { bool showCount = true; int numberOfTabs = 3; bool useTabs = false; int spaces = 9; CodeLayout.RenderingOptions renderingOptions = new CodeLayout.RenderingOptions(showCount, numberOfTabs, useTabs, spaces); const int expectedChildrenCount = 0; string renderedRegion = Render(Region, expectedChildrenCount, renderingOptions); IList lines = renderedRegion.GetLines(); VerifyHeader(lines, expectedChildrenCount, renderingOptions); VerifyFooter(lines, renderingOptions); } #endregion Tests  #region Helper Methods (9)  // [rgn] Protected Methods (8) protected abstract RegionRenderer CreateConcreteRenderer( CodeLayout.Configuration configuration ); /// /// Extracts the lines that are not region headers or footers. /// protected abstract IList ExtractBody( IList lines ); protected string Render( Region region, int expectedMemberCount ) { return Render( region, expectedMemberCount, _defaultRenderingOptions ); } // [rgn] Private Methods (1) private string Render(Region region, int expectedMemberCount, CodeLayout.RenderingOptions renderingOptions) { Symbol mockedSymbol = _mockRepository.Stub(); using ( _mockRepository.Record() ) { // Setup an expectation for the header to be embedded. string expectedRegionTitle = RegionTitle + string.Format( " ({0})", expectedMemberCount ); Expect.Call( mockedSymbol.Embed( expectedRegionTitle ) ).Return( " " + expectedRegionTitle ); // Setup an expectation for the footer to be embedded. // (Does not contain children count like the last expectation). Expect.Call( mockedSymbol.Embed( RegionTitle ) ).Return( " " + RegionTitle ); } CodeLayout.Configuration configuration = new CodeLayout.Configuration( mockedSymbol, renderingOptions, null); RegionRenderer renderer = CreateConcreteRenderer(configuration); string renderedRegion; using ( _mockRepository.Playback() ) { renderedRegion = renderer.Render( region ); } _mockRepository.Verify( mockedSymbol ); return renderedRegion; } protected void VerifyBody( IList lines, IList code ) { IList body = ExtractBody( lines ); // Assuming all Code objects in "code" are one-liners. Assert.AreEqual( code.Count, body.Count ); for ( int i = 0; i < body.Count; i++ ) { Assert.AreEqual( body[ i ], code[ i ] + Environment.NewLine ); } } protected void VerifyFooter( IList lines ) { VerifyFooter( lines, _defaultRenderingOptions ); } protected abstract void VerifyFooter(IList lines, CodeLayout.RenderingOptions renderingOptions); protected void VerifyHeader( IList lines, int? expectedChildrenCount ) { VerifyHeader(lines, expectedChildrenCount, _defaultRenderingOptions); } protected abstract void VerifyHeader(IList lines, int? expectedChildrenCount, CodeLayout.RenderingOptions renderingOptions); #endregion Helper Methods  } }