Skip to content

Commit 778d9cb

Browse files
committed
Add maven wrapper and tests
1 parent b9d6ccb commit 778d9cb

File tree

8 files changed

+866
-56
lines changed

8 files changed

+866
-56
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
wrapperVersion=3.3.4
2+
distributionType=only-script
3+
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip

README.md

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,77 @@
1-
# 🚀 Requirements
1+
# Warehouse Kata – Instructions
22

3-
Add requirements here
3+
Welcome! In this exercise you will implement a small domain around a Warehouse with products. Your goal is to:
4+
- Create and complete several classes/interfaces under src/main/java that are currently missing or partially implemented.
5+
- Pick correct data types for parameters and return values so the project compiles and tests can run.
6+
- Make all tests in BasicTest green first.
7+
- Commit after major steps. When all BasicTest tests are green, push your commits.
8+
- Extra credit: implement the advanced features so that EdgeCaseTest is also green.
9+
10+
## 1) Getting started
11+
1. Open this project in your IDE (IntelliJ IDEA recommended).
12+
2. Ensure you have JDK 25.
13+
3. Build once to see current state:
14+
- ./mvnw compile
15+
16+
## 2) What you will need to create/finish
17+
You will work primarily in src/main/java/com/example. Some files already exist but contain TODOs or empty methods. Implement the following:
18+
19+
- Category (value object)
20+
- Use a private constructor and a public static factory Category.of(String name).
21+
- Validate input: null => "Category name can't be null"; empty/blank => "Category name can't be blank".
22+
- Normalize name with initial capital letter (e.g., "fruit" -> "Fruit").
23+
- Cache/flyweight: return the same instance for the same normalized name.
24+
25+
- Product (abstract base class)
26+
- Keep UUID id, String name, Category category, BigDecimal price.
27+
- Provide getters named uuid(), name(), category(), price() and a setter price(BigDecimal).
28+
- Provide an abstract String productDetails() for polymorphism.
29+
30+
- FoodProduct (extends Product)
31+
- Implements Perishable and Shippable.
32+
- Fields: LocalDate expirationDate, BigDecimal weight (kg).
33+
- Validations: negative price -> IllegalArgumentException("Price cannot be negative."); negative weight -> IllegalArgumentException("Weight cannot be negative.").
34+
- productDetails() should look like: "Food: Milk, Expires: 2025-12-24".
35+
- Shipping rule: cost = weight * 50.
36+
37+
- ElectronicsProduct (extends Product)
38+
- Implements Shippable.
39+
- Fields: int warrantyMonths, BigDecimal weight (kg).
40+
- Validation: negative warranty -> IllegalArgumentException("Warranty months cannot be negative.").
41+
- productDetails() should look like: "Electronics: Laptop, Warranty: 24 months".
42+
- Shipping rule: base 79, add 49 if weight > 5.0 kg.
43+
44+
- Interfaces
45+
- Perishable: expose expirationDate() and a default isExpired() based on LocalDate.now().
46+
- Shippable: expose calculateShippingCost() and weight() (used by shipping optimizer in extra tests).
47+
48+
- Warehouse (singleton per name)
49+
- getInstance(String name) returns the same instance per unique name.
50+
- addProduct(Product): throw IllegalArgumentException("Product cannot be null.") if null.
51+
- getProducts(): return an unmodifiable copy.
52+
- getProductById(UUID): return Optional.
53+
- updateProductPrice(UUID, BigDecimal): when not found, throw NoSuchElementException("Product not found with id: <uuid>"). Also track changed products in getChangedProducts().
54+
- expiredProducts(): return List<Perishable> that are expired.
55+
- shippableProducts(): return List<Shippable> from stored products.
56+
- remove(UUID): remove the matching product if present.
57+
58+
- WarehouseAnalyzer (extra credit)
59+
- Implement the advanced methods used by EdgeCaseTest: price-range search (inclusive), expiring-within-days, case-insensitive name search, above-price search, weighted average per category (round to 2 decimals), price outliers (population stddev), shipping group optimization (first‑fit decreasing by weight), expiration-based discounts, inventory validation summary, and inventory statistics.
60+
61+
## 3) Workflow to follow
62+
1. Implement the missing classes/interfaces and methods so the project compiles.
63+
2. Run tests:
64+
- Basic first: ./mvnw -Dtest=BasicTest test
65+
- When green, commit with a clear message.
66+
3. Extra credit: make EdgeCaseTest green:
67+
- ./mvnw -Dtest=EdgeCaseTest test
68+
4. Commit after each major milestone (e.g., "Implement Product & FoodProduct", "Warehouse behaviors", "Analyzer advanced features").
69+
5. Push when BasicTest is fully green (and EdgeCaseTest too if you do the extra credit).
70+
71+
## 4) Tips
72+
- Prefer BigDecimal for prices and weights (exact values in tests). Where an interface requires Double (e.g., weight()), convert BigDecimal to double on return.
73+
- Always round monetary results to 2 decimals using HALF_UP when tests assert exact values.
74+
- Keep public APIs exactly as tests expect (method names, exception messages).
75+
- Ensure Warehouse.clearProducts() is called in tests; do not share state between tests.
76+
77+
Good luck and have fun!

mvnw

Lines changed: 295 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)