<commit_before>require 'spec_helper'

require 'ostruct'
require 'nokogiri'
require 'xeroid/deserialisers/extractors'

module Xeroid::Deserialisers
  describe Extractors do
    describe Extractors::Extractor do
      let(:xml) { '<r><s>A string</s><c>10.00</c></r>' }
      let(:doc) { Nokogiri::XML(xml) }
      let(:x) { Extractors::Extractor.new(doc) }

      context "string values" do
        it "can extract a value" do
          x.extract_string('/r/s').should == 'A string'
        end

        it "returns nil for a missing value" do
          x.extract_string('/r/null').should be_nil
        end
      end

      context "currency values" do
        it "can extract a value" do
          x.extract_currency('/r/c').should == BigDecimal.new("10.00")
        end

        it "returns nil for a missing value" do
          x.extract_currency('/r/null').should be_nil
        end
      end

      describe "using mappings" do
        it "can extract a specific kind of value using a mapping" do
          attributes = {}
          x.extract_from_mapping({:thing => '/r/s'}, :string, attributes)
          attributes[:thing].should == 'A string'
        end

        it "ignores empty-result xpaths" do
          attributes = {}
          x.extract_from_mapping({:thing => '/r/null'}, :string, attributes)
          attributes.should_not have_key(:thing)
        end

        it "ignores nil mappings" do
          attributes = {}
          x.extract_from_mapping(nil, :string, attributes)
          attributes.should be_empty
        end
      end
    end

    describe "straight-text attributes" do
      let(:xml) { '<r><a>A string</a><b>B string</b></r>' }
      let(:klass) { Class.new { include Extractors; object_class OpenStruct; as_string :thing => '/r/a' } }
      let(:instance) { klass.deserialise_one(xml) }

      it "can extract a value" do
        instance.thing.should == "A string"
      end

      context "several values" do
        let(:klass) { Class.new { include Extractors; object_class OpenStruct; as_string :a => '/r/a', :b => '/r/b' } }

        it "can extract the first value" do
          instance.a.should == 'A string'
        end

        it "can extract the second value" do
          instance.b.should == 'B string'
        end
      end

      context "missing values" do
        let(:klass) { Class.new { include Extractors; object_class OpenStruct; as_string :a => '/r/a', :c => '/r/c' } }

        it "extracts the first value" do
          instance.a.should == 'A string'
        end

        it "doesn't attempt to set the second" do
          instance.should_not respond_to(:c)
        end
      end
    end

    describe "currency attributes" do
      let(:xml) { '<r><a>10.00</a><b>20.00</b></r>' }
      let(:klass) { Class.new { include Extractors; object_class OpenStruct; as_currency :thing => '/r/a' } }
      let(:instance) { klass.deserialise_one(xml) }
      let(:ten) { BigDecimal.new("10.00")  }
      let(:twenty) { BigDecimal.new("20.00") }

      it "can extract a value" do
        instance.thing.should == ten
      end

      context "several values" do
        let(:klass) { Class.new { include Extractors; object_class OpenStruct; as_currency :a => '/r/a', :b => '/r/b' } }

        it "can extract the first value" do
          instance.a.should == ten
        end

        it "can extract the second value" do
          instance.b.should == twenty
        end
      end

      context "missing values" do
        let(:klass) { Class.new { include Extractors; object_class OpenStruct; as_currency :a => '/r/a', :c => '/r/c' } }

        it "extracts the first value" do
          instance.a.should == ten
        end

        it "doesn't attempt to set the second" do
          instance.should_not respond_to(:c)
        end
      end
    end
  end
end<commit_msg>Add several-mapping case to mappings specs, remove extra specs from value-specific mapping specs<commit_after>require 'spec_helper'

require 'ostruct'
require 'nokogiri'
require 'xeroid/deserialisers/extractors'

module Xeroid::Deserialisers
  describe Extractors do
    describe Extractors::Extractor do
      let(:xml) { '<r><s>A string</s><c>10.00</c></r>' }
      let(:doc) { Nokogiri::XML(xml) }
      let(:x) { Extractors::Extractor.new(doc) }

      context "string values" do
        it "can extract a value" do
          x.extract_string('/r/s').should == 'A string'
        end

        it "returns nil for a missing value" do
          x.extract_string('/r/null').should be_nil
        end
      end

      context "currency values" do
        it "can extract a value" do
          x.extract_currency('/r/c').should == BigDecimal.new("10.00")
        end

        it "returns nil for a missing value" do
          x.extract_currency('/r/null').should be_nil
        end
      end

      describe "using mappings" do
        it "can extract a specific kind of value using a mapping" do
          attributes = {}
          x.extract_from_mapping({:thing => '/r/s'}, :string, attributes)
          attributes[:thing].should == 'A string'
        end

        context "many-value mappings" do
          let(:xml) { '<r><a>A string</a><b>B string</b></r>' }

          it "can extract several values" do
            attributes = {}
            x.extract_from_mapping({:a => '/r/a', :b => '/r/b'}, :string, attributes)
            attributes[:a].should == 'A string'
            attributes[:b].should == 'B string'
          end
        end

        it "ignores empty-result xpaths" do
          attributes = {}
          x.extract_from_mapping({:thing => '/r/null'}, :string, attributes)
          attributes.should_not have_key(:thing)
        end

        it "ignores nil mappings" do
          attributes = {}
          x.extract_from_mapping(nil, :string, attributes)
          attributes.should be_empty
        end
      end
    end

    describe "straight-text attributes" do
      let(:xml) { '<r><a>A string</a><b>B string</b></r>' }
      let(:klass) { Class.new { include Extractors; object_class OpenStruct; as_string :thing => '/r/a' } }

      it "can extract a value" do
        klass.deserialise_one(xml).thing.should == "A string"
      end
    end

    describe "currency attributes" do
      let(:xml) { '<r><a>10.00</a><b>20.00</b></r>' }
      let(:klass) { Class.new { include Extractors; object_class OpenStruct; as_currency :thing => '/r/a' } }
      let(:ten) { BigDecimal.new("10.00")  }

      it "can extract a value" do
        klass.deserialise_one(xml).thing.should == ten
      end
    end
  end
end
{'fraction_non_alphanumeric': 0.12983257229832573, 'fraction_numerical': 0.006697108066971081, 'mean_word_length': 2.1743961352657006, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 13}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4254283', 'n_tokens_mistral': 2055, 'n_tokens_neox': 1977, 'n_words': 559}