Skip to content

Commit

Permalink
update README
Browse files Browse the repository at this point in the history
  • Loading branch information
ashahabov committed Oct 21, 2022
1 parent fb1efad commit b4265ed
Show file tree
Hide file tree
Showing 8 changed files with 239 additions and 267 deletions.
9 changes: 8 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ The internal structure of PowerPoint presentation is one the most difficult amon

## Code style and conventions

### Code style

SC-001: Public members except interface should have "SC" prefix

```c#
Expand All @@ -41,4 +43,9 @@ public class SCPresentation
{
public DocumentFormat.OpenXml.Packaging.SlidePart SDKSlidePart { get; } // valid
}
```
```

### Test file

- test file should math the following pattern `ShapeCrawler.Tests\Resorce\{shape-type}\{shape-type}-case{N}.pptx`, eg. testing file for testing feature for Chart: `ShapeCrawler.Tests\Resorce\charts\charts-case001.pptx`.
- if possible use single slide presentation.
21 changes: 7 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,19 @@ ShapeCrawler (formerly SlideDotNet) is a .NET library for manipulating PowerPoin

## Getting Started

### Install

To get started, install ShapeCrawler from [NuGet](https://nuget.org/packages/ShapeCrawler):

```console
dotnet add package ShapeCrawler
```

The library currently supports the following frameworks:
- .NET 5+
- .NET Core 2.0+
- .NET Framework 4.6.1+
> `install-package ShapeCrawler`
### Usage

```c#
using var pres = SCPresentation.Open("helloWorld.pptx");
using var pres = SCPresentation.Open("some.pptx");

// get number of slides
var slidesCount = pres.Slides.Count;

// get text of TextBox
var autoShape = pres.Slides[0].Shapes.GetByName<IAutoShape>("TextBox 1");
Console.WriteLine(autoShape.TextFrame.Text);
var text = autoShape.TextFrame!.Text;
```

Visit [**Wiki**](https://github.com/ShapeCrawler/ShapeCrawler/wiki/Examples) page to find more usage samples.
Expand Down
289 changes: 148 additions & 141 deletions ShapeCrawler.Tests/ShapeFillTests.cs
Original file line number Diff line number Diff line change
@@ -1,156 +1,163 @@
#if DEBUG

using System.Collections.Generic;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
using ShapeCrawler.Extensions;
using ShapeCrawler.Shapes;
using ShapeCrawler.Tests.Helpers;
using ShapeCrawler.Tests.Helpers.Attributes;
using ShapeCrawler.Tests.Properties;
using Xunit;

// ReSharper disable TooManyDeclarations
// ReSharper disable InconsistentNaming
// ReSharper disable TooManyChainedReferences

namespace ShapeCrawler.Tests
namespace ShapeCrawler.Tests;

public class ShapeFillTests : ShapeCrawlerTest, IClassFixture<PresentationFixture>
{
public class ShapeFillTests : ShapeCrawlerTest, IClassFixture<PresentationFixture>
private readonly PresentationFixture _fixture;

public ShapeFillTests(PresentationFixture fixture)
{
_fixture = fixture;
}

[Fact]
public void Fill_is_not_null()
{
private readonly PresentationFixture _fixture;

public ShapeFillTests(PresentationFixture fixture)
{
_fixture = fixture;
}

[Fact]
public void Fill_is_not_null()
{
// Arrange
var autoShape = (IAutoShape)_fixture.Pre021.Slides[0].Shapes.First(sp => sp.Id == 108);

// Act-Assert
autoShape.Fill.Should().NotBeNull();
}

[Theory]
[SlideShapeData("008.pptx", slideNumber: 1, shapeName: "AutoShape 1")]
[SlideShapeData("autoshape-case009.pptx", slideNumber: 1, shapeName: "AutoShape 1")]
[LayoutShapeData("autoshape-case003.pptx", slideNumber: 1, shapeName: "AutoShape 1")]
[MasterShapeData("autoshape-case003.pptx", shapeName: "AutoShape 1")]
public void SetPicture_updates_fill_with_specified_picture_image_When_shape_is_Not_filled(IShape shape)
{
// Arrange
var autoShape = (IAutoShape)shape;
var fill = autoShape.Fill;
var imageStream = GetTestStream("test-image-1.png");

// Act
fill.SetPicture(imageStream);

// Assert
var pictureBytes = fill.Picture!.BinaryData.Result;
var imageBytes = imageStream.ToArray();
pictureBytes.SequenceEqual(imageBytes).Should().BeTrue();
}

[Fact]
public void Picture_SetImage_updates_picture_fill()
{
// Arrange
var pres = SCPresentation.Open(TestFiles.Presentations.pre009);
var shape = (IAutoShape)pres.Slides[2].Shapes.First(sp => sp.Id == 4);
var fill = shape.Fill;
var newImage = TestFiles.Images.img02_stream;
var imageSizeBefore = fill.Picture!.BinaryData.GetAwaiter().GetResult().Length;

// Act
fill.Picture.SetImage(newImage);

// Assert
var imageSizeAfter = shape.Fill.Picture.BinaryData.GetAwaiter().GetResult().Length;
imageSizeAfter.Should().NotBe(imageSizeBefore, "because image has been changed");
}

[Theory]
[MemberData(nameof(TestCasesFillType))]
public void Type_returns_fill_type(IAutoShape shape, SCFillType expectedFill)
{
// Act
var fillType = shape.Fill.Type;

// Assert
fillType.Should().Be(expectedFill);
}

public static IEnumerable<object[]> TestCasesFillType()
{
var pptxStream = GetTestStream("009_table.pptx");
var pres = SCPresentation.Open(pptxStream);

var withNoFill = pres.Slides[1].Shapes.GetById<IAutoShape>(6);
yield return new object[] { withNoFill, SCFillType.NoFill };

var withSolid = pres.Slides[1].Shapes.GetById<IAutoShape>(2);
yield return new object[] { withSolid, SCFillType.Solid };

var withGradient = pres.Slides[1].Shapes.GetByName<IAutoShape>("AutoShape 1");
yield return new object[] { withGradient, SCFillType.Gradient };

var withPicture = pres.Slides[2].Shapes.GetById<IAutoShape>(4);
yield return new object[] { withPicture, SCFillType.Picture };

var withPattern = pres.Slides[1].Shapes.GetByName<IAutoShape>("AutoShape 2");
yield return new object[] { withPattern, SCFillType.Pattern };

pptxStream = GetTestStream("autoshape-case003.pptx");
pres = SCPresentation.Open(pptxStream);
var withSlideBg = pres.Slides[0].Shapes.GetByName<IAutoShape>("AutoShape 1");
yield return new object[] { withSlideBg, SCFillType.SlideBackground };
}

[Fact]
public void AutoShape_Fill_Type_returns_NoFill_When_shape_is_Not_filled()
{
// Arrange
var autoShape = (IAutoShape)_fixture.Pre009.Slides[1].Shapes.First(sp => sp.Id == 6);

// Act
var fillType = autoShape.Fill.Type;

// Assert
fillType.Should().Be(SCFillType.NoFill);
}

[Fact]
public void HexSolidColor_getter_returns_color_name()
{
// Arrange
var autoShape = (IAutoShape)_fixture.Pre009.Slides[1].Shapes.First(sp => sp.Id == 2);

// Act
var shapeSolidColorName = autoShape.Fill.HexSolidColor;

// Assert
shapeSolidColorName.Should().BeEquivalentTo("ff0000");
}

[Fact]
public async void Picture_GetImageBytes_returns_image()
{
// Arrange
var shape = (IAutoShape)_fixture.Pre009.Slides[2].Shapes.First(sp => sp.Id == 4);

// Act
var imageBytes = await shape.Fill.Picture.BinaryData.ConfigureAwait(false);

// Assert
imageBytes.Length.Should().BePositive();
}
// Arrange
var autoShape = (IAutoShape)_fixture.Pre021.Slides[0].Shapes.First(sp => sp.Id == 108);

// Act-Assert
autoShape.Fill.Should().NotBeNull();
}

[Theory]
[SlideShapeData("008.pptx", slideNumber: 1, shapeName: "AutoShape 1")]
[SlideShapeData("autoshape-case009.pptx", slideNumber: 1, shapeName: "AutoShape 1")]
[LayoutShapeData("autoshape-case003.pptx", slideNumber: 1, shapeName: "AutoShape 1")]
[MasterShapeData("autoshape-case003.pptx", shapeName: "AutoShape 1")]
public void SetPicture_updates_fill_with_specified_picture_image_When_shape_is_Not_filled(IShape shape)
{
// Arrange
var autoShape = (IAutoShape)shape;
var fill = autoShape.Fill;
var imageStream = GetTestStream("test-image-1.png");

// Act
fill.SetPicture(imageStream);

// Assert
var pictureBytes = fill.Picture!.BinaryData.Result;
var imageBytes = imageStream.ToArray();
pictureBytes.SequenceEqual(imageBytes).Should().BeTrue();
}
}

#endif
[Theory]
[SlideShapeData("autoshape-case005_text-frame.pptx", slideNumber: 1, shapeName: "AutoShape 1")]
public void SetHexSolidColor_sets_solid_color(IShape shape)
{
// Arrange
var autoShape = (IAutoShape)shape;
var shapeFill = autoShape.Fill;

// Act
shapeFill.SetHexSolidColor("32a852");

// Assert
shapeFill.HexSolidColor.Should().Be("32a852");
}

[Fact]
public void Picture_SetImage_updates_picture_fill()
{
// Arrange
var pres = SCPresentation.Open(TestFiles.Presentations.pre009);
var shape = (IAutoShape)pres.Slides[2].Shapes.First(sp => sp.Id == 4);
var fill = shape.Fill;
var newImage = TestFiles.Images.img02_stream;
var imageSizeBefore = fill.Picture!.BinaryData.GetAwaiter().GetResult().Length;

// Act
fill.Picture.SetImage(newImage);

// Assert
var imageSizeAfter = shape.Fill.Picture.BinaryData.GetAwaiter().GetResult().Length;
imageSizeAfter.Should().NotBe(imageSizeBefore, "because image has been changed");
}

[Theory]
[MemberData(nameof(TestCasesFillType))]
public void Type_returns_fill_type(IAutoShape shape, SCFillType expectedFill)
{
// Act
var fillType = shape.Fill.Type;

// Assert
fillType.Should().Be(expectedFill);
}

public static IEnumerable<object[]> TestCasesFillType()
{
var pptxStream = GetTestStream("009_table.pptx");
var pres = SCPresentation.Open(pptxStream);

var withNoFill = pres.Slides[1].Shapes.GetById<IAutoShape>(6);
yield return new object[] { withNoFill, SCFillType.NoFill };

var withSolid = pres.Slides[1].Shapes.GetById<IAutoShape>(2);
yield return new object[] { withSolid, SCFillType.Solid };

var withGradient = pres.Slides[1].Shapes.GetByName<IAutoShape>("AutoShape 1");
yield return new object[] { withGradient, SCFillType.Gradient };

var withPicture = pres.Slides[2].Shapes.GetById<IAutoShape>(4);
yield return new object[] { withPicture, SCFillType.Picture };

var withPattern = pres.Slides[1].Shapes.GetByName<IAutoShape>("AutoShape 2");
yield return new object[] { withPattern, SCFillType.Pattern };

pptxStream = GetTestStream("autoshape-case003.pptx");
pres = SCPresentation.Open(pptxStream);
var withSlideBg = pres.Slides[0].Shapes.GetByName<IAutoShape>("AutoShape 1");
yield return new object[] { withSlideBg, SCFillType.SlideBackground };
}

[Fact]
public void AutoShape_Fill_Type_returns_NoFill_When_shape_is_Not_filled()
{
// Arrange
var autoShape = (IAutoShape)_fixture.Pre009.Slides[1].Shapes.First(sp => sp.Id == 6);

// Act
var fillType = autoShape.Fill.Type;

// Assert
fillType.Should().Be(SCFillType.NoFill);
}

[Fact]
public void HexSolidColor_getter_returns_color_name()
{
// Arrange
var autoShape = (IAutoShape)_fixture.Pre009.Slides[1].Shapes.First(sp => sp.Id == 2);

// Act
var shapeSolidColorName = autoShape.Fill.HexSolidColor;

// Assert
shapeSolidColorName.Should().BeEquivalentTo("ff0000");
}

[Fact]
public async void Picture_GetImageBytes_returns_image()
{
// Arrange
var shape = (IAutoShape)_fixture.Pre009.Slides[2].Shapes.First(sp => sp.Id == 4);

// Act
var imageBytes = await shape.Fill.Picture.BinaryData.ConfigureAwait(false);

// Assert
imageBytes.Length.Should().BePositive();
}
}
1 change: 1 addition & 0 deletions ShapeCrawler/Charts/ICategory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using ShapeCrawler.Shared;
using X = DocumentFormat.OpenXml.Spreadsheet;

// ReSharper disable once CheckNamespace
namespace ShapeCrawler
{
/// <summary>
Expand Down
Loading

0 comments on commit b4265ed

Please sign in to comment.