module JsonPath RSpec.describe Builder do let(:key) { "some-value" } let(:other_key) { "some-other-value" } let(:list) { %w[some-list-value-1 some-list-value-2] } let(:input) { { key: key, other_key: other_key, list: list }.as_json } subject(:instance) { described_class.new } describe '.from' do it 'handles simple path mapping' do %i[key other_key].each { |k| instance.from(k) } expect(instance.build_for(input)).to eql({ key: key, other_key: other_key }) end it 'handles renaming path name' do instance.from(:other_key, to: :another_key) expect(instance.build_for(input)).to eql({ another_key: other_key }) end it 'handles transformations' do instance.from(:key, transform: proc { |v| v.upcase }) expect(instance.build_for(input)).to eql({ key: key.upcase }) end end describe '.from_each' do it 'handles simple path mapping' do instance.from_each(:list) expect(instance.build_for(input)).to eql({ list: list }) end it 'handles renaming path name' do instance.from(:list, to: :another_list_key) expect(instance.build_for(input)).to eql({ another_list_key: list }) end it 'handles transformations' do instance.from_each(:list, transform: proc { |v| v.upcase }) expect(instance.build_for(input)).to eql({ list: list.map(&:upcase) }) end it 'handles skipping items' do instance.from_each(:list, skip_if: proc { |v| v == 'some-list-value-1' }) expect(instance.build_for(input)).to eql({ list: ['some-list-value-2'] }) end end describe '#within' do let(:email) { 'email@domain.com' } let(:user_id) { 1 } let(:input) { { root: { deep: { profile: { email: email, uid: user_id } } } }.as_json } it 'uses scope to simplify dot notation' do builder = described_class.new builder.within('root.deep.profile') do |b| b.from(:email) b.from(:uid, to: :user_id) end expect(builder.build_for(input)).to eql({ email: email, user_id: user_id }) end end describe '#with_wrapped_data_class' do let(:email) { 'email@domain.com' } let(:user_id) { 123 } let(:input) { { profile: { email: email } }.as_json } let(:user) { double(:user, id: user_id) } let(:user_repo) { double(:user_repo, find_by: user) } let(:wrapped_data_class) do Class.new(SimpleDelegator) do class << self attr_accessor :user_repo end def user self.class.user_repo.find_by(email: dig('profile', 'email')) end end end before do wrapped_data_class.user_repo = user_repo end it 'wraps input data in wrapped class' do builder = described_class.new builder.with_wrapped_data_class(wrapped_data_class) transform = proc do |_email, path_context| path_context.wrapped_source_data.user.id end builder.from('profile.email', to: :user_id, transform: transform) expect(builder.build_for(input)).to eql({ user_id: user_id }) end end describe '#wrapped_data_class' do context 'with custom data class' do let(:wrapper_class) { Class.new(DefaultDataWrapper) } it 'returns custom class' do instance.with_wrapped_data_class(wrapper_class) expect(instance.data_wrapper_class).to eql(wrapper_class) end end context 'without custom data class' do let(:custom_wrapper) { nil } it 'returns default class' do expect(instance.data_wrapper_class).to eql(DefaultDataWrapper) end end end # describe PathsBuilder::PathContext do # let(:key) { "some-value" } # let(:other_key) { "some-other-value" } # let(:list) { %w[some-list-value-1 some-list-value-2] } # # let(:input) { { key: key, other_key: other_key, list: list }.as_json } # let(:builder) { PathsBuilder.new } # let(:path_context) { builder.path_context_collection.first } # # before(:each) do # builder.from(:key, to: :another_key, transform: proc { |val| val.upcase }) # builder.with_source_data(input) # end # # # it 'returns path context instance' do # expect(path_context).to be_instance_of(described_class) # end # # describe '#wrapped_source_data' do # subject { path_context.wrapped_source_data } # # context 'with custom data class' do # let(:wrapper_class) { Sharplaunch::PropertyListingDataWrapper } # # before(:each) { builder.with_wrapped_data_class(wrapper_class) } # # it 'returns custom class' do # expect(subject).to be_an_instance_of(wrapper_class) # end # end # # context 'without custom data wrapper class' do # it 'returns default wrapper instance' do # expect(subject).to be_instance_of(PathsBuilder::DefaultDataWrapper) # end # end # end # end end end