Thank you for your interest in contributing to TOON! This document provides guidelines and information to help you contribute effectively.
Be respectful, constructive, and professional in all interactions. We're building something useful together.
- Clojure CLI tools
- Babashka (optional, for faster task execution)
- Git
- A text editor with Clojure support (VS Code + Calva, Emacs + CIDER, IntelliJ + Cursive, etc.)
- Fork and clone the repository:
git clone https://github.com/YOUR_USERNAME/toon.git
cd toon- Run the tests to verify your setup:
bb test # Run Clojure tests
bb test:bb # Run Babashka tests (if applicable)
bb test:all # Run all tests- Try building the library:
bb ci # Run CI pipeline (tests + build)git checkout -b feature/your-feature-nameUse descriptive branch names:
feature/add-streaming-supportfix/encoding-edge-casedocs/improve-api-examplesrefactor/simplify-parser
- Write clear, idiomatic Clojure code
- Follow existing code style and conventions
- Add docstrings to public functions
- Keep functions focused and small
- Use meaningful variable names
Every change must include tests. We use:
- Unit tests: Test individual functions and edge cases
- Property-based tests: Use
test.checkfor roundtrip and invariant testing - Integration tests: Test end-to-end encoding/decoding workflows
Example test structure:
(ns com.vadelabs.toon.feature-test
(:require
[clojure.test :refer [deftest is testing]]
[clojure.test.check.generators :as gen]
[clojure.test.check.properties :as prop]
[clojure.test.check.clojure-test :refer [defspec]]
[com.vadelabs.toon.core :as toon]))
(deftest my-feature-test
(testing "basic functionality"
(is (= expected (my-function input))))
(testing "edge cases"
(is (= edge-expected (my-function edge-input)))))
(defspec my-feature-property-test 100
(prop/for-all [input gen/some-generator]
(= input (roundtrip input))))# Run all tests
bb test
# Run specific test namespace
clojure -X:test :only [com.vadelabs.toon.feature-test]
# Run with coverage (if configured)
bb test:coverageAll tests must pass before submitting a PR.
Use clear, concise commit messages:
git commit -m "add streaming encoder support"
git commit -m "fix quoted string edge case in parser"
git commit -m "improve API documentation with examples"Commit message guidelines:
- Use lowercase, imperative mood
- Keep first line under 50 characters
- Be specific about what changed
- No need for "Co-Authored-By" or emoji
git push origin feature/your-feature-nameThen create a Pull Request on GitHub with:
- Clear title: Summarize the change
- Description: Explain what and why
- Tests: Confirm all tests pass
- Documentation: Update README if needed
- Readability over cleverness: Write code others can understand
- Composition over complexity: Use simple functions that compose well
- Explicit over implicit: Make data flow and dependencies clear
- Test everything: If it can break, test it
- Functions:
kebab-case(e.g.,parse-array-header) - Private functions: Prefix with
-(e.g.,-internal-helper) - Predicates: End with
?(e.g.,empty-array?) - Mutable operations: End with
!(e.g.,append!) - Constants:
kebab-casewithdef(e.g.,default-delimiter)
(ns com.vadelabs.toon.feature
"Brief description of namespace purpose."
(:require
[clojure.string :as str]
[com.vadelabs.toon.utils :as utils]))
;; ============================================================================
;; Constants
;; ============================================================================
(def default-value 42)
;; ============================================================================
;; Helper Functions
;; ============================================================================
(defn- private-helper
"Helper function description."
[arg]
...)
;; ============================================================================
;; Public API
;; ============================================================================
(defn public-function
"Public function with comprehensive docstring.
Parameters:
- arg1: Description of first argument
- arg2: Description of second argument
Returns:
Description of return value
Examples:
(public-function 1 2) ;=> 3"
[arg1 arg2]
...)(defn example-function
"One-line summary of what the function does.
More detailed explanation if needed.
Parameters:
- param1: Description with type info
- param2: Description with type info
- options: Optional map (default: {...})
Returns:
Description of return value
Examples:
(example-function x y)
;=> result"
[param1 param2 & [options]]
...)- Test normal cases and edge cases
- Use descriptive test names
- One assertion per test when possible
- Use
testingblocks for grouping
(deftest parse-array-test
(testing "inline arrays"
(is (= [1 2 3] (parse-array "[3]: 1,2,3"))))
(testing "empty arrays"
(is (= [] (parse-array "[]"))))
(testing "invalid input"
(is (thrown? ExceptionInfo (parse-array "invalid")))))- Use for roundtrip testing
- Test invariants (e.g., encoding + decoding = identity)
- Generate diverse test data
(defspec roundtrip-test 100
(prop/for-all [data gen/json-like]
(= (normalize data)
(-> data encode decode))))Aim for high coverage of:
- All public API functions
- Edge cases (empty input, special characters, large data)
- Error conditions (invalid input, malformed data)
- Platform-specific behavior (CLJ vs CLJS)
Update documentation when you:
- Add new features
- Change public API
- Fix important bugs
- Add new configuration options
- README.md: User-facing features and examples
- Docstrings: Function-level documentation
- CHANGELOG.md: Record all notable changes
- Code comments: Explain complex logic
- Be concise and clear
- Provide examples
- Explain why, not just what
- Keep examples up-to-date
- Ensure all tests pass: Run
bb testlocally - Update documentation: Add examples if needed
- Write clear PR description: Explain what and why
- Request review: Tag maintainers if needed
- Address feedback: Respond to review comments
- Keep commits clean: Squash if needed
- Tests pass locally
- New tests added for new functionality
- Documentation updated
- Code follows style guidelines
- Commit messages are clear
- No unrelated changes included
- Performance optimization: Faster encoding/decoding
- Memory efficiency: Reduce allocations
- Error messages: More helpful error messages
- Examples: Real-world use cases
- ClojureScript support: Browser compatibility
- Streaming: Encode/decode large data incrementally
- Benchmarks: Compare performance vs JSON
- Tooling: Editor plugins, formatters
- Features: Custom type handlers, schema validation
- Interop: Java, JavaScript bindings
- Documentation: Tutorials, guides, videos
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Email: pragyan@vadelabs.com
By contributing to TOON, you agree that your contributions will be licensed under the MIT License.