|
| 1 | +# Fixture Monkey Code Style Guide |
| 2 | + |
| 3 | +This guide outlines the code consistency and style conventions for contributing to the Fixture Monkey project. |
| 4 | +Please follow these rules to reduce code review time and maintain project quality. |
| 5 | + |
| 6 | +## 1. General Principles |
| 7 | + |
| 8 | +* **Language Version**: |
| 9 | + * Java: JDK 8 or higher compatible |
| 10 | + * Kotlin: 1.8 or higher |
| 11 | +* **Encoding**: UTF-8 |
| 12 | +* **Line Ending**: LF (Line Feed) |
| 13 | +* **Indentation**: Use **Tab** (Size: 4) |
| 14 | + * Please configure your IDE to match the `.editorconfig` file included in the project root. |
| 15 | + |
| 16 | +## 2. Naming Conventions |
| 17 | + |
| 18 | +* **Package**: Lowercase, format `com.navercorp.fixturemonkey...` |
| 19 | +* **Class/Interface**: PascalCase (e.g., `MonkeyContext`, `CombinableArbitrary`) |
| 20 | +* **Method/Variable**: camelCase (e.g., `giveMeOne`, `objectBuilder`) |
| 21 | +* **Constant**: UPPER_SNAKE_CASE (e.g., `DEFAULT_MAX_TRIES`) |
| 22 | + |
| 23 | +## 3. Java Coding Rules |
| 24 | + |
| 25 | +### 3.1. Library Dependencies |
| 26 | +* **No Lombok in Production Code**: Do not use Lombok in production code (`src/main/java`). Explicitly write Getters, constructors, etc., or use IDE generation features. |
| 27 | +* **Lombok Allowed in Test Code**: Lombok usage is permitted in test code (`src/test/java`). |
| 28 | + |
| 29 | +### 3.2. API Documentation & Annotations |
| 30 | +* **@API Annotation**: Public APIs must use the `org.apiguardian.api.API` annotation to specify status and introduction version (since). |
| 31 | + ```java |
| 32 | + @API(since = "0.6.0", status = Status.MAINTAINED) |
| 33 | + public interface CombinableArbitrary<T> { ... } |
| 34 | + ``` |
| 35 | +* **Javadoc**: Public classes and methods must have Javadoc explaining their role, parameters, and return values. |
| 36 | + |
| 37 | +### 3.3. Immutability |
| 38 | +* Design objects to be Immutable whenever possible. |
| 39 | +* Actively use the `final` keyword for fields. |
| 40 | + |
| 41 | +## 4. Kotlin Coding Rules |
| 42 | + |
| 43 | +* **Trailing Commas**: It is recommended to use **Trailing Commas** for multi-line parameters or list declarations. |
| 44 | + ```kotlin |
| 45 | + MatchArbitraryIntrospector( |
| 46 | + listOf( |
| 47 | + PrimaryConstructorArbitraryIntrospector.INSTANCE, |
| 48 | + it, // Trailing comma |
| 49 | + ) |
| 50 | + ) |
| 51 | + ``` |
| 52 | +* **Standard Library Usage**: Utilize Kotlin standard library functions (`apply`, `let`, `map`, etc.) appropriately for concise code. |
| 53 | + |
| 54 | +## 5. Test Code Rules |
| 55 | + |
| 56 | +* **Frameworks**: |
| 57 | + * **jqwik**: Mainly used for Property-based testing. Use the `@Property` annotation. |
| 58 | + * **JUnit 5**: Used for general unit testing. |
| 59 | + * **AssertJ**: Used for writing assertions. |
| 60 | +* **Test Naming**: Write test names that clearly indicate the target and intent. |
| 61 | + |
| 62 | +## 6. License Header |
| 63 | + |
| 64 | +All source files (`*.java`, `*.kt`) must include the Apache License 2.0 header at the very top. |
| 65 | + |
| 66 | +```java |
| 67 | +/* |
| 68 | + * Fixture Monkey |
| 69 | + * |
| 70 | + * Copyright (c) 2021-present NAVER Corp. |
| 71 | + * |
| 72 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
| 73 | + * ... |
| 74 | + */ |
| 75 | +``` |
| 76 | + |
| 77 | +--- |
| 78 | + |
| 79 | +## 7. Object Generation Architecture |
| 80 | + |
| 81 | +Understanding the internal object generation flow is crucial for contributing to core logic. |
| 82 | + |
| 83 | +### 7.1. Core Components |
| 84 | +* **FixtureMonkey**: The main entry point. It holds the `MonkeyContext` and creates `ArbitraryBuilder`. |
| 85 | +* **ArbitraryBuilder**: Configures how to generate an object. It accumulates user customizations (manipulators). |
| 86 | +* **ArbitraryResolver**: Resolves the `ArbitraryBuilder` into a `CombinableArbitrary`. It constructs the `ObjectTree`. |
| 87 | +* **ObjectTree**: Represents the structure of the object to be generated. It consists of `ObjectNode`s. |
| 88 | +* **ArbitraryIntrospector**: Determines how to create an instance of a specific type (e.g., Constructor, Bean, Factory method). |
| 89 | + |
| 90 | +### 7.2. Generation Flow |
| 91 | +1. **Initialization**: `FixtureMonkey.create()` initializes options and context. |
| 92 | +2. **Builder Creation**: `fixtureMonkey.giveMeBuilder(Type)` creates a `DefaultArbitraryBuilder` with a `RootProperty`. |
| 93 | +3. **Customization**: Methods like `.set()`, `.size()` add `ArbitraryManipulator`s to the `ArbitraryBuilderContext`. |
| 94 | +4. **Resolution**: Calling `.sample()` triggers `ArbitraryResolver.resolve()`. |
| 95 | + * It creates an `ObjectTree` representing the object structure. |
| 96 | + * It applies all registered `ArbitraryManipulator`s to the `ObjectTree`. |
| 97 | + * It traverses the tree to generate the actual object using `ArbitraryIntrospector`s. |
| 98 | +5. **Generation**: The `ObjectTree` produces the final Java/Kotlin object instance. |
| 99 | + |
| 100 | +### 7.3. Key Concepts |
| 101 | +* **Introspection**: The process of inspecting a class to understand how to instantiate it. |
| 102 | +* **Manipulation**: The process of modifying the generated object or its structure based on user input (path expressions). |
| 103 | +* **Lazy Evaluation**: Objects are not generated until `.sample()` is called, allowing for efficient configuration. |
0 commit comments