Back to Repositories

Testing CSS Margin Rule Generation in Bourbon Framework

This test suite validates the margin mixin functionality in Bourbon, ensuring proper CSS margin rule generation for various input combinations. The tests verify the mixin’s ability to handle different margin configurations while maintaining CSS specification compliance.

Test Coverage Overview

The test suite provides comprehensive coverage of the margin mixin functionality, testing various input scenarios.

  • Single value margin application
  • Two-value alternating margins
  • Three-value margin combinations
  • Four-value explicit margins
  • Null value handling

Implementation Analysis

The testing approach utilizes RSpec’s context-based structure to organize different margin scenarios systematically. The implementation leverages custom matchers (have_rule and have_ruleset) to verify CSS output patterns, with ParserSupport handling file parsing for each test case.

The tests employ BDD-style expectations with clear, descriptive contexts that map directly to CSS margin shorthand syntax patterns.

Technical Details

  • Testing Framework: RSpec
  • Custom Matchers: have_rule, have_ruleset
  • Support Classes: ParserSupport
  • File Structure: Organized by margin value combinations
  • Setup: Utilizes before(:all) hook for file parsing

Best Practices Demonstrated

The test suite exemplifies several testing best practices including isolation of test cases, clear context descriptions, and comprehensive edge case coverage.

  • Organized test structure using nested contexts
  • Consistent assertion patterns
  • Clear separation of setup and expectations
  • Thorough validation of CSS rule generation

thoughtbot/bourbon

spec/bourbon/library/margin_spec.rb

            
require "spec_helper"

describe "margin" do
  before(:all) do
    ParserSupport.parse_file("library/margin")
  end

  context "called with one size" do
    it "applies same width to all sides" do
      rule = "margin: 1px"

      expect(".margin-all").to have_rule(rule)
    end
  end

  context "called with two sizes" do
    it "applies to alternating sides" do
      rule = "margin: 2px 3px"

      expect(".margin-alternate").to have_rule(rule)
    end
  end

  context "called with three sizes" do
    it "applies second width to left and right" do
      rule = "margin: 4px 5px 6px"

      expect(".margin-implied-left").to have_rule(rule)
    end
  end

  context "called with four sizes" do
    it "applies different widths to all sides" do
      rule = "margin: 7px 8px 9px 10px"

      expect(".margin-explicit").to have_rule(rule)
    end
  end

  context "called with null values" do
    it "writes rules for other three" do
      ruleset = "margin-top: 11px; " +
                "margin-right: 12px; " +
                "margin-left: 13px;"
      bad_rule = "margin-bottom: null;"

      expect(".margin-false-third").to have_ruleset(ruleset)
      expect(".margin-false-third").to_not have_rule(bad_rule)
    end
  end
end