Contributing to FakeDataDSL

Thank you for your interest in contributing to FakeDataDSL! This document provides guidelines and information for contributors.

Table of Contents

Code of Conduct

This project adheres to a Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to the maintainers.

Getting Started

  1. Fork the repository on GitHub
  2. Clone your fork locally: bash git clone https://github.com/YOUR_USERNAME/fake_data_dsl.git cd fake_data_dsl
  3. Add the upstream remote: bash git remote add upstream https://github.com/talaatmagdyx/fake_data_dsl.git

Development Setup

Prerequisites

  • Ruby 3.1.0 or higher
  • Bundler 2.0+

Installation

# Install dependencies
bundle install

# Run tests to verify setup
bundle exec rspec

# Run linter
bundle exec rubocop

Running the CLI locally

# From the project root
bundle exec exe/fake_data_dsl --help

How to Contribute

Reporting Bugs

Before creating a bug report:

  1. Check the existing issues
  2. Ensure you're using the latest version
  3. Collect information about the bug:
    • Stack trace
    • Ruby version (ruby --version)
    • Gem version (bundle show fake_data_dsl)
    • Your operating system
    • Steps to reproduce

Suggesting Enhancements

Enhancement suggestions are tracked as GitHub issues. When creating an enhancement suggestion, include:

  • A clear and descriptive title
  • A detailed description of the proposed functionality
  • Examples of how the feature would be used
  • Why this enhancement would be useful

Adding New Types

To add a new data type:

  1. Create a new file in lib/fake_data_dsl/types/ in the appropriate domain folder
  2. Inherit from FakeDataDSL::Types::Base
  3. Implement generate_random, generate_edge, and generate_invalid methods
  4. Register the type in lib/fake_data_dsl.rb in register_builtin_types!
  5. Add tests in spec/types/
  6. Document in tech_docs/dsl/core_types.md

Example:

# lib/fake_data_dsl/types/personal_names/nickname.rb
module FakeDataDSL
  module Types
    module PersonalNames
      class Nickname < Base
        def generate_random(rng, context, args)
          rng.element(["Ace", "Buddy", "Chief", "Duke", "Flash"])
        end

        def generate_edge(rng, context, args)
          rng.element(["", "X", "A" * 100])
        end

        def generate_invalid(rng, context, args)
          rng.element([nil, 123, [], {}])
        end
      end
    end
  end
end

Adding New Behaviors

To add a new behavior:

  1. Create a new file in lib/fake_data_dsl/behaviors/
  2. Inherit from FakeDataDSL::Behaviors::Base
  3. Implement the apply method
  4. Register in lib/fake_data_dsl/behaviors/registry.rb
  5. Add tests and documentation

Adding New Export Formats

To add a new export format:

  1. Create a new file in lib/fake_data_dsl/export/
  2. Inherit from FakeDataDSL::Export::Base
  3. Implement export and optionally export_all methods
  4. Register in lib/fake_data_dsl/export.rb
  5. Add CLI support in lib/fake_data_dsl/cli.rb if needed
  6. Add tests and documentation

Pull Request Process

  1. Create a new branch from main:

    git checkout -b feature/my-new-feature
    
  2. Make your changes and commit:

    git add .
    git commit -m "feat: add new feature X"
    
  3. Follow the Conventional Commits specification:

    • feat: - New features
    • fix: - Bug fixes
    • docs: - Documentation changes
    • style: - Code style changes (formatting, etc.)
    • refactor: - Code refactoring
    • test: - Adding or updating tests
    • chore: - Maintenance tasks
  4. Ensure all tests pass:

    bundle exec rspec
    
  5. Ensure code style compliance:

    bundle exec rubocop
    
  6. Update documentation if needed

  7. Push your branch and create a Pull Request

PR Requirements

  • [ ] Tests pass
  • [ ] RuboCop passes
  • [ ] New code has test coverage
  • [ ] Documentation updated (if applicable)
  • [ ] CHANGELOG.md updated (for user-facing changes)

Code Style

We follow the Ruby Style Guide with some customizations. RuboCop is configured to enforce these rules.

Key Guidelines

  • Use 2 spaces for indentation
  • Use frozen_string_literal pragma
  • Maximum line length: 120 characters
  • Document public methods with YARD
  • Prefer explicit over implicit
  • Keep methods small and focused

Example

# frozen_string_literal: true

module FakeDataDSL
  module Example
    # Generate a random example value
    #
    # @param count [Integer] number of values to generate
    # @return [Array<String>] generated values
    #
    # @example
    #   generate_examples(3)
    #   # => ["example1", "example2", "example3"]
    #
    def generate_examples(count)
      count.times.map { |i| "example#{i + 1}" }
    end
  end
end

Testing Guidelines

Running Tests

# Run all tests
bundle exec rspec

# Run specific file
bundle exec rspec spec/types/core_types_spec.rb

# Run with coverage
bundle exec rspec --coverage

Writing Tests

  • Place tests in spec/ mirroring the lib/ structure
  • Use descriptive describe and it blocks
  • Test edge cases and error conditions
  • Use factories or fixtures for complex data

Example Test

# frozen_string_literal: true

RSpec.describe FakeDataDSL::Types::PersonalNames::Nickname do
  subject(:generator) { described_class.new }

  describe "#generate_random" do
    it "returns a string" do
      result = generator.generate_random(rng, context, {})
      expect(result).to be_a(String)
    end

    it "returns consistent results with same seed" do
      rng1 = FakeDataDSL::Generator::RNG.new(42)
      rng2 = FakeDataDSL::Generator::RNG.new(42)

      result1 = generator.generate_random(rng1, context, {})
      result2 = generator.generate_random(rng2, context, {})

      expect(result1).to eq(result2)
    end
  end

  describe "#generate_edge" do
    it "returns edge case values" do
      result = generator.generate_edge(rng, context, {})
      expect(result).to satisfy { |v| v.empty? || v.length == 1 || v.length >= 100 }
    end
  end
end

Documentation

Code Documentation

  • Use YARD for API documentation
  • Document all public methods
  • Include usage examples
  • Document parameters and return values

User Documentation

  • Update tech_docs/ for user-facing features
  • Include examples that users can copy/paste
  • Keep tutorials up to date

Generating Docs

# Generate YARD documentation
bundle exec yard doc

Questions?

If you have questions about contributing:

  1. Check existing documentation
  2. Search existing issues
  3. Open a new issue with the "question" label

Thank you for contributing to FakeDataDSL! 🎉