<commit_before>require 'spec_helper'

describe Morfo::Base do
  let(:input) do
    [
      {
        title: 'The Walking Dead',
        channel: 'AMC',
        watchers: 1337,
        status: 'running',
        cast: ['<NAME>', '<NAME>'],
        ratings: {
          imdb: 8.7,
          trakt: 89,
          rotten_tomatoes: 93,
        },
      },
      {
        title: 'Breaking Bad',
        channel: 'AMC',
        watchers: 72891,
        status: 'ended',
        cast: ['<NAME>', '<NAME>'],
        ratings: {
          imdb: 9.5,
          trakt: 95,
          rotten_tomatoes: 100,
        },
      }
    ]
  end

  describe '#morf' do
    context 'errors' do
      subject(:no_from) do
        class NilMapper < Morfo::Base
          field :my_field, {}
        end
        NilMapper
      end
      it 'raises error for nil field' do
        expect{no_from.morf([])}.to raise_error(ArgumentError)
      end
    end

    context '1 to 1 conversion' do
      subject do
        class TitleMapper < Morfo::Base
          field :tv_show_title, from: :title
        end
        TitleMapper
      end

      it 'maps title correctly' do
        expected_output = input.map{|v| {tv_show_title: v[:title]} }
        expect(subject.morf(input)).to eq(expected_output)
      end

      it 'leaves out nil values in result' do
        expected_output = [{},{}]
        modified_input = input.map{|h| h.reject{|k, v| k == :title}}
        expect(subject.morf(modified_input)).to eq(expected_output)
      end
    end

    context '1 to 1 conversion with transformation' do
      subject do
        class NumCastMapper < Morfo::Base
          field(:cast_num, from: :cast){|v,r| v.size}
        end
        NumCastMapper
      end

      it 'calls transformation correctly' do
        expected_output = input.map{|v| {cast_num: v[:cast].size} }
        expect(subject.morf(input)).to eq(expected_output)
      end
    end

    context '1 to many conversion' do
      subject do
        class MutliTitleMapper < Morfo::Base
          field :title, from: :title
          field :also_title, from: :title
        end
        MutliTitleMapper
      end

      it 'maps title to multiple fields' do
        expected_output = input.map{|v| {title: v[:title], also_title: v[:title]} }
        expect(subject.morf(input)).to eq(expected_output)
      end
    end

    context 'nested conversion' do
      context 'nested source' do
        subject(:valid_path) do
          class ImdbRatingMapper < Morfo::Base
            field :rating, from: [:ratings, :imdb]
          end
          ImdbRatingMapper
        end

        subject(:valid_path_with_transformation) do
          class ImdbRatingMapper < Morfo::Base
            field(:rating, from: [:ratings, :imdb]){|v| "Rating: #{v}"}
          end
          ImdbRatingMapper
        end

        subject(:invalid_path) do
          class InvalidImdbRatingMapper < Morfo::Base
            field :rating, from: [:very, :long, :path, :that, :might, :not, :exist]
          end
          InvalidImdbRatingMapper
        end

        it 'maps nested attributes' do
          expected_output = input.map{|v| {rating: v[:ratings][:imdb]} }
          expect(valid_path.morf(input)).to eq(expected_output)
        end

        it 'maps nested attributes with transformation' do
          expected_output = input.map{|v| {rating: "Rating: #{v[:ratings][:imdb]}"} }
          expect(valid_path_with_transformation.morf(input)).to eq(expected_output)
        end

        it 'doesn\'t raise error for invalid path' do
          expected_output = [{},{}]
          expect(invalid_path.morf(input)).to eq(expected_output)
        end
      end

      context 'nested destination' do
        subject do
          class WrapperMapper < Morfo::Base
            field([:tv_show, :title], from: :title)
            field([:tv_show, :channel], from: :channel){|v| "Channel: #{v}"}
          end
          WrapperMapper
        end

        it 'maps to nested destination' do
          expected_output = input.map{|v|
            {
              tv_show: {
                title: v[:title],
                channel: "Channel: #{v[:channel]}",
              }
            }
          }
          expect(subject.morf(input)).to eq(expected_output)
        end
      end
    end

    context 'calculations' do
      subject do
        class TitlePrefixMapper < Morfo::Base
          field(:title_with_channel){|v,r| "#{r[:title]}, (#{r[:channel]})"}
        end
        TitlePrefixMapper
      end

      it 'maps calculation correctly' do
        expected_output = input.map{|r|
          {
            title_with_channel: "#{r[:title]}, (#{r[:channel]})"
          }
        }
        expect(subject.morf(input)).to eq(expected_output)
      end
    end
  end
end
<commit_msg>add test for static value<commit_after>require 'spec_helper'

describe Morfo::Base do
  let(:input) do
    [
      {
        title: 'The Walking Dead',
        channel: 'AMC',
        watchers: 1337,
        status: 'running',
        cast: ['<NAME>', '<NAME>'],
        ratings: {
          imdb: 8.7,
          trakt: 89,
          rotten_tomatoes: 93,
        },
      },
      {
        title: 'Breaking Bad',
        channel: 'AMC',
        watchers: 72891,
        status: 'ended',
        cast: ['<NAME>', '<NAME>'],
        ratings: {
          imdb: 9.5,
          trakt: 95,
          rotten_tomatoes: 100,
        },
      }
    ]
  end

  describe '#morf' do
    context 'errors' do
      subject(:no_from) do
        class NilMapper < Morfo::Base
          field :my_field, {}
        end
        NilMapper
      end
      it 'raises error for nil field' do
        expect{no_from.morf([])}.to raise_error(ArgumentError)
      end
    end

    context '1 to 1 conversion' do
      subject do
        class TitleMapper < Morfo::Base
          field :tv_show_title, from: :title
        end
        TitleMapper
      end

      it 'maps title correctly' do
        expected_output = input.map{|v| {tv_show_title: v[:title]} }
        expect(subject.morf(input)).to eq(expected_output)
      end

      it 'leaves out nil values in result' do
        expected_output = [{},{}]
        modified_input = input.map{|h| h.reject{|k, v| k == :title}}
        expect(subject.morf(modified_input)).to eq(expected_output)
      end
    end

    context '1 to 1 conversion with transformation' do
      subject do
        class NumCastMapper < Morfo::Base
          field(:cast_num, from: :cast){|v,r| v.size}
        end
        NumCastMapper
      end

      it 'calls transformation correctly' do
        expected_output = input.map{|v| {cast_num: v[:cast].size} }
        expect(subject.morf(input)).to eq(expected_output)
      end
    end

    context '1 to many conversion' do
      subject do
        class MutliTitleMapper < Morfo::Base
          field :title, from: :title
          field :also_title, from: :title
        end
        MutliTitleMapper
      end

      it 'maps title to multiple fields' do
        expected_output = input.map{|v| {title: v[:title], also_title: v[:title]} }
        expect(subject.morf(input)).to eq(expected_output)
      end
    end

    context 'nested conversion' do
      context 'nested source' do
        subject(:valid_path) do
          class ImdbRatingMapper < Morfo::Base
            field :rating, from: [:ratings, :imdb]
          end
          ImdbRatingMapper
        end

        subject(:valid_path_with_transformation) do
          class ImdbRatingMapper < Morfo::Base
            field(:rating, from: [:ratings, :imdb]){|v| "Rating: #{v}"}
          end
          ImdbRatingMapper
        end

        subject(:invalid_path) do
          class InvalidImdbRatingMapper < Morfo::Base
            field :rating, from: [:very, :long, :path, :that, :might, :not, :exist]
          end
          InvalidImdbRatingMapper
        end

        it 'maps nested attributes' do
          expected_output = input.map{|v| {rating: v[:ratings][:imdb]} }
          expect(valid_path.morf(input)).to eq(expected_output)
        end

        it 'maps nested attributes with transformation' do
          expected_output = input.map{|v| {rating: "Rating: #{v[:ratings][:imdb]}"} }
          expect(valid_path_with_transformation.morf(input)).to eq(expected_output)
        end

        it 'doesn\'t raise error for invalid path' do
          expected_output = [{},{}]
          expect(invalid_path.morf(input)).to eq(expected_output)
        end
      end

      context 'nested destination' do
        subject do
          class WrapperMapper < Morfo::Base
            field([:tv_show, :title], from: :title)
            field([:tv_show, :channel], from: :channel){|v| "Channel: #{v}"}
          end
          WrapperMapper
        end

        it 'maps to nested destination' do
          expected_output = input.map{|v|
            {
              tv_show: {
                title: v[:title],
                channel: "Channel: #{v[:channel]}",
              }
            }
          }
          expect(subject.morf(input)).to eq(expected_output)
        end
      end
    end

    context 'calculations' do
      subject do
        class TitlePrefixMapper < Morfo::Base
          field(:title_with_channel){|v,r| "#{r[:title]}, (#{r[:channel]})"}
        end
        TitlePrefixMapper
      end

      it 'maps calculation correctly' do
        expected_output = input.map{|r|
          {
            title_with_channel: "#{r[:title]}, (#{r[:channel]})"
          }
        }
        expect(subject.morf(input)).to eq(expected_output)
      end
    end

    context 'static values' do
      subject do
        class StaticTitleMapper < Morfo::Base
          field(:new_title){ 'Static Title' }
        end
        StaticTitleMapper
      end

      it 'maps static value correctly' do
        expected_output = input.map{|r| {new_title: 'Static Title'} }
        expect(subject.morf(input)).to eq(expected_output)
      end
    end
  end
end

{'fraction_non_alphanumeric': 0.1126238862749024, 'fraction_numerical': 0.005405946541195315, 'mean_word_length': 1.8789625360230549, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '2845796', 'n_tokens_mistral': 3053, 'n_tokens_neox': 2917, 'n_words': 752}