CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-eslint-plugin-jasmine

ESLint plugin providing 23 linting rules specifically designed for Jasmine testing framework to enforce best practices and catch common mistakes

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

code-style-rules.mddocs/

Code Style Rules

Rules that enforce consistent code style and formatting in Jasmine tests to improve readability and maintainability.

Capabilities

new-line-between-declarations

Enforces new lines between variable declarations in test files to improve readability and make code structure clearer.

/**
 * Rule: new-line-between-declarations
 * Enforces new lines between variable declarations
 * @config [0|1|2] - Rule severity level
 */
'jasmine/new-line-between-declarations': [0|1|2]

Examples:

// ❌ Bad - declarations without spacing
describe('Service tests', function() {
  let service;
  let config;
  let mockData;
  
  beforeEach(function() {
    let options = {};
    let settings = getSettings();
    let environment = 'test';
    // Hard to scan visually
  });
});

// ✅ Good - spaced declarations
describe('Service tests', function() {
  let service;
  
  let config;
  
  let mockData;
  
  beforeEach(function() {
    let options = {};
    
    let settings = getSettings();
    
    let environment = 'test';
    // Much clearer visual separation
  });
});

new-line-before-expect

Enforces a new line before expect statements to visually separate test setup from assertions and improve test readability.

/**
 * Rule: new-line-before-expect
 * Enforces new line before expect statements for better readability
 * @config [0|1|2] - Rule severity level
 */
'jasmine/new-line-before-expect': [0|1|2]

Examples:

// ❌ Bad - no space before expect
it('should calculate total', function() {
  const items = [{ price: 10 }, { price: 20 }];
  const service = new PriceService();
  const result = service.calculateTotal(items);
  expect(result).toBe(30);
});

// ❌ Bad - multiple expects without spacing
it('should validate user data', function() {
  const user = { name: 'John', age: 30 };
  const validator = new UserValidator();
  const result = validator.validate(user);
  expect(result.isValid).toBe(true);
  expect(result.errors).toEqual([]);
  expect(user.name).toBe('John');
});

// ✅ Good - proper spacing before expects
it('should calculate total', function() {
  const items = [{ price: 10 }, { price: 20 }];
  const service = new PriceService();
  const result = service.calculateTotal(items);
  
  expect(result).toBe(30);
});

// ✅ Good - spaced expects for better readability
it('should validate user data', function() {
  const user = { name: 'John', age: 30 };
  const validator = new UserValidator();
  const result = validator.validate(user);
  
  expect(result.isValid).toBe(true);
  expect(result.errors).toEqual([]);
  expect(user.name).toBe('John');
});

Rule Configuration

Both code style rules support standard ESLint severity levels:

  • 0 or "off" - Disable the rule
  • 1 or "warn" - Enable as warning
  • 2 or "error" - Enable as error (fails lint)

Recommended Settings:

rules:
  jasmine/new-line-between-declarations: 1   # Warning - improves readability
  jasmine/new-line-before-expect: 1          # Warning - separates setup from assertions

Style Guidelines

Readable Test Structure

describe('UserRegistrationService', function() {
  let service;
  
  let mockEmailService;
  
  let mockDatabase;
  
  let validUserData;
  
  beforeEach(function() {
    mockEmailService = jasmine.createSpyObj('emailService', ['sendWelcome']);
    
    mockDatabase = jasmine.createSpyObj('database', ['save', 'findByEmail']);
    
    service = new UserRegistrationService(mockEmailService, mockDatabase);
    
    validUserData = {
      name: 'John Doe',
      email: 'john@example.com',
      password: 'securePassword123'
    };
  });
  
  describe('registerUser', function() {
    it('should register new user successfully', function() {
      mockDatabase.findByEmail.and.returnValue(null);
      mockDatabase.save.and.returnValue({ id: 123, ...validUserData });
      
      const result = service.registerUser(validUserData);
      
      expect(mockDatabase.findByEmail).toHaveBeenCalledWith('john@example.com');
      expect(mockDatabase.save).toHaveBeenCalledWith(validUserData);
      expect(mockEmailService.sendWelcome).toHaveBeenCalledWith(validUserData.email);
      expect(result.success).toBe(true);
      expect(result.user.id).toBe(123);
    });
    
    it('should reject duplicate email addresses', function() {
      const existingUser = { id: 456, email: 'john@example.com' };
      mockDatabase.findByEmail.and.returnValue(existingUser);
      
      const result = service.registerUser(validUserData);
      
      expect(mockDatabase.findByEmail).toHaveBeenCalledWith('john@example.com');
      expect(mockDatabase.save).not.toHaveBeenCalled();
      expect(mockEmailService.sendWelcome).not.toHaveBeenCalled();
      expect(result.success).toBe(false);
      expect(result.error).toBe('Email already registered');
    });
    
    it('should validate required fields', function() {
      const invalidData = { name: '', email: 'invalid-email', password: '123' };
      
      const result = service.registerUser(invalidData);
      
      expect(result.success).toBe(false);
      expect(result.errors).toContain('Name is required');
      expect(result.errors).toContain('Invalid email format');
      expect(result.errors).toContain('Password too short');
    });
  });
});

Complex Test Scenarios

describe('DataProcessingPipeline', function() {
  let pipeline;
  
  let mockValidator;
  
  let mockTransformer;
  
  let mockStorage;
  
  let sampleData;
  
  beforeEach(function() {
    mockValidator = jasmine.createSpyObj('validator', ['validate']);
    
    mockTransformer = jasmine.createSpyObj('transformer', ['transform']);
    
    mockStorage = jasmine.createSpyObj('storage', ['save']);
    
    pipeline = new DataProcessingPipeline(mockValidator, mockTransformer, mockStorage);
    
    sampleData = [
      { id: 1, name: 'Item 1', value: 100 },
      { id: 2, name: 'Item 2', value: 200 },
      { id: 3, name: 'Item 3', value: 300 }
    ];
  });
  
  describe('processData', function() {
    it('should process valid data through complete pipeline', async function() {
      const validatedData = sampleData.map(item => ({ ...item, validated: true }));
      const transformedData = validatedData.map(item => ({ ...item, processed: true }));
      
      mockValidator.validate.and.returnValue(Promise.resolve(validatedData));
      mockTransformer.transform.and.returnValue(Promise.resolve(transformedData));
      mockStorage.save.and.returnValue(Promise.resolve({ success: true }));
      
      const result = await pipeline.processData(sampleData);
      
      expect(mockValidator.validate).toHaveBeenCalledWith(sampleData);
      expect(mockTransformer.transform).toHaveBeenCalledWith(validatedData);
      expect(mockStorage.save).toHaveBeenCalledWith(transformedData);
      expect(result.success).toBe(true);
      expect(result.processedCount).toBe(3);
    });
    
    it('should handle validation errors gracefully', async function() {
      const validationError = new Error('Validation failed for item 2');
      mockValidator.validate.and.returnValue(Promise.reject(validationError));
      
      const result = await pipeline.processData(sampleData);
      
      expect(mockValidator.validate).toHaveBeenCalledWith(sampleData);
      expect(mockTransformer.transform).not.toHaveBeenCalled();
      expect(mockStorage.save).not.toHaveBeenCalled();
      expect(result.success).toBe(false);
      expect(result.error).toBe('Validation failed for item 2');
    });
  });
});

Benefits of Consistent Styling

Improved Readability

  • Clear visual separation between setup, action, and assertion phases
  • Easier to scan and understand test structure
  • Consistent formatting across team members

Better Maintenance

  • Easier to locate specific parts of tests
  • Clearer boundaries between different test concerns
  • Reduced cognitive load when reading tests

Enhanced Debugging

  • Clear visual structure helps identify issues faster
  • Proper spacing makes it easier to add debug statements
  • Consistent patterns make tests more predictable

docs

code-organization-rules.md

code-style-rules.md

expectation-rules.md

index.md

jasmine-matcher-rules.md

promise-rules.md

spy-rules.md

test-structure-rules.md

tile.json