spec/extensions/postgres/attribute_spec.rb in rom-sql-1.3.2 vs spec/extensions/postgres/attribute_spec.rb in rom-sql-1.3.3

- old
+ new

@@ -1,11 +1,8 @@ RSpec.describe 'ROM::SQL::Attribute', :postgres do include_context 'database setup' - jsonb_hash = -> v { Sequel::Postgres::JSONBHash.new(v) } - jsonb_array = -> v { Sequel::Postgres::JSONBArray.new(v) } - before do conn.drop_table?(:pg_people) conn.drop_table?(:people) conf.relation(:people) do @@ -14,116 +11,130 @@ end let(:people) { relations[:people] } let(:create_person) { commands[:people].create } - describe 'using arrays' do - before do - conn.create_table :pg_people do - primary_key :id - String :name - column :fields, :jsonb - end + %i(json jsonb).each do |type| + if type == :json + json_hash = Sequel::Postgres::JSONHash.method(:new) + json_array = Sequel::Postgres::JSONArray.method(:new) + else + json_hash = Sequel::Postgres::JSONBHash.method(:new) + json_array = Sequel::Postgres::JSONBArray.method(:new) + end - conf.commands(:people) do - define(:create) - define(:update) - end + describe "using arrays in #{ type }" do + before do + conn.create_table :pg_people do + primary_key :id + String :name + column :fields, type + end - create_person.(name: 'John Doe', fields: [{ name: 'age', value: '30' }, - { name: 'height', value: 180 }]) - create_person.(name: 'Jade Doe', fields: [{ name: 'age', value: '25' }]) - end + conf.commands(:people) do + define(:create) + define(:update) + end - it 'allows to query jsonb by inclusion' do - expect(people.select(:name).where { fields.contain([value: '30']) }.one). - to eql(name: 'John Doe') - end + create_person.(name: 'John Doe', fields: [{ name: 'age', value: '30' }, + { name: 'height', value: 180 }]) + create_person.(name: 'Jade Doe', fields: [{ name: 'age', value: '25' }]) + end - it 'cat project result of contains' do - expect(people.select { fields.contain([value: '30']).as(:contains) }.to_a). - to eql([{ contains: true }, { contains: false }]) - end + it 'fetches data from jsonb array by index' do + expect(people.select { [fields.get(1).as(:field)] }.where(name: 'John Doe').one). + to eql(field: json_hash['name' => 'height', 'value' => 180]) + end - it 'fetches data from jsonb array by index' do - expect(people.select { [fields.get(1).as(:field)] }.where(name: 'John Doe').one). - to eql(field: jsonb_hash['name' => 'height', 'value' => 180]) - end + it 'fetches data from jsonb array' do + expect(people.select { fields.get(1).get_text('value').as(:height) }.where(name: 'John Doe').one). + to eql(height: '180') + end - it 'fetches data from jsonb array' do - expect(people.select { fields.get(1).get_text('value').as(:height) }.where(name: 'John Doe').one). - to eql(height: '180') - end + it 'fetches data with path' do + expect(people.select(people[:fields].get_text('1', 'value').as(:height)).to_a). + to eql([{ height: '180' }, { height: nil }]) + end - it 'fetches data with path' do - expect(people.select(people[:fields].get_text('1', 'value').as(:height)).to_a). - to eql([{ height: '180' }, { height: nil }]) - end + if type == :jsonb + it 'allows to query jsonb by inclusion' do + expect(people.select(:name).where { fields.contain([value: '30']) }.one). + to eql(name: 'John Doe') + end - it 'deletes key from result' do - expect(people.select { fields.delete(0).as(:result) }.limit(1).one). - to eq(result: jsonb_array[['name' => 'height', 'value' => 180]]) - end + it 'cat project result of contains' do + expect(people.select { fields.contain([value: '30']).as(:contains) }.to_a). + to eql([{ contains: true }, { contains: false }]) + end - it 'deletes by path' do - expect(people.select { fields.delete('0', 'name').delete('1', 'name').as(:result) }.limit(1).one). - to eq(result: jsonb_array[[{ 'value' => '30' }, { 'value' => 180 }]]) - end + it 'deletes key from result' do + expect(people.select { fields.delete(0).as(:result) }.limit(1).one). + to eq(result: json_array[['name' => 'height', 'value' => 180]]) + end - it 'concatenates JSON values' do - expect(people.select { (fields + [name: 'height', value: 165]).as(:result) }.by_pk(2).one). - to eq(result: jsonb_array[[{ 'name' => 'age', 'value' => '25' }, - { 'name' => 'height', 'value' => 165 }]]) - end - end + it 'deletes by path' do + expect(people.select { fields.delete('0', 'name').delete('1', 'name').as(:result) }.limit(1).one). + to eq(result: json_array[[{ 'value' => '30' }, { 'value' => 180 }]]) + end - describe 'using map' do - before do - conn.create_table :pg_people do - primary_key :id - String :name - column :data, :jsonb + it 'concatenates JSON values' do + expect(people.select { (fields + [name: 'height', value: 165]).as(:result) }.by_pk(2).one). + to eq(result: json_array[[{ 'name' => 'age', 'value' => '25' }, + { 'name' => 'height', 'value' => 165 }]]) + end end + end - conf.commands(:people) do - define(:create) - define(:update) - end + if type == :jsonb + describe "using maps in #{ type }" do + before do + conn.create_table :pg_people do + primary_key :id + String :name + column :data, type + end - create_person.(name: 'John Doe', data: { age: 30, height: 180 }) - create_person.(name: 'Jade Doe', data: { age: 25 }) - end + conf.commands(:people) do + define(:create) + define(:update) + end - it 'queries data by inclusion' do - expect(people.select(:name).where { data.contain(age: 30) }.one). - to eql(name: 'John Doe') - end + create_person.(name: 'John Doe', data: { age: 30, height: 180 }) + create_person.(name: 'Jade Doe', data: { age: 25 }) + end - it 'queries data by left inclusion' do - expect(people.select(:name).where { data.contained_by(age: 25, foo: 'bar') }.one). - to eql(name: 'Jade Doe') - end + it 'queries data by inclusion' do + expect(people.select(:name).where { data.contain(age: 30) }.one). + to eql(name: 'John Doe') + end - it 'checks for key presence' do - expect(people.select { data.has_key('height').as(:there) }.to_a). - to eql([{ there: true }, { there: false }]) + it 'queries data by left inclusion' do + expect(people.select(:name).where { data.contained_by(age: 25, foo: 'bar') }.one). + to eql(name: 'Jade Doe') + end - expect(people.select(:name).where { data.has_any_key('height', 'width') }.one). - to eql(name: 'John Doe') + it 'checks for key presence' do + expect(people.select { data.has_key('height').as(:there) }.to_a). + to eql([{ there: true }, { there: false }]) - expect(people.select(:name).where { data.has_all_keys('height', 'age') }.one). - to eql(name: 'John Doe') - end + expect(people.select(:name).where { data.has_any_key('height', 'width') }.one). + to eql(name: 'John Doe') - it 'concatenates JSON values' do - expect(people.select { data.merge(height: 165).as(:result) }.by_pk(2).one). - to eql(result: jsonb_hash['age' => 25, 'height' => 165]) - end + expect(people.select(:name).where { data.has_all_keys('height', 'age') }.one). + to eql(name: 'John Doe') + end - it 'deletes key from result' do - expect(people.select { data.delete('height').as(:result) }.to_a). - to eql([{ result: jsonb_hash['age' => 30] }, - { result: jsonb_hash['age' => 25] }]) + it 'concatenates JSON values' do + expect(people.select { data.merge(height: 165).as(:result) }.by_pk(2).one). + to eql(result: json_hash['age' => 25, 'height' => 165]) + end + + it 'deletes key from result' do + expect(people.select { data.delete('height').as(:result) }.to_a). + to eql([{ result: json_hash['age' => 30] }, + { result: json_hash['age' => 25] }]) + end + end end end describe 'using array types' do before do