Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
namespace CommunityToolkit.Maui.Core;

/// <summary>
/// Default Values for RatingView
/// </summary>
public static class RatingViewDefaults
{
/// <summary>
/// Default value for <see cref="CurrentRating"/>
/// </summary>
public const int CurrentRating = 0;

/// <summary>
/// Default value for <see cref="MaximumRating"/>
/// </summary>
public const int MaximumRating = 5;

/// <summary>
/// Default value for <see cref="Size"/>
/// </summary>
public const double Size = 20.0;

/// <summary>
/// Default value for <see cref="Spacing"/>
/// </summary>
public const double Spacing = 10.0;

/// <summary>
/// Default value for <see cref="StrokeThickness"/>
/// </summary>
public const double StrokeThickness = 7.0;

/// <summary>
/// Default value for <see cref="IsEnabled"/>
/// </summary>
public const bool IsEnabled = true;

/// <summary>
/// Default value for <see cref="FilledBackgroundColor"/>
/// </summary>
public static Color FilledBackgroundColor { get; } = Colors.Yellow;

/// <summary>
/// Default value for <see cref="EmptyBackgroundColor"/>
/// </summary>
public static Color EmptyBackgroundColor { get; } = Colors.Transparent;

/// <summary>
/// Default value for <see cref="StrokeColor"/>
/// </summary>
public static Color StrokeColor { get; } = Colors.Grey;
}
11 changes: 11 additions & 0 deletions src/CommunityToolkit.Maui.Core/Primitives/Rating.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace CommunityToolkit.Maui.Core.Primitives;

///<summary></summary>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder to add descriptive XML Comments

public class Rating
{
///<summary></summary>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder to add descriptive XML Comments

public double? CurrentRating { get; set; }

///<summary></summary>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder to add descriptive XML Comments

public object? CommandParameter { get; set; }
}
49 changes: 49 additions & 0 deletions src/CommunityToolkit.Maui.Core/Primitives/RatingShape.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
namespace CommunityToolkit.Maui.Core.Primitives;

/// <summary>
/// The type of the shape to display on the rating view
/// </summary>
public readonly struct RatingShape(string pathData)
{
/// <summary>
/// the data path data from the svg
/// </summary>
public string PathData { get; } = pathData;

/// <summary>
/// the default star shape
/// </summary>
public static RatingShape Star { get; } = new(PathShapes.Star);

/// <summary>
/// The default heart shape
/// </summary>
public static RatingShape Heart { get; } = new(PathShapes.Heart);

/// <summary>
/// The circle shape
/// </summary>
public static RatingShape Circle { get; } = new(PathShapes.Circle);

/// <summary>
/// The Like shapes
/// </summary>
public static RatingShape Like { get; } = new(PathShapes.Like);

/// <summary>
/// The Dislike
/// </summary>
public static RatingShape Dislike { get; } = new(PathShapes.Dislike);
}

/// <summary>
///
/// </summary>
static class PathShapes
{
public const string Star = "M9 11.3l3.71 2.7-1.42-4.36L15 7h-4.55L9 2.5 7.55 7H3l3.71 2.64L5.29 14z";
public const string Heart = "M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z";
public const string Circle = "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z";
public const string Like = "M1 21h4V9H1v12zm22-11c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-1.91l-.01-.01L23 10z";
public const string Dislike = "M15 3H6c-.83 0-1.54.5-1.84 1.22l-3.02 7.05c-.09.23-.14.47-.14.73v1.91l.01.01L1 14c0 1.1.9 2 2 2h6.31l-.95 4.57-.03.32c0 .41.17.79.44 1.06L9.83 23l6.59-6.59c.36-.36.58-.86.58-1.41V5c0-1.1-.9-2-2-2zm4 0v12h4V3h-4z";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
using CommunityToolkit.Maui.Core;
using CommunityToolkit.Maui.Core.Primitives;
using CommunityToolkit.Maui.Core.Primitives.Defaults;
using FluentAssertions;
using Microsoft.Maui.Controls.Shapes;
using Xunit;
using Path = Microsoft.Maui.Controls.Shapes.Path;

namespace CommunityToolkit.Maui.UnitTests.Views.RatingView;

public class RatingViewTests : BaseHandlerTest
{
[Fact]
public void DefaultInitialization_ShouldHaveCorrectDefaultValues()
{
// Arrange
var ratingView = new Maui.Views.RatingView.RatingView();

// Assert
Assert.Equal(RatingViewDefaults.CurrentRating, ratingView.CurrentRating);
Assert.Equal(RatingViewDefaults.MaximumRating, ratingView.MaximumRating);
Assert.Equal(RatingViewDefaults.Size, ratingView.Size);
Assert.Equal(RatingViewDefaults.FilledBackgroundColor, ratingView.FilledBackgroundColor);
Assert.Equal(RatingViewDefaults.EmptyBackgroundColor, ratingView.EmptyBackgroundColor);
Assert.Equal(RatingViewDefaults.StrokeThickness, ratingView.StrokeThickness);
Assert.Equal(RatingViewDefaults.Spacing, ratingView.Spacing);
Assert.Equal(RatingViewDefaults.IsEnabled, ratingView.IsEnabled);
}

[Fact]
public void OnControlInitialized_ShouldCreateCorrectNumberOfShapes()
{
// Arrange
var ratingView = new Maui.Views.RatingView.RatingView();
ratingView.MaximumRating = 3;

// Act
ratingView.InitializeShape();

// Assert
ratingView.Control?.ColumnDefinitions.Count.Should().Be(3);
ratingView.Control?.Children.Count.Should().Be(3);
}

[Fact]
public void PropertyChangedEvent_ShouldBeRaised_WhenCurrentRatingChanges()
{
// Arrange
var ratingView = new Maui.Views.RatingView.RatingView();
bool eventRaised = false;
ratingView.PropertyChanged += (_, e) => { eventRaised = true; };

// Act
ratingView.CurrentRating = 3.5;

// Assert
eventRaised.Should().BeTrue();
}

[Fact]
public void Draw_ShouldCreateCorrectNumberOfShapes()
{
// Arrange
var ratingView = new Maui.Views.RatingView.RatingView
{
MaximumRating = 3
};

// Assert
ratingView.Control?.ColumnDefinitions.Count.Should().Be(3);
ratingView.Control?.Children.Count.Should().Be(3);
}

[Fact]
public void ReDraw_ShouldRecreateShapes()
{
// Arrange
var ratingView = new Maui.Views.RatingView.RatingView
{
MaximumRating = 3
};

// Act
ratingView.ReDraw();

// Assert
ratingView.Control?.ColumnDefinitions.Count.Should().Be(3);
ratingView.Control?.Children.Count.Should().Be(3);
}

[Fact]
public void UpdateDraw_ShouldUpdateShapesCorrectly()
{
// Arrange
var ratingView = new Maui.Views.RatingView.RatingView
{
MaximumRating = 3,
CurrentRating = 2.5
};

// Act
ratingView.UpdateDraw();

// Assert
ratingView.Control?.Children.Count.Should().Be(3);
#pragma warning disable CS8602 // Dereference of a possibly null reference.
(ratingView.Control?.Children[0] as Path).Fill.Should()
.BeEquivalentTo(Brush.Yellow);
(ratingView.Control?.Children[0] as Path).Stroke.Should()
.BeEquivalentTo(Brush.Yellow);
#pragma warning restore CS8602 // Dereference of a possibly null reference.
}

[Fact]
public void InitializeShape_ShouldSetShapeAndControlColumnSpacing()
{
// Arrange
var ratingView = new Maui.Views.RatingView.RatingView();

// Act
ratingView.InitializeShape();

// Assert
ratingView.Shape.Should().NotBeNull();
ratingView.Control?.ColumnSpacing.Should().Be(ratingView.Spacing);
}

[Fact]
public void OnShapeTapped_ShouldUpdateCurrentRatingCorrectly()
{
// Arrange
var ratingView = new Maui.Views.RatingView.RatingView
{
MaximumRating = 3,
IsEnabled = true
};

Path tappedShape = new()
{
Data = (Geometry?)new PathGeometryConverter().ConvertFromInvariantString(RatingShape.Star.PathData)
};

// Act
ratingView.OnShapeTapped(tappedShape, null);

// Assert
ratingView.CurrentRating.Should().Be(1);
}

[Fact]
public void ShapeProperty_ShouldSetShapeCorrectly()
{
// Arrange
var ratingView = new Maui.Views.RatingView.RatingView();

// Act
ratingView.Shape = RatingShape.Heart;

// Assert
ratingView.Shape.Should().Be(RatingShape.Heart);
}
}
4 changes: 2 additions & 2 deletions src/CommunityToolkit.Maui/CommunityToolkit.Maui.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiPackageVersion)"/>
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="$(MauiPackageVersion)"/>
<PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiPackageVersion)" />
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="$(MauiPackageVersion)" />
</ItemGroup>

</Project>
Loading