Getting Started Core Concepts - hiraishikentaro/rails-factorybot-jump GitHub Wiki
Getting Started: Core Concepts
Understanding the essential concepts and terminology for Rails FactoryBot Jump extension development.
Core Technologies
VSCode Extension Architecture
Document Link Provider: The foundation of the extension. VSCode calls this interface whenever it needs to generate clickable links in a document.
class FactoryLinkProvider implements vscode.DocumentLinkProvider {
provideDocumentLinks(document: vscode.TextDocument): vscode.DocumentLink[];
}
Document Links: VSCode objects that represent clickable text ranges with associated actions.
Commands: Custom VSCode commands that execute specific actions (e.g., jumping to a specific line).
Source: src/extension.ts#L14-L26
FactoryBot Integration
Factory Definitions: Ruby code that defines how to create test objects.
FactoryBot.define do
factory :user do
name { "John Doe" }
email { "[email protected]" }
end
end
Factory Calls: Code in test files that uses factories to create objects.
user = create(:user) # Calls the :user factory
Traits: Variations of factories that modify specific attributes.
trait :admin do
admin { true }
end
# Usage: create(:user, :admin)
Pattern Recognition
Factory Call Detection
The extension recognizes various FactoryBot method patterns:
Basic Methods:
create(:factory_name)
- Create and save to databasebuild(:factory_name)
- Build without savingbuild_stubbed(:factory_name)
- Build with stubbed associations
List Methods:
create_list(:factory_name, count)
- Create multiple recordsbuild_list(:factory_name, count)
- Build multiple records
Syntax Variations:
# Parentheses
create(:user)
create(:user, :admin)
# No parentheses (Ruby style)
create :user
create :user, :admin
Source: src/providers/factoryLinkProvider.ts
Factory Definition Detection
Factory Pattern: factory :name do
Trait Pattern: trait :name do
The extension parses these patterns to build its internal cache of available factories and traits.
Caching System
Factory Cache
Purpose: Fast lookup of factory definitions by name.
Structure: Map<factoryName, {uri, lineNumber}>
Example:
{
"user" => { uri: "file:///spec/factories/users.rb", lineNumber: 2 },
"post" => { uri: "file:///spec/factories/posts.rb", lineNumber: 1 }
}
Trait Cache
Purpose: Fast lookup of trait definitions within factories.
Structure: Map<"factoryName:traitName", {uri, lineNumber, factory}>
Example:
{
"user:admin" => { uri: "file:///spec/factories/users.rb", lineNumber: 6, factory: "user" },
"post:published" => { uri: "file:///spec/factories/posts.rb", lineNumber: 8, factory: "post" }
}
Cache Lifecycle
- Initialization: Built when extension activates or configuration changes
- Updates: Triggered by file system changes (create, modify, delete)
- Lookup: Used during document link generation
- Refresh: Complete rebuild when needed
Configuration System
Factory Paths
Purpose: Tell the extension where to find factory files.
Default: ["spec/factories/**/*.rb"]
Glob Patterns: Support for flexible file matching.
{
"rails-factorybot-jump.factoryPaths": [
"spec/factories/**/*.rb", // RSpec standard
"test/factories/**/*.rb", // Minitest standard
"lib/factories/**/*.rb" // Custom location
]
}
Path Resolution
Cross-platform: Uses POSIX paths for consistent behavior across operating systems.
Workspace Relative: Paths are resolved relative to the VSCode workspace root.
Source: package.json#L55-L65
File System Integration
File Watching
Purpose: Keep caches up-to-date with file changes.
Pattern: **/factories/**/*.rb
Events:
onDidCreate
- New factory file addedonDidChange
- Existing factory file modifiedonDidDelete
- Factory file removed
Workspace Integration
Multi-folder Support: Works with VSCode multi-root workspaces.
File Discovery: Uses VSCode's workspace APIs for reliable file access.
Source: src/extension.ts#L28-L41
Navigation Mechanics
Link Generation
- Text Scanning: Regex detects factory calls in document
- Cache Lookup: Find corresponding factory/trait definition
- Link Creation: Generate VSCode DocumentLink with command URI
- User Interaction: Click triggers navigation command
Command Execution
Command: rails-factorybot-jump.gotoLine
Parameters:
uri
: Target file URIlineNumber
: Specific line to navigate to
Actions:
- Open target document
- Create editor for document
- Position cursor at specific line
- Reveal line in editor view
Source: src/extension.ts#L14-L26
Performance Concepts
Lazy Loading
Factory Discovery: Only scans factory files when needed, not on every activation.
Cache Building: Deferred until first use to reduce startup time.
Incremental Updates
File Changes: Only rebuild affected cache entries, not entire cache.
Targeted Refresh: File watcher events trigger specific cache updates.
Memory Efficiency
Map Data Structures: O(1) lookup performance for factory and trait resolution.
Minimal Storage: Only store essential information (URI + line number).
Error Handling Concepts
Graceful Degradation
Missing Files: Extension continues working with available factory files.
Parse Errors: Skip problematic definitions without breaking functionality.
Permission Issues: Handle file access errors gracefully.
User Experience
Silent Failures: Don't interrupt workflow with error dialogs.
Debug Information: Log issues for troubleshooting without user intervention.
Fallback Behavior: Provide best-effort functionality when possible.
Extension Lifecycle
Activation
Trigger: When VSCode opens a Ruby language file.
Setup:
- Register document link provider
- Register commands
- Setup file system watcher
- Initialize factory cache (lazy)
Deactivation
Cleanup:
- Dispose subscriptions
- Clean up file watchers
- Clear caches
Resource Management: Ensure no memory leaks or background processes.
Source: src/extension.ts#L4-L44
Development Concepts
Testing Strategy
VSCode Environment: Tests run in actual VSCode instance for realistic testing.
Mock Data: Use Sinon for mocking file system and VSCode APIs.
Test Coverage: Cover core functionality, edge cases, and error conditions.
Code Organization
Provider Pattern: Separate concerns between extension management and link provision.
Single Responsibility: Each class has one clear purpose.
TypeScript: Strong typing for better development experience and fewer runtime errors.
Next Steps
- Technology Stack - Detailed technology overview
- System Design - Architecture deep dive
- Local Development - Start contributing