Here is the Deck.java file, I know for sure the error is here.
import java.util.List;
import java.util.ArrayList;
/**
 * The Deck class represents a shuffled deck of cards.
 * It provides several operations including
 *      initialize, shuffle, deal, and check if empty.
 */
public class Deck {
    /**
     * cards contains all the cards in the deck.
     */
    private List<Card> cards;
    /**
     * size is the number of not-yet-dealt cards.
     * Cards are dealt from the top (highest index) down.
     * The next card to be dealt is at size - 1.
     */
    private int size;
    /**
     * Creates a new <code>Deck</code> instance.<BR>
     * It pairs each element of ranks with each element of suits,
     * and produces one of the corresponding card.
     * @param ranks is an array containing all of the card ranks.
     * @param suits is an array containing all of the card suits.
     * @param values is an array containing all of the card point values.
     */
    public Deck(String[] ranks, String[] suits, int[] values) {
        cards = new ArrayList<Card>();
        for (int j = 1; j < ranks.length; j++) {
            for (String suitString : suits) {
                cards.add(new Card(ranks[j], suitString, values[j]));
            }
        }
        shuffle();
    }
    /**
     * Determines if this deck is empty (no undealt cards).
     * @return true if this deck is empty, false otherwise.
     */
    public boolean isEmpty() {
        return size < 0;
    }
    /**
     * Accesses the number of undealt cards in this deck.
     * @return the number of undealt cards in this deck.
     */
    public int size() {
        return size;
    }
    /**
     * Randomly permute the given collection of cards
     * and reset the size to represent the entire deck.
     */
    public void shuffle() {
        for (int k = cards.size() - 1; k >= 0; k--) {
            int howMany = k + 1;
            int start = 0;
            int randPos = (int) (Math.random() * howMany) + start;
            Card temp = cards.get(k);
            cards.set(k, cards.get(randPos));
            cards.set(randPos, temp);
        }
        size = cards.size();
    }
    /**
     * Deals a card from this deck.
     * @return the card just dealt, or null if all the cards have been
     *         previously dealt.
     */
    public Card deal() {
        size--;
        if (isEmpty()) {
            return null;
        }
        Card c = cards.get(size);
        return c;
    }
    /**
     * Generates and returns a string representation of this deck.
     * @return a string representation of this deck.
     */
    @Override
    public String toString() {
        String rtn = "size = " + size + "\nUndealt cards: \n";
        for (int k = size - 1; k >= 0; k--) {
            rtn = rtn + cards.get(k);
            if (k != 0) {
                rtn = rtn + ", ";
            }
            if ((size - k) % 2 == 0) {
                // Insert carriage returns so entire deck is visible on console.
                rtn = rtn + "\n";
            }
        }
        rtn = rtn + "\nDealt cards: \n";
        for (int k = cards.size() - 1; k >= size; k--) {
            rtn = rtn + cards.get(k);
            if (k != size) {
                rtn = rtn + ", ";
            }
            if ((k - cards.size()) % 2 == 0) {
                // Insert carriage returns so entire deck is visible on console.
                rtn = rtn + "\n";
            }
        }
        rtn = rtn + "\n";
        return rtn;
    }
}
Here is the runner code. This is where I get the error: "Exception in thread "main" java.lang.NullPointerException at DeckTester.testShuffle(DeckTester.java:137) at DeckTester.main(DeckTester.java:15)" Ill comment the line number next to the lines affected.
 * This is a class that tests the Deck class using assert statements.
 */
public class DeckTester {
    /**
     * The main method in this class checks the Deck operations for consistency
     * using assert statements.
     *  @param args is not used.
     */
   public static void main(String[] args) {
   test2CardDeck();
      test1CardDeck();
      testShuffle(); //Line 15
      System.out.println("All tests passed!");
   }
    /**
     * Create a 1-card Deck and test the Deck methods with it.
     */
   private static void test1CardDeck() {
      String[] r1 = {"ace"};
      String[] s1 = {"spades"};
      int[] v1 = {1};
      Deck d = new Deck(r1, s1, v1);
      testOneCard(d, new Card("ace", "spades", 1));
      testEmpty(d);
      d.shuffle();
      testOneCard(d, new Card("ace", "spades", 1));
      testEmpty(d);
   }
    /**
     * Create a 2-card Deck and test the Deck methods with it.
     */
   private static void test2CardDeck() {
      String[] r2 = {"ace", "2"};
      String[] s2 = {"hearts"};
      int[] v2 = {1, 2};
      Deck d = new Deck(r2, s2, v2);
      assert d.size() == 2 : "Initial size is " + d.size()
         + ". It should be 2.";
      assert !d.isEmpty() : "Initial deck is empty.";
      boolean aceIsFirst, twoIsFirst;
      Card c = d.deal();
      assert c != null : "1st card dealt is null.";
      aceIsFirst = c.matches(new Card("ace", "hearts", 1));
      twoIsFirst = c.matches(new Card("2", "hearts", 2));
      assert (aceIsFirst || twoIsFirst) : "1st card dealt is " + c
         + ".  It is not the one of the two correct cards.";
      assert d.size() == 1 : "Size after one deal is " + d.size()
         + ". It should be 1.";
      assert !d.isEmpty() : "Deck is empty after one deal.";
      c = d.deal();
      assert c != null : "2nd card dealt is null.";
      if (aceIsFirst) {
         assert c.matches(new Card("2", "hearts", 2))   : "2nd card dealt is "
            + c + ". It is not one of the two correct cards.";
      } else {
         assert c.matches(new Card("ace", "hearts", 1)) : "2nd card dealt is "
            + c + ". It is not one of the two correct cards.";
      }
      testEmpty(d);
      d.shuffle();
      c = d.deal();
      assert c != null : "1st card dealt after shuffle is null.";
      aceIsFirst = c.matches(new Card("ace", "hearts", 1));
      twoIsFirst = c.matches(new Card("2", "hearts", 2));
      assert (aceIsFirst || twoIsFirst) : "1st card dealt after shuffle is "
         + c + ".  It is not the one of the two correct cards.";
      assert d.size() == 1 : "Size is " + d.size()
         + "after shuffle and one deal. It should be 1.";
      assert !d.isEmpty() : "Deck is empty after shuffle and one deal.";
      c = d.deal();
      assert c != null : "2nd card dealt after shuffle is null.";
      if (aceIsFirst) {
         assert c.matches(new Card("2", "hearts", 2))
            : "2nd card dealt after shuffle is " + c
            + ". It is not the one of the two correct cards.";
      } else {
         assert c.matches(new Card("ace", "hearts", 1))
            : "2nd card dealt after shuffle is " + c
            + ". It is not the one of the two correct cards.";
      }
      testEmpty(d);
   }
    /**
     * Check that the given deck is empty.
     * @param d is a deck that should be empty.
     */
   private static void testEmpty(Deck d) {
      assert d.size() == 0 :  "Size for an empty deck is " + d.size()
         + ". It should be 0.";
      assert d.isEmpty() : "isEmpty is false for an empty deck.";
      Card c = d.deal();
      assert c == null : "Dealt card is " + c
         + ". It should be null for an empty deck.";
   }
    /**
     * Check that the given deck contains the given card and nothing else.
     * @param d is a deck that should contain a single card.
     * @param intended is the card that the one-card deck should contain.
     */
   private static void testOneCard(Deck d, Card intended) {
      assert d.size() == 1 : "Size is " + d.size()
         + ". It should be 1 for a 1-card deck.";
      assert !d.isEmpty() : "isEmpty true for a 1-card deck.";
      Card c = d.deal();
      assert c != null : "1st dealt card is null for a 1-card deck.";
      assert c.matches(intended) : "1st card dealt for a 1-card deck is "
         + c + ". It should be " + intended + ".";
   }
    /**
     * Check that two decks constructed in succession aren't the same.
     */
   private static void testShuffle() {
      String[] r = {"ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "jack", "queen", "king"};
      String[] s = {"spades", "hearts", "diamonds", "clubs"};
      int[] v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
      Deck d1 = new Deck(r, s, v);
      Deck d2 = new Deck(r, s, v);
      assert d1 != d2 : "Decks d1 and d2 are the same physical object.";
      assert d1.size() == d2.size() : "Deck d1 size of " + d1.size()
         + " does not match deck d2 size of " + d2.size() + ".";
      boolean allMatch = true;
      while (!d1.isEmpty()) {
         Card c1 = d1.deal();
         Card c2 = d2.deal();
         if (c1.matches(c2)) { //Line 137
            allMatch = false;
         }
      }
      assert !allMatch : "The sequence of cards in d1 and d2 are identical.";
   }
}``` 
