Milestone 4 Requirements

Web Only

This textbook was authored for the CIS 400 - Object-Oriented Design, Implementation, and Testing course at Kansas State University. This section describes assignments specific to the Spring 2023 offering of that course. Prior semester offerings can be found here. If you are not enrolled in the course, please disregard this section.

For this milestone, you will be creating new classes representing an order and refactoring your existing classes to implement an interface and base classes. You will also need to update your unit tests to account for these changes. Finally, you will also create a UML class diagram to represent your classes.

General requirements:

  • You need to follow the style laid out in the C# Coding Conventions

  • You need to document your code using XML-style comments, with a minimum of <summary> tags, plus <param>, <returns>, and <exception> as appropriate.

Assignment requirements:

You will need to:

  • Create an IMenuItem interface to represent an item appearing on the menu

  • Refactor your existing classes to implement the IMenuItem interface

  • Add additional unit tests to verify your menu items can be treated as IMenuItem instances

  • Create an Order class to represent a collection of menu items being ordered together

  • Write unit tests to verify your new classes work as expected

  • Create a UML diagram for your Data Project

Purpose:

This milestone serves to introduce and utilize aspects of polymorphism including base classes, abstract base classes, abstract methods, virtual methods, method overriding, and interfaces. While the actual programming involved is straightforward, the concepts involved can be challenging to master. If you have any confusion after you have read the entire assignment please do not hesitate to reach out to a Professor Bean, the TAs, or your classmates over Discord.

IMenuItem Interface

You will create an interface named IMenuItem in the file IMenuItem.cs to represent the properties that all menu items share, which should include:

  • A get-only Name property of type string
  • A get-only Description property of type string
  • A get-only Price property of type decimal
  • A get-only Calories property of type uint
  • A get-only SpecialInstructions property of type IEnumerable<string>

You will need to implement this interface on all existing and future menu items defined in the Data project.

You will also want to test that your menu items can be cast to be an IMenuItem using the Assert.IsAssignableFrom<T>() assertion in the corresponding unit test file with a new Fact.

Abstract Base Classes

You will also write abstract base classes representing Entree, Side, and Drink menu items, in files named Entree.cs, Side.cs, and Drink.cs respectively. These should generalize (collect together) the properties that each of these categories of menu items have in common - either as abstract or virtual properties, to be overridden as needed in the derived classes.

All of your menu classes should be refactored to derive from one of these abstract base classes. Note that this may allow you to remove methods or require you to override the base method.

You will also want to test that your menu items can be cast to be the corresponding base class using the Assert.IsAssignableFrom<T>() assertion in the corresponding unit test file with a new Fact.

Drink Classes

You will also need to implement new classes representing the drinks available at The Flying Saucer, which are Liquified Vegetation, Saucer Fuel, and Inorganic Substance. All drinks have a Size property of type ServingSize, in addition to the normal IMenuItem properties.

Liquified Vegetation

Property Accessors Type Value
Name get only string "Liquified Vegetation"
Description get only string "A cold glass of blended vegetable juice."
Size get and set ServingSize Default of `ServingSize.Small`
Ice get and set bool Defaults to true
Price get only decimal $1.00 for small, $1.50 for medium, $2.00 for large
Calories get only uint 72 for small, 144 for medium, 216 for large
SpecialInstructions get only IEnumerable⟨string⟩ Should include:
  • "No Ice" if Ice is false

Saucer Fuel

Property Accessors Type Value
Name get only string "Saucer Fuel" or "Decaf Saucer Fuel" if Decaf is true
Description get only string "A steaming cup of coffee."
Size get and set ServingSize Default of `ServingSize.Small`
Decaf get and set bool Defaults to false
Cream get and set bool Defaults to false
Price get only decimal $1.00 for small, $1.50 for medium, $2.00 for large
Calories get only uint 1 for small, 2 for medium, 3 for large, plus 29 calories for cream
SpecialInstructions get only IEnumerable⟨string⟩ Should include:
  • "With Cream" if Cream is true

Inorganic Substance

Property Accessors Type Value
Name get only string "Inorganic Substance"
Description get only string "A cold glass of ice water."
Size get and set ServingSize Default of `ServingSize.Small`
Ice get and set bool Defaults to true
Price get only decimal $0.00 for any size
Calories get only uint 0 for all sizes
SpecialInstructions get only IEnumerable⟨string⟩ Should include:
  • "No Ice" if Ice is false

Order Class

You will also need to create a class, Order in a file Order.cs, representing an order containing multiple, potentially customized menu items. This class will need to implement the ICollection<IMenuItem> interface, allowing it to be treated as a collection. In addition to the methods and properties required for the interface, it should have the additional properties of:

  • Subtotal, a get-only decimal that is the price of all items in the order
  • TaxRate, a get/set decimal that represents the sales tax rate
  • Tax, a get-only decimal that is the tax for the order (Subtotal * TaxRate)
  • Total, a get-only decimal that is the sum of the Subtotal and Tax

Add Tests

Remember that your new classes (Order and all the drinks) will all need to have corresponding unit tests added to the DataTests project. Abstract classes Entree, Side, and Drink do not need to be tested, but any properties or methods inherited from them should be tested in the unit tests of the derived classes.

Note that for testing the Order class, you will want to use a mock object rather than your real menu item classes. This can be declared in the unit test class like this:

/// <summary>
/// A mock menu item for testing
/// </summary>
internal MockMenuItem : IMenuItem 
{
  public string Name {get; set;}
  public string Description {get; set;}
  public decimal Price {get; set;}
  public uint Calories {get; set;}
  public IEnumerable<string> SpecialInstructions {get;set;}
}

This allows you to initialize it with known values in a test, i.e. we might initialize four menu items with prices to test the Subtotal property:

[fact]
public SubtotalShouldReflectItemPrices()
{ 
  Order order = new Order();
  order.Add(new MockMenuItem() {Price = 1.00m});
  order.Add(new MockMenuItem() {Price = 2.50m});
  order.Add(new MockMenuItem() {Price = 3.00m});
  Assert.Equal(6.50m, order.Subtotal);
}

UML Class Diagram

Finally, you will need to create a UML class diagram for the Data project, and add it to your repository. This can be done with Visio or another visual editing program like Draw.io or Lucid Charts. You should save the diagram in a PDF or image format that the graders can view. You also will want to keep it in an editable format, as you’ll be updating it in future milestones. Be sure to follow the instructions in [Adding Documentation Files]https://textbooks.cs.ksu.edu/cis400/b-git-and-github/12-adding-documentation-files/ and double-check that the UML diagrams appear in your release.

Submitting the Assignment

Once your project is complete, merge your feature branch back into the main branch and create a release tagged v0.4.0 with name "Milestone 4". Copy the URL for the release page and submit it to the Canvas assignment.

Grading Rubric

The grading rubric for this assignment will be:

20% Structure Did you implement the structure as laid out in the specification? Are the correct names used for classes, enums, properties, methods, events, etc? Do classes inherit from expected base classes?

20% Documentation Does every class, method, property, and field use the correct XML-style documentation? Does every XML comment tag contain explanatory text? Is there a UML Diagram for the data project? Does the UML accurately reflect the structure of the project

20% Design Are you appropriately using C# to create reasonably efficient, secure, and usable software? Does your code contain bugs that will cause issues at runtime?

20% Functionality Does the program do what the assignment asks? Do properties return the expected values? Do methods perform the expected actions?

20% Tests Does the test suite include unit tests for all classes? Do the unit tests provide adequate coverage of the project?

Warning

Projects that do not compile will receive an automatic grade of 0.