lab03 : Testing and Sorting with Lambdas

num ready? description assigned due
lab03 true Testing and Sorting with Lambdas Fri 08/24 09:30AM Fri 08/31 11:59AM
Midterm Exam E01

NOTE: the deadline is midnight Friday 8/31, but late submissions on Gradescope will be accepted through midnight Monday September 3. If you are not done with lab03, please get done over the three-day weekend. After that, there are no further extensions.

In this lab:

Working in a pair? Switch navigator/driver frequently and tradeoff who commits

If you are in your repo directory, and type git log at the command line, you’ll see a list of the commits for your repo.

Record that you are pairing on each commit message by putting the initials of the pair partners at the start of the commit message.

E.g. If Selena Gomez is driving, and Justin Timberlake is navigating, and you fixed a bug in your getDanceMoves() method, your commit message should be SG/JT fixed bug in getDanceMoves()

We should see frequent switches between SG/JT and JT/SG.

Step-by-Step

Step 0: Set up your repo

You may work individually or as a pair on this lab. However, if you work as a pair, please:

If there is some reason this is not feasible, please check with your mentor before starting.

Create your repo the same way you did for lab01 and lab02

Clone this empty repo into your ~/cs56 directory, or wherever you prefer to work.

The starter code is in https://github.com/ucsb-cs56-m18/STARTER_lab03. Visit that page for the approrpiate URL to add the starter remote.

To add the starter as a remote, cd into the repo you cloned, then do:

git remote add starter https://github.com/ucsb-cs56-m18/STARTER_lab03

Then do:

git pull starter master
git push origin master

That should get you set up with the starter code.

Step 1: Get oriented to using Maven instead of Ant

A few things to notice:

Don’t change the package from pconrad to your name; the autograder is looking for the code under the edu.ucsb.cs56.pconrad.menuitems package. So each source file:

Here are the commands you’ll need as you work with the code. Try them out now.

To do this Type this command
compile the code mvn compile
reset everything mvn clean
run the tests mvn test
generate javadoc mvn javadoc:javadoc site:deploy
generate a report of test coverage mvn test jacoco:report site:deploy
generate a jar file mvn package

Step 2: Set up your github pages site

Try out the mvn site site:deploy command and then do a git add on the docs subdirectory to get that into github.

Then, go to the Settings page for your repo, and turn on github pages on the docs subdirectory of the master branch.

Having that page up and working is part of your grade (one of the manually graded items worth, collectively, 20 points).

You can also set up the test case coverage report there.

You may notice, when you generate the javadoc, that there are some warnings:

[WARNING] Javadoc Warnings
[WARNING] /Users/pconrad/github/cs56/STARTER_lab03/src/main/java/edu/ucsb/cs56/pconrad/menuitem/MenuItem.java:26: warning: no @return
[WARNING] public String getPrice() {
[WARNING] ^
[WARNING] /Users/pconrad/github/cs56/STARTER_lab03/src/main/java/edu/ucsb/cs56/pconrad/menuitem/MenuItem.java:41: warning: no @return
[WARNING] public String getPrice(int width) {
[WARNING] ^

By looking at the other examples of Javadoc, and reading about how to write correct Javadoc online, you should be able to figure out how to remove these warnings. We’ll check for that when we do the “manual grading” part of the assignment.

Step 3: Start writing code.

In this lab, you’ll be implementing several methods of two classes that represent a restaurant Menu, composed of MenuItems.

A MenuItem represents an item on the menu of a restaurant. It has three attributes:

A Menu is simply an encapsulated list of MenuItems. What Menu adds over ArrayList is the ability to sort the menu in various ways that might be useful in producing formatted menus.

Note that the starter code:

So you’ll need to do a bit more work than you may be used to.

I suggest that you work in this order:

I suggest getting the toString() of the MenuItem class to work before trying the csv() method of Menu or any of the extended versions of that method that require sorting.

Details about methods of MenuItem

The constructor has the signature:

public MenuItem(String name,
                int priceInCents,
                String category)

Here are the instance methods you’ll need to implement for MenuItem

Modifier and Type Method Description
String getCategory() Returns the category of the menu item
String getName() Returns the name of the menu item
String getPrice() Returns the price, formatted as a string with a $.
String getPrice(int width) Returns the price, formatted as a string with a $, right justified in a field with the specified width.
int getPriceInCents() get the price in cents only
String toString() return a string in csv format, in the order name,price,cateogry.
For example: "Small Poke Bowl,1049,Poke Bowls"
In this case, the price is unformatted; just an integer number of cents.

There is also a class Menu, which wraps an ArrayList<MenuItem>.

The constructor takes no arguments, and simply initializes an empty ArrayList. (It is given in the starter code.)

Details about methods of Menu

The methods for Menu are as follows:

Modifier and Type Method Description
void add(MenuItem mi) add a menu item to the menu (to the wrapped ArrayList)  
String csv() Produce a listing of each item in csv format, with newlines between each item. Order is whatever order the items are currently in the ArrayList
String csvSortedByName() same as csv(), but the items should be sorted in lexicographic order by name.
String csvSortedByCategoryThenName() same as csv(), but the items should be sorted by category. With the same category, the items should be sorted by name.
String csvSortedByCategoryThenPriceDescendingThenByName() same as csv(), but the items should be sorted by category. With the same category, the items should be sorted by name.
String csvSortedByPriceThenName()  

When all your tests pass

Some of the points in the manual inspection may be awarded on the basis of having good test coverage. While 100% test coverage is not always the goal, in this particular exercise, it should be possible. So if you see that you don’t have 100% test coverage, go back and write some additional unit tests.

How to read the test coverage reports

An important point about academic honesty

Yes, I am aware that it is possible to “cheat” on this lab by looking at the jacoco reports of other students and pairs to access their source code. Even though the repos are private, the jacoco test coverage reports are public, and you can browse the source code. I strongly encourage you to NOT do that.

Ultimately, I’d like to find a way to easily obtain test coverage reports without leaking the source code. But in the meantime, I’m simply relying on your sense of ethics and honor to NOT LOOK. I decided the educational value of introducing test-coverage outweighed the risk from potential academic dishonesty.

If you do copy code from other students by looking at their test coverage report, it will be pretty obvious. And, the biggest problem is that you’ll miss the learning opportunity in this assignment, which will help you prepare for the exam next Thursday.

End of description for lab03

Appendix–Troubleshooting tips

If you run into problems with the mvn test step, especially if you are using Java 10 on Mac OS, and you see the following, there is a suggested fix.

Here’s what the problem looks like with Mac OS and using Java 10.
The fix is simple, and comes after the scary output.

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Exception in thread "main" java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
	at java.instrument/sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:510)
	at java.instrument/sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:522)
Caused by: java.lang.RuntimeException: Class java/util/UUID could not be instrumented.
	at org.jacoco.agent.rt.internal_6da5971.core.runtime.ModifiedSystemClassRuntime.createFor(ModifiedSystemClassRuntime.java:140)
	at org.jacoco.agent.rt.internal_6da5971.core.runtime.ModifiedSystemClassRuntime.createFor(ModifiedSystemClassRuntime.java:101)
	at org.jacoco.agent.rt.internal_6da5971.PreMain.createRuntime(PreMain.java:55)
	at org.jacoco.agent.rt.internal_6da5971.PreMain.premain(PreMain.java:47)
	... 6 more
Caused by: java.lang.NoSuchFieldException: $jacocoAccess
	at java.base/java.lang.Class.getField(Class.java:1958)
	at org.jacoco.agent.rt.internal_6da5971.core.runtime.ModifiedSystemClassRuntime.createFor(ModifiedSystemClassRuntime.java:138)
	... 9 more
FATAL ERROR in native method: processing of -javaagent failed
/bin/sh: line 1: 57799 Abort trap: 6           
/Library/Java/JavaVirtualMachines/jdk-10.0.2.jdk/Contents/Home/bin/java -javaagent:/Users/pconrad/.m2/repository/org/jacoco/org.jacoco.agent/0.7.7.201606060606/org.jacoco.agent-0.7.7.201606060606-
...
Results :

Tests run: 0, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.503 s
[INFO] Finished at: 2018-08-29T12:54:43-07:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test (default-test) on project menuitem: Execution default-test of goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test failed: The forked VM terminated without saying properly goodbye. VM crash or System.exit called ? -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException

The fix is simply to go into the pom.xml and make these changes:

Change #1:

Before: ``` org.jacoco jacoco-maven-plugin 0.8.0


After: change the version to `0.8.2`:

<dependency>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.2</version>
</dependency>  ```

Change #2:

Before:

<!-- Test case coverage report -->
      <plugin>
	<groupId>org.jacoco</groupId>
	<artifactId>jacoco-maven-plugin</artifactId>
	<version>0.7.7.201606060606</version>
	...

After (change version to 0.8.2):

<!-- Test case coverage report --> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.2</version>