require 'rails_helper'

RSpec.describe UnitConversion::ParsedUnit do

  it 'converts simple units' do
    data = {
        'c' => '[cup_us]',
        'cups' => '[cup_us]',
        'pints' => '[pt_us]',
        'gram' => 'g',
        'grams' => 'g',
        'Grams' => 'g',
        'Tbsp' => '[tbs_us]',
        '[tbs_us]' => '[tbs_us]',
        '[oz_av]' => '[oz_av]',
        'cubic inch' => '[in_i]3',
        'in3' => '[in_i]3'

    }

    data.each do |input, output|
      expect(UnitConversion::ParsedUnit.new(input).unit).to eq output
    end
  end

  it 'converts mixed units' do
    data = {
        'oz/c' => '[oz_av]/[cup_us]',
        'kilograms/cups' => 'kg/[cup_us]',
        'pints/junk' => '[pt_us]/junk',
        'gram/[tbs_us]' => 'g/[tbs_us]'
    }

    data.each do |input, output|
      expect(UnitConversion::ParsedUnit.new(input).unit).to eq output
    end
  end

  describe '.to_s' do
    it 'renders friendly simple units' do
      expect(UnitConversion::ParsedUnit.new('m').to_s).to eq 'meter'
      expect(UnitConversion::ParsedUnit.new('tbsp').to_s).to eq 'tablespoon'
      expect(UnitConversion::ParsedUnit.new('gallons').to_s).to eq 'gallon'
      expect(UnitConversion::ParsedUnit.new('[cup_us]').to_s).to eq 'cup'
      expect(UnitConversion::ParsedUnit.new('junk').to_s).to eq 'junk'
    end

    it 'renders friendly compound units' do
      expect(UnitConversion::ParsedUnit.new('m/c').to_s).to eq 'meter/cup'
      expect(UnitConversion::ParsedUnit.new('[oz_av]/[cup_us]').to_s).to eq 'ounce/cup'
    end
  end

  describe '.metric?' do
    it 'returns true for metric units' do
      expect(UnitConversion::ParsedUnit.new('m').metric?).to be_truthy
      expect(UnitConversion::ParsedUnit.new('g').metric?).to be_truthy
      expect(UnitConversion::ParsedUnit.new('meter').metric?).to be_truthy
      expect(UnitConversion::ParsedUnit.new('centiliter').metric?).to be_truthy
    end

    it 'returns false for standard units' do
      expect(UnitConversion::ParsedUnit.new('c').metric?).to be_falsey
      expect(UnitConversion::ParsedUnit.new('tbsp').metric?).to be_falsey
      expect(UnitConversion::ParsedUnit.new('oz').metric?).to be_falsey
    end

    it 'returns false for unknown units' do
      expect(UnitConversion::ParsedUnit.new('cats').metric?).to be_falsey
      expect(UnitConversion::ParsedUnit.new('dogs').metric?).to be_falsey
    end
  end

  describe '.density?' do
    it 'returns true for any mass over volume unit' do
      data = [
          'gram/cup',
          'pound/gallon',
          'ounce/tablespoon',
          'ounce/centimeter3'
      ]

      data.each do |input|
        expect(UnitConversion::ParsedUnit.new(input).density?).to be_truthy
      end
    end

    it 'returns false for any non density unit' do
      data = [
          'cup',
          'gram',
          'gram/hour',
          'centimeter3/ounce'
      ]

      data.each do |input|
        expect(UnitConversion::ParsedUnit.new(input).density?).to be_falsey
      end
    end
  end

end