flutter_fixtures_core 0.1.0

SDKflutter
Platformandroidioswindowslinuxmacosweb

Core interfaces and domain models for Flutter Fixtures

Flutter Fixtures Core

pub package

Core interfaces and domain models for the Flutter Fixtures library. This package provides the foundational abstractions that enable extensible fixture-based mocking.

🎯 Purpose

This package defines the core contracts and data models used by all Flutter Fixtures implementations. Use this package when:

  • Creating custom data providers (database, file system, network, etc.)
  • Extending the Flutter Fixtures ecosystem with new data source functionality
  • Building libraries that need fixture-based mocking capabilities

📦 What's Included

Interfaces

  • DataQuery<Input, Output>: Abstract interface for querying data sources
  • DataSelectorView: Interface for fixture selection components
  • FixtureSelector: Mixin providing fixture selection functionality

Data Models

  • FixtureCollection: Container for multiple fixture response options
  • FixtureDocument: Individual fixture response definition

Selection Strategies

  • DataSelectorType: Sealed class defining fixture selection strategies
    • Random(): Randomly select from available fixtures
    • Default(): Use the fixture marked as default
    • Pick(): Let user choose through UI

🚀 Quick Start

Add to your pubspec.yaml:

dependencies:
  flutter_fixtures_core: ^0.1.0

🛠️ Creating Custom Data Providers

Implement the DataQuery interface to create custom data sources:

import 'package:flutter_fixtures_core/flutter_fixtures_core.dart';

class DatabaseDataQuery implements DataQuery<String, Map<String, dynamic>> {
  final Database database;

  DatabaseDataQuery(this.database);

  @override
  Future<Map<String, dynamic>?> find(String query) async {
    // Query your database
    final result = await database.query('fixtures', where: 'query = ?', whereArgs: [query]);
    return result.isNotEmpty ? result.first : null;
  }

  @override
  Future<FixtureCollection?> parse(Map<String, dynamic> source) async {
    // Parse database result into fixture collection
    return FixtureCollection(
      description: source['description'],
      items: (source['options'] as List).map((item) =>
        FixtureDocument(
          identifier: item['id'],
          description: item['description'],
          defaultOption: item['is_default'] ?? false,
          data: item['response_data'],
        )
      ).toList(),
    );
  }

  @override
  Future<Map<String, dynamic>?> data(FixtureDocument document) async {
    // Return the response data
    return document.data;
  }

  @override
  Future<FixtureDocument?> select(
    FixtureCollection fixture,
    DataSelectorView? view,
    DataSelectorType selector,
  ) async {
    // Use the FixtureSelector mixin for standard selection logic
    return switch (selector) {
      Pick() => await view?.pick(fixture),
      Default() => fixture.items.firstWhere((item) => item.defaultOption ?? false),
      Random() => fixture.items[Random().nextInt(fixture.items.length)],
    };
  }
}

🧩 Using the FixtureSelector Mixin

The FixtureSelector mixin provides standard fixture selection logic:

class MyDataProvider with FixtureSelector implements DataQuery<String, Map<String, dynamic>> {
  @override
  Future<Map<String, dynamic>?> find(String input) async {
    // Your find implementation
  }

  @override
  Future<FixtureCollection?> parse(Map<String, dynamic> source) async {
    // Your parse implementation
  }

  @override
  Future<Map<String, dynamic>?> data(FixtureDocument document) async {
    // Your data implementation
  }

  // select() method is provided by the FixtureSelector mixin
}

📋 Data Model Reference

FixtureCollection

Container for multiple fixture response options:

final collection = FixtureCollection(
  description: 'User API responses',
  items: [
    FixtureDocument(
      identifier: 'success',
      description: '200 Success',
      defaultOption: true,
      data: {'users': [...]},
    ),
    // ... more fixtures
  ],
);

FixtureDocument

Individual fixture response definition:

final document = FixtureDocument(
  identifier: 'success',           // Unique identifier
  description: '200 Success',      // Human-readable description
  defaultOption: true,             // Whether this is the default choice
  data: {'users': [...]},          // Inline response data
  dataPath: 'users_large.json',    // Or path to external data file
);

DataSelectorType

Fixture selection strategies:

// Always use default fixture
final defaultSelector = DataSelectorType.defaultValue();

// Randomly select fixture
final randomSelector = DataSelectorType.random();

// Let user choose via UI (requires DataSelectorView implementation)
final pickSelector = DataSelectorType.pick();

DataSelectorView

Interface for implementing fixture selection mechanisms:

abstract class DataSelectorView {
  Future<FixtureDocument?> pick(FixtureCollection fixture);
}

This interface is implemented by UI packages to provide user-driven fixture selection. The core package defines the contract, while implementation packages (like flutter_fixtures_ui) provide concrete implementations.

🔗 Integration

This package provides the foundation for:

Use this package directly when building custom data providers or extending the Flutter Fixtures ecosystem.

📚 Examples

For complete examples and usage patterns, see the Flutter Fixtures repository.

🤝 Contributing

Contributions are welcome! Please read our contributing guide.

📄 License

MIT License - see the LICENSE file for details.