diff --git a/.github/workflows/e2e_test.yml b/.github/workflows/e2e_test.yml index 7ad1154a1..df2a2e681 100644 --- a/.github/workflows/e2e_test.yml +++ b/.github/workflows/e2e_test.yml @@ -16,10 +16,13 @@ jobs: strategy: fail-fast: false matrix: - ruby: [ jruby, ruby-3.3.5 ] - neo4j: [ 5.23.0 ] - active_model: [ 7.1.4, 7.2.1 ] + ruby: [ jruby, ruby ] + neo4j: [ 5.26.0 ] + active_model: [ 7.1.5.1, 7.2.2.1 ] include: + - ruby: ruby + neo4j: 5.26.0 + active_model: 8.0.1 - ruby: jruby java-version: 17 env: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 635f94489..49cab3612 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,16 +16,19 @@ jobs: strategy: fail-fast: false matrix: - ruby: [ jruby, ruby-3.1.6 ] - neo4j: [ 5.23.0 ] - active_model: [ 7.0.8, 7.1.4, 7.2.1 ] + ruby: [ jruby, ruby ] + neo4j: [ 5.26.0 ] + active_model: [ 7.1.5.1, 7.2.2.1 ] include: - - ruby: ruby-3.2.5 - neo4j: 5.23.0 - active_model: 7.1.4 - - ruby: ruby-3.3.5 - neo4j: 5.23.0 - active_model: 7.1.4 + - ruby: ruby-3.2.6 + neo4j: 5.26.0 + active_model: 7.1.5.1 + - ruby: ruby-3.3.6 + neo4j: 5.26.0 + active_model: 7.1.5.1 + - ruby: ruby + neo4j: 5.26.0 + active_model: 8.0.1 - ruby: jruby java-version: 17 env: diff --git a/activegraph.gemspec b/activegraph.gemspec index 0e145d27b..542cb87b0 100644 --- a/activegraph.gemspec +++ b/activegraph.gemspec @@ -7,7 +7,7 @@ Gem::Specification.new do |s| s.name = 'activegraph' s.version = ActiveGraph::VERSION - s.required_ruby_version = '>= 2.6' + s.required_ruby_version = '>= 3.1' s.authors = 'Andreas Ronge, Brian Underwood, Chris Grigg, Heinrich Klobuczek' s.email = 'andreas.ronge@gmail.com, public@brian-underwood.codes, chris@subvertallmedia.com, heinrich@mail.com' @@ -30,9 +30,9 @@ DESCRIPTION 'bug_tracker_uri' => 'https://github.com/neo4jrb/activegraph/issues' } - s.add_dependency('activemodel', '>= 7') + s.add_dependency('activemodel') s.add_dependency('i18n', '!= 1.8.8') # https://github.com/jruby/jruby/issues/6547 - s.add_dependency('neo4j-ruby-driver', '>= 5.7.0.alpha.1') + s.add_dependency('neo4j-ruby-driver', '>= 5.7.0.alpha.3') s.add_dependency('orm_adapter', '>= 0.5.0') s.add_dependency('sorted_set') s.add_development_dependency('guard') diff --git a/lib/active_graph/migration.rb b/lib/active_graph/migration.rb index e7d0a0680..a95a87b36 100644 --- a/lib/active_graph/migration.rb +++ b/lib/active_graph/migration.rb @@ -39,7 +39,8 @@ def initialize(path = default_path) def migrate ActiveGraph.deprecator.warn '`AddIdProperty` task is deprecated and may be removed from future releases. ' \ - 'Create a new migration and use the `populate_id_property` helper.', caller + 'Create a new migration and use the `populate_id_property` helper.', + caller_locations models = ActiveSupport::HashWithIndifferentAccess.new(YAML.load_file(models_filename))[:models] output 'This task will add an ID Property every node in the given file.' output 'It may take a significant amount of time, please be patient.' @@ -108,7 +109,6 @@ def setup # print_output message # end - # def id_batch_set(label, id_property, new_ids, count) # tx = ActiveGraph::Base.new_transaction diff --git a/lib/active_graph/relationship/query.rb b/lib/active_graph/relationship/query.rb index c58bd3699..895105c49 100644 --- a/lib/active_graph/relationship/query.rb +++ b/lib/active_graph/relationship/query.rb @@ -49,7 +49,7 @@ def last private def deprecation_warning! - ActiveGraph.deprecator.warn 'The ActiveGraph::Relationship::Query module has been deprecated and will be removed in a future version of the gem.', caller + ActiveGraph.deprecator.warn 'The ActiveGraph::Relationship::Query module has been deprecated and will be removed in a future version of the gem.', caller_locations end def where_query diff --git a/lib/active_graph/version.rb b/lib/active_graph/version.rb index 77b4afd25..020e4bd62 100644 --- a/lib/active_graph/version.rb +++ b/lib/active_graph/version.rb @@ -1,3 +1,3 @@ module ActiveGraph - VERSION = '12.0.0.beta.4' + VERSION = '12.0.0.beta.5' end diff --git a/spec/e2e/association_dependency_spec.rb b/spec/e2e/association_dependency_spec.rb index dbc1c1f95..5d28e37d3 100644 --- a/spec/e2e/association_dependency_spec.rb +++ b/spec/e2e/association_dependency_spec.rb @@ -104,7 +104,6 @@ def routing_setup @route2 = Route.create(name: 'Secondary Route') @tour.routes << [@route1, @route2] - # Pro Tip from Chris: No good metal shows happen in Manhattan. # Boston is iffy, too. city_names = %w(Philadelphia Brooklyn Manhattan Providence Boston) @@ -217,7 +216,7 @@ def routing_setup it 'deletes only orphans' do rel_1.destroy expect { BadModel.find(bad_model_1.id) }.to raise_error(ActiveGraph::Node::Labels::RecordNotFound) - expect { BadModel.find(bad_model_2.id) }.not_to raise_error + expect { BadModel.find(bad_model_2.id) }.not_to raise_error end end @@ -365,7 +364,7 @@ def routing_setup describe 'invalid options' do it 'raises an error when an invalid option is passed' do - expect { Stop.has_many(:out, :fooz, dependent: :foo).to raise_error } + expect { Stop.has_many(:out, :fooz, dependent: :foo) }.to raise_error end end end diff --git a/spec/e2e/query_spec.rb b/spec/e2e/query_spec.rb index c1eaa44fd..301c0e406 100644 --- a/spec/e2e/query_spec.rb +++ b/spec/e2e/query_spec.rb @@ -3,7 +3,6 @@ clear_model_memory_caches end - let(:student_interests_association_options) { {} } before(:each) do @@ -42,11 +41,11 @@ def self.ordered_by_subject has_many :out, :lessons, rel_class: 'IsEnrolledFor' - has_many :out, :interests, {type: nil}.merge(scoped_interests_options) + has_many :out, :interests, { type: nil }.merge(scoped_interests_options) has_many :both, :favorite_teachers, type: nil, model_class: 'Teacher' has_many :both, :hated_teachers, type: nil, model_class: 'Teacher' - has_many :in, :winning_lessons, model_class: 'Lesson', origin: :teachers_pet + has_many :in, :winning_lessons, model_class: 'Lesson', origin: :teachers_pet end stub_relationship_class('IsEnrolledFor') do @@ -167,7 +166,6 @@ def self.ordered_by_subject let!(:math) { Interest.create(name: 'Math') } let!(:monster_trucks) { Interest.create(name: 'Monster Trucks') } - it 'evaluates `all` lazily' do result = Teacher.all expect(result).to be_a(ActiveGraph::Node::Query::QueryProxy) @@ -209,10 +207,10 @@ def self.ordered_by_subject describe '.merge' do let(:timestamps) { [1, 1, 2, 3].map(&DateTime.method(:new)) } - let(:merge_attrs) { {name: 'Dr. Dre'} } + let(:merge_attrs) { { name: 'Dr. Dre' } } let(:on_match_clause) { {} } let(:on_create_clause) { {} } - let(:set_attrs) { {status: 'on create status'} } + let(:set_attrs) { { status: 'on create status' } } before { allow(DateTime).to receive(:now).and_return(*timestamps) } after { expect(Teacher.count).to eq 1 } @@ -235,7 +233,7 @@ def self.ordered_by_subject its(:labels) { is_expected.to match_array [:TeacherFoo, :Substitute] } end - let_context 'on_create', on_create_clause: {age: 49} do + let_context 'on_create', on_create_clause: { age: 49 } do its(:age) { is_expected.to eq 49 } its(:status) { is_expected.to eq 'on create status' } @@ -244,8 +242,7 @@ def self.ordered_by_subject end end - - let_context 'on_merge', on_match_clause: {age: 50}, on_create_clause: {age: 49}, set_attrs: {status: 'on match status'} do + let_context 'on_merge', on_match_clause: { age: 50 }, on_create_clause: { age: 49 }, set_attrs: { status: 'on match status' } do before { Teacher.merge(on_create_clause.merge(merge_attrs)) } its(:age) { is_expected.to eq 50 } @@ -286,7 +283,7 @@ def self.ordered_by_subject end it 'also sets properties on create' do - Teacher.find_or_create({name: 'Dr. Harold Samuels'}, age: 34) + Teacher.find_or_create({ name: 'Dr. Harold Samuels' }, age: 34) expect(Teacher.count).to eq(1) @@ -298,7 +295,7 @@ def self.ordered_by_subject end it 'overrides default properties on create' do - Teacher.find_or_create({name: 'Dr. Harold Samuels'}, age: 34, status: 'inactive') + Teacher.find_or_create({ name: 'Dr. Harold Samuels' }, age: 34, status: 'inactive') expect(Teacher.count).to eq(1) @@ -343,7 +340,7 @@ def custom_prop_method end context 'on match' do - let(:original) { Teacher.find_or_create({name: 'Dr. Harold Samuels'}, age: 34) } + let(:original) { Teacher.find_or_create({ name: 'Dr. Harold Samuels' }, age: 34) } before(:each) { original } @@ -355,7 +352,7 @@ def custom_prop_method end it 'updates nothing' do - teacher = Teacher.find_or_create({name: 'Dr. Harold Samuels'}, age: 0) + teacher = Teacher.find_or_create({ name: 'Dr. Harold Samuels' }, age: 0) expect(teacher.id).to eq(original.id) expect(teacher.name).to eq('Dr. Harold Samuels') @@ -550,13 +547,13 @@ def custom_prop_method describe 'on classes' do before(:each) do danny.lessons << math101 - danny.lessons(:l, :r).query.set(r: {grade: 65}).exec + danny.lessons(:l, :r).query.set(r: { grade: 65 }).exec bobby.lessons << math101 - bobby.lessons(:l, :r).query.set(r: {grade: 71}) + bobby.lessons(:l, :r).query.set(r: { grade: 71 }) math101.teachers << othmar - math101.teachers(:t, :r).query.set(r: {since: 2001}).exec + math101.teachers(:t, :r).query.set(r: { since: 2001 }).exec sandra.lessons << ss101 end @@ -565,9 +562,8 @@ def custom_prop_method it { expect(Student.as(:student).where(age: 15).lessons(:lesson).where(level: 101).pluck(:student)).to eq([danny]) } it { expect(Student.where(age: 15).lessons(:lesson).where(level: '101').pluck(:lesson)).not_to eq([[othmar]]) } it do - expect(Student.as(:student).where(age: 15).lessons(:lesson).where(level: 101).pluck(:student)).to eq( - Student.as(:student).node_where(age: 15).lessons(:lesson).node_where(level: 101).pluck(:student) - ) + expect(Student.as(:student).where(age: 15).lessons(:lesson).where(level: 101).pluck(:student)) + .to eq( Student.as(:student).node_where(age: 15).lessons(:lesson).node_where(level: 101).pluck(:student) ) end end @@ -687,8 +683,9 @@ def custom_prop_method expect(Teacher.where(date: date).to_cypher_with_params).to include(converted_date.to_s) expect(Teacher.where(datetime: datetime).to_cypher_with_params).to include(converted_datetime.to_s) expect(Teacher.where(time: time).to_cypher_with_params).to include(converted_time.to_s) - expect(Teacher.where(age: '1').to_cypher_with_params).to include(':result_teacher2_age=>1') - expect(Student.where(likely_to_succeed: 'false').to_cypher_with_params).to include(':result_student2_likely_to_succeed=>false') + expect(Teacher.where(age: '1').to_cypher_with_params).to include({ result_teacher2_age: 1 }.to_s) + expect(Student.where(likely_to_succeed: 'false').to_cypher_with_params) + .to include({ result_student2_likely_to_succeed: false }.to_s) end context '...and values already in the destination format' do @@ -696,8 +693,9 @@ def custom_prop_method expect(Teacher.where(date: converted_date).to_cypher_with_params).to include(converted_date.to_s) expect(Teacher.where(datetime: converted_datetime).to_cypher_with_params).to include(converted_datetime.to_s) expect(Teacher.where(time: converted_time).to_cypher_with_params).to include(converted_time.to_s) - expect(Teacher.where(age: 1).to_cypher_with_params).to include(':result_teacher2_age=>1') - expect(Student.where(likely_to_succeed: false).to_cypher_with_params).to include(':result_student2_likely_to_succeed=>false') + expect(Teacher.where(age: 1).to_cypher_with_params).to include({ result_teacher2_age: 1 }.to_s) + expect(Student.where(likely_to_succeed: false).to_cypher_with_params) + .to include({ result_student2_likely_to_succeed: false }.to_s) end end @@ -741,9 +739,9 @@ def custom_prop_method describe 'Associations with `unique` set' do let(:from_node) { Student.create } - let(:to_node) { Interest.create } - let(:first_props) { {score: 900} } - let(:second_props) { {score: 1000} } + let(:to_node) { Interest.create } + let(:first_props) { { score: 900 } } + let(:second_props) { { score: 1000 } } let(:changed_props_create) { proc { from_node.interests.create(to_node, second_props) } } before do @@ -752,7 +750,7 @@ def custom_prop_method end context 'with `true` option' do - let(:student_interests_association_options) { {type: nil, unique: true} } + let(:student_interests_association_options) { { type: nil, unique: true } } it 'becomes :none' do expect(ActiveGraph::Shared::FilteredHash).to receive(:new).with(instance_of(Hash), :none).and_call_original @@ -761,7 +759,7 @@ def custom_prop_method end context 'with :none open' do - let(:student_interests_association_options) { {type: nil, unique: :none} } + let(:student_interests_association_options) { { type: nil, unique: :none } } it 'does not create additional rels, even when properties change' do expect do @@ -771,7 +769,7 @@ def custom_prop_method end context 'with `:all` option' do - let(:student_interests_association_options) { {type: nil, unique: :all} } + let(:student_interests_association_options) { { type: nil, unique: :all } } it 'creates additional rels when properties change' do expect { changed_props_create.call }.to change { from_node.interests.count } @@ -779,7 +777,7 @@ def custom_prop_method end context 'with {on: [keys]} option' do - let(:student_interests_association_options) { {type: nil, unique: {on: :score}} } + let(:student_interests_association_options) { { type: nil, unique: { on: :score } } } context 'and a listed property changes' do it 'creates a new rel' do diff --git a/spec/unit/migrations/schema_spec.rb b/spec/unit/migrations/schema_spec.rb index 59cfd5c15..ce2b25247 100644 --- a/spec/unit/migrations/schema_spec.rb +++ b/spec/unit/migrations/schema_spec.rb @@ -14,9 +14,9 @@ let(:constraints) { [] } let(:range_index) { 'CREATE RANGE INDEX `range_index` FOR (n:`Person`) ON (n.`nickname`)' } - let(:point_index) { "CREATE POINT INDEX `point_index` FOR (n:`Person`) ON (n.`location`) OPTIONS {indexConfig: {`spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0],`spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0],`spatial.cartesian.max`: [1000000.0, 1000000.0],`spatial.cartesian.min`: [-1000000.0, -1000000.0],`spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0],`spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0],`spatial.wgs-84.max`: [180.0, 90.0],`spatial.wgs-84.min`: [-180.0, -90.0]}, indexProvider: 'point-1.0'}" } - let(:fulltext_index) { "CREATE FULLTEXT INDEX `fulltext_index` FOR (n:`Friend`) ON EACH [n.`name`] OPTIONS {indexConfig: {`fulltext.analyzer`: 'swedish',`fulltext.eventually_consistent`: false}, indexProvider: 'fulltext-1.0'}" } - let(:text_index) { "CREATE TEXT INDEX `text_index` FOR ()-[r:`KNOWS`]-() ON (r.`city`) OPTIONS {indexConfig: {}, indexProvider: 'text-2.0'}" } + let(:point_index) { "CREATE POINT INDEX `point_index` FOR (n:`Person`) ON (n.`location`) OPTIONS {indexConfig: {`spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0],`spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0],`spatial.cartesian.max`: [1000000.0, 1000000.0],`spatial.cartesian.min`: [-1000000.0, -1000000.0],`spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0],`spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0],`spatial.wgs-84.max`: [180.0, 90.0],`spatial.wgs-84.min`: [-180.0, -90.0]}}" } + let(:fulltext_index) { "CREATE FULLTEXT INDEX `fulltext_index` FOR (n:`Friend`) ON EACH [n.`name`] OPTIONS {indexConfig: {`fulltext.analyzer`: 'swedish',`fulltext.eventually_consistent`: false}}" } + let(:text_index) { "CREATE TEXT INDEX `text_index` FOR ()-[r:`KNOWS`]-() ON (r.`city`)" } let(:unique_constraint) { 'CREATE CONSTRAINT `unique_constraint` FOR (n:`Person`) REQUIRE (n.`name`) IS UNIQUE' } let(:not_null_rel_prop_constraint) { 'CREATE CONSTRAINT `not_null_rel_prop_constraint` FOR ()-[r:`LIKED`]-() REQUIRE (r.`when`) IS NOT NULL' } @@ -28,14 +28,14 @@ end if ActiveGraph::Base.version?('<4.4') - let(:range_index) { "CREATE INDEX `range_index` FOR (n:`Person`) ON (n.`nickname`) OPTIONS {indexConfig: {`spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0],`spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0],`spatial.cartesian.max`: [1000000.0, 1000000.0],`spatial.cartesian.min`: [-1000000.0, -1000000.0],`spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0],`spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0],`spatial.wgs-84.max`: [180.0, 90.0],`spatial.wgs-84.min`: [-180.0, -90.0]}, indexProvider: 'native-btree-1.0'}" } + let(:range_index) { "CREATE INDEX `range_index` FOR (n:`Person`) ON (n.`nickname`) OPTIONS {indexConfig: {`spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0],`spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0],`spatial.cartesian.max`: [1000000.0, 1000000.0],`spatial.cartesian.min`: [-1000000.0, -1000000.0],`spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0],`spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0],`spatial.wgs-84.max`: [180.0, 90.0],`spatial.wgs-84.min`: [-180.0, -90.0]}}" } let(:point_index) {} let(:text_index) {} - let(:unique_constraint) { "CREATE CONSTRAINT `unique_constraint` ON (n:`Person`) ASSERT (n.`name`) IS UNIQUE OPTIONS {indexConfig: {`spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0],`spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0],`spatial.cartesian.max`: [1000000.0, 1000000.0],`spatial.cartesian.min`: [-1000000.0, -1000000.0],`spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0],`spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0],`spatial.wgs-84.max`: [180.0, 90.0],`spatial.wgs-84.min`: [-180.0, -90.0]}, indexProvider: 'native-btree-1.0'}" } + let(:unique_constraint) { "CREATE CONSTRAINT `unique_constraint` ON (n:`Person`) ASSERT (n.`name`) IS UNIQUE OPTIONS {indexConfig: {`spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0],`spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0],`spatial.cartesian.max`: [1000000.0, 1000000.0],`spatial.cartesian.min`: [-1000000.0, -1000000.0],`spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0],`spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0],`spatial.wgs-84.max`: [180.0, 90.0],`spatial.wgs-84.min`: [-180.0, -90.0]}}" } let(:not_null_rel_prop_constraint) { 'CREATE CONSTRAINT `not_null_rel_prop_constraint` ON ()-[r:`LIKED`]-() ASSERT (r.`when`) IS NOT NULL' } let(:not_null_node_prop_constraint) { 'CREATE CONSTRAINT `not_null_node_prop_constraint` ON (n:`Person`) ASSERT (n.`name`) IS NOT NULL' } - let(:node_key_constraint) { "CREATE CONSTRAINT `node_key_constraint` ON (n:`Person`) ASSERT (n.`name`, n.`surname`) IS NODE KEY OPTIONS {indexConfig: {`spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0],`spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0],`spatial.cartesian.max`: [1000000.0, 1000000.0],`spatial.cartesian.min`: [-1000000.0, -1000000.0],`spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0],`spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0],`spatial.wgs-84.max`: [180.0, 90.0],`spatial.wgs-84.min`: [-180.0, -90.0]}, indexProvider: 'native-btree-1.0'}" } + let(:node_key_constraint) { "CREATE CONSTRAINT `node_key_constraint` ON (n:`Person`) ASSERT (n.`name`, n.`surname`) IS NODE KEY OPTIONS {indexConfig: {`spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0],`spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0],`spatial.cartesian.max`: [1000000.0, 1000000.0],`spatial.cartesian.min`: [-1000000.0, -1000000.0],`spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0],`spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0],`spatial.wgs-84.max`: [180.0, 90.0],`spatial.wgs-84.min`: [-180.0, -90.0]}}" } end if ActiveGraph::Base.version?('<4.3') diff --git a/spec/unit/node/has_n/association_spec.rb b/spec/unit/node/has_n/association_spec.rb index 41da7c49c..2d2298599 100644 --- a/spec/unit/node/has_n/association_spec.rb +++ b/spec/unit/node/has_n/association_spec.rb @@ -2,7 +2,7 @@ class Default end describe ActiveGraph::Node::HasN::Association do - let(:options) { {type: nil} } + let(:options) { { type: nil } } let(:name) { :default } let(:direction) { :out } @@ -34,13 +34,13 @@ class Default end context 'origin and type specified' do - let(:options) { {type: :bar, origin: :foo} } + let(:options) { { type: :bar, origin: :foo } } it { expect { subject }.to raise_error(ArgumentError) } end context 'type and rel_class specified' do - let(:options) { {type: :foo, origin: :bar} } + let(:options) { { type: :foo, origin: :bar } } it { expect { subject }.to raise_error(ArgumentError) } end @@ -50,13 +50,13 @@ class Default before do stub_const('FooClass', Class.new) end - let(:options) { {type: false, model_class: :FooClass} } + let(:options) { { type: false, model_class: :FooClass } } it { expect(subject.relationship_type).to be_falsey } end end context 'origin and rel_class specified' do - let(:options) { {origin: :foo, rel_class: :bar} } + let(:options) { { origin: :foo, rel_class: :bar } } it { expect { subject }.to raise_error(ArgumentError) } end @@ -77,7 +77,6 @@ def self.type end end - it { is_expected.to eq('-[]->') } context 'inbound' do @@ -98,7 +97,7 @@ def self.type it { is_expected.to eq('-[:`DEFAULT`]->') } context 'properties given' do - let(:properties) { {foo: 1, bar: 'test'} } + let(:properties) { { foo: 1, bar: 'test' } } it { is_expected.to eq('-[:`DEFAULT` {foo: 1, bar: "test"}]->') } end @@ -110,19 +109,19 @@ def self.type it { is_expected.to eq('-[fooy]->') } context 'properties given' do - let(:properties) { {foo: 1, bar: 'test'} } + let(:properties) { { foo: 1, bar: 'test' } } it { is_expected.to eq('-[fooy {foo: 1, bar: "test"}]->') } end context 'relationship type given' do - let(:options) { {type: :new_type} } + let(:options) { { type: :new_type } } it { is_expected.to eq('-[fooy:`new_type`]->') } end context 'rel_class given' do - let(:options) { {rel_class: :MyRel} } + let(:options) { { rel_class: :MyRel } } it { is_expected.to eq('-[fooy:`ar_type`]->') } end @@ -133,7 +132,7 @@ def self.type it { is_expected.to eq('-[fooy:`DEFAULT`]->') } context 'properties given' do - let(:properties) { {foo: 1, bar: 'test'} } + let(:properties) { { foo: 1, bar: 'test' } } it { is_expected.to eq('-[fooy:`DEFAULT` {foo: 1, bar: "test"}]->') } end @@ -205,28 +204,28 @@ def self.type context 'as a Hash' do context 'with :min and :max specified' do - let(:length) { {min: 2, max: 6} } + let(:length) { { min: 2, max: 6 } } it { is_expected.to eq('-[*2..6]->') } end context 'with only :min specified' do - let(:length) { {min: 2} } + let(:length) { { min: 2 } } it { is_expected.to eq('-[*2..]->') } end context 'with only :max specified' do - let(:length) { {max: 2} } + let(:length) { { max: 2 } } it { is_expected.to eq('-[*..2]->') } end context 'with both :min and :max missing' do - let(:length) { {foo: 2, bar: 3} } + let(:length) { { foo: 2, bar: 3 } } it 'raises an error' do - expect { subject }.to raise_error ArgumentError, 'Invalid value for rel_length ({:foo=>2, :bar=>3}): Hash keys should be a subset of [:min, :max]' + expect { subject }.to raise_error ArgumentError, "Invalid value for rel_length (#{{ foo: 2, bar: 3 }.to_s}): Hash keys should be a subset of [:min, :max]" end end end @@ -249,18 +248,18 @@ def self.type end context 'with relationship variable given' do - let(:length) { {min: 0} } + let(:length) { { min: 0 } } let(:var) { :r } it { is_expected.to eq('-[r*0..]->') } context 'with relationship type given' do - let(:options) { {type: :TYPE} } + let(:options) { { type: :TYPE } } it { is_expected.to eq('-[r:`TYPE`*0..]->') } context 'with properties given' do - let(:properties) { {foo: 1, bar: 'test'} } + let(:properties) { { foo: 1, bar: 'test' } } it { is_expected.to eq('-[r:`TYPE`*0.. {foo: 1, bar: "test"}]->') } end @@ -278,10 +277,9 @@ def self.type it { is_expected.to eq(['::Burz']) } end - context 'specified model class' do context 'specified as string' do - let(:options) { {type: :foo, model_class: 'Bizzl'} } + let(:options) { { type: :foo, model_class: 'Bizzl' } } it { is_expected.to eq(['::Bizzl']) } end @@ -291,7 +289,7 @@ def self.type stub_const 'Fizzl', Class.new { include ActiveGraph::Node } end - let(:options) { {type: :foo, model_class: 'Fizzl'} } + let(:options) { { type: :foo, model_class: 'Fizzl' } } it { is_expected.to eq(['::Fizzl']) } end @@ -304,12 +302,13 @@ def self.type def self.name 'TheRel' end + include ActiveGraph::Relationship from_class :any end) end - let(:options) { {rel_class: 'TheRel'} } + let(:options) { { rel_class: 'TheRel' } } context 'targeting any class' do before(:each) do @@ -346,14 +345,14 @@ def self.name describe 'target_class' do subject { association.target_classes } - let(:options) { {type: nil, model_class: 'BadClass'} } + let(:options) { { type: nil, model_class: 'BadClass' } } context 'with invalid target class name' do it { expect { subject }.to raise_error ArgumentError, /Could not find class.*BadClass/ } end context 'target_class_names defines class which exists, but is not Node' do - let(:options) { {type: nil, model_class: 'Integer'} } + let(:options) { { type: nil, model_class: 'Integer' } } context 'with invalid target class name' do it { expect { subject }.to raise_error ArgumentError, /Integer.* is not an Node model/ } @@ -392,7 +391,7 @@ def self.name describe 'unique' do context 'true' do - let(:options) { {type: :foo, unique: true} } + let(:options) { { type: :foo, unique: true } } it do expect(subject).to be_unique @@ -401,7 +400,7 @@ def self.name context 'false' do let(:type) { :has_many } - let(:options) { {type: :foo, unique: false} } + let(:options) { { type: :foo, unique: false } } it { expect(subject).not_to be_unique } end