diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index f1c315549..08b5fdd3c 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -42,7 +42,6 @@ Layout/EmptyLineBetweenDefs: # SupportedStyles: auto_detection, squiggly, active_support, powerpack, unindent Layout/IndentHeredoc: Exclude: - - 'bin/neo4j-jars' - 'lib/neo4j/migration.rb' - 'lib/neo4j/migrations/runner.rb' - 'lib/neo4j/model_schema.rb' diff --git a/Gemfile b/Gemfile index 8e75b6fd6..f52d3808d 100644 --- a/Gemfile +++ b/Gemfile @@ -7,6 +7,8 @@ gemspec branch = ENV['NEO4J_CORE_BRANCH'] || ENV['TRAVIS_PULL_REQUEST_BRANCH'] || ENV['TRAVIS_BRANCH'] slug = !ENV['TRAVIS_PULL_REQUEST_SLUG'].to_s.empty? ? ENV['TRAVIS_PULL_REQUEST_SLUG'] : ENV['TRAVIS_REPO_SLUG'] +# gem 'neo4j-ruby-driver', path: '../neo4j-ruby-driver' + gem 'listen', '< 3.1' active_model_version = ENV['ACTIVE_MODEL_VERSION'] diff --git a/bin/neo4j-jars b/bin/neo4j-jars deleted file mode 100755 index e1dab5f45..000000000 --- a/bin/neo4j-jars +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env ruby - -require 'neo4j' - -if ARGV.empty? - puts < - -TEXT - exit -end - -if ARGV.include?('community') - require 'neo4j-community' # not really needed -elsif ARGV.include?('advanced') - require 'neo4j-advanced' # not really needed -elsif ARGV.include?('enterprise') - require 'neo4j-enterprise' # not really needed -else - puts 'Expected community, advanced, enterprise' - exit(-1) -end - -lib_dir = File.join(Dir.pwd, 'lib') -fail "Expected a lib folder where to copy the jars file, mkdir #{lib_dir}? " unless File.exist?(lib_dir) - -files = $CLASSPATH.find_all { |x| x =~ /\.jar$/ }.collect { |y| y.sub('file:', '') } -files.each { |file| FileUtils.cp(file, lib_dir) } - -puts "copied #{files.size} files to #{lib_dir}" diff --git a/lib/neo4j/core/cypher_session/driver.rb b/lib/neo4j/core/cypher_session/driver.rb index 2cac74928..d545fc785 100644 --- a/lib/neo4j/core/cypher_session/driver.rb +++ b/lib/neo4j/core/cypher_session/driver.rb @@ -10,6 +10,7 @@ require 'neo4j/core/cypher_session/query_builder' require 'neo4j/core/cypher_session/has_uri' require 'neo4j/core/cypher_session/schema' +require 'neo4j/core/cypher_session/responses' module Neo4j module Core @@ -18,6 +19,7 @@ class Driver include Neo4j::Core::Instrumentable include HasUri include Schema + include Responses USER_AGENT_STRING = "neo4j-gem/#{::Neo4j::VERSION} (https://github.com/neo4jrb/neo4j)" @@ -126,11 +128,10 @@ def close def query_set(transaction, queries, options = {}) setup_queries!(queries, transaction, skip_instrumentation: options[:skip_instrumentation]) - responses = queries.map do |query| - transaction.root_tx.run(query.cypher, query.parameters) + self.wrap_level = options[:wrap_level] || @options[:wrap_level] || Neo4j::Core::Config.wrapping_level + queries.map do |query| + result_from_data(transaction.root_tx.run(query.cypher, query.parameters)) end - wrap_level = options[:wrap_level] || @options[:wrap_level] - Responses.new(responses, wrap_level: wrap_level).to_a rescue Neo4j::Driver::Exceptions::Neo4jException => e raise Neo4j::Core::CypherSession::CypherError.new_from(e.code, e.message) # , e.stack_track.to_a end diff --git a/lib/neo4j/core/cypher_session/responses.rb b/lib/neo4j/core/cypher_session/responses.rb index 6d449fd6b..5d8933a53 100644 --- a/lib/neo4j/core/cypher_session/responses.rb +++ b/lib/neo4j/core/cypher_session/responses.rb @@ -3,22 +3,13 @@ module Neo4j module Core module CypherSession - class Responses - include Enumerable + module Responses + extend ActiveSupport::Concern - def initialize(responses, options = {}) - @responses = responses - @wrap_level = options[:wrap_level] || Neo4j::Core::Config.wrapping_level + included do + attr_accessor :wrap_level end - def each - @responses.each do |response| - yield result_from_data(response) - end - end - - private - def result_from_data(entities_data) rows = entities_data.map do |entity_data| wrap(entity_data.values) @@ -27,27 +18,31 @@ def result_from_data(entities_data) Neo4j::Core::CypherSession::Result.new(entities_data.keys, rows) end + private + def wrap(value) case value - when Array - value.map(&method(:wrap)) - when Hash - value.map { |key, val| [key, wrap(val)] }.to_h when Neo4j::Driver::Types::Entity wrap_by_level(value) + when Neo4j::Driver::Types::Path + value + when Hash + value.map { |key, val| [key, wrap(val)] }.to_h + when Enumerable + value.map(&method(:wrap)) else value end end def wrap_by_level(entity) - case @wrap_level + case wrap_level when :core_entity entity when :proc entity.wrap else - fail ArgumentError, "Invalid wrap_level: #{@wrap_level.inspect}" + fail ArgumentError, "Invalid wrap_level: #{wrap_level.inspect}" end end end diff --git a/lib/neo4j/version.rb b/lib/neo4j/version.rb index e4b55c7e7..c77151222 100644 --- a/lib/neo4j/version.rb +++ b/lib/neo4j/version.rb @@ -1,3 +1,3 @@ module Neo4j - VERSION = '9.6.0' + VERSION = '10.0.0-alpha.1' end diff --git a/neo4j.gemspec b/neo4j.gemspec index 664c78e5c..47ade5eaa 100644 --- a/neo4j.gemspec +++ b/neo4j.gemspec @@ -22,7 +22,7 @@ DESCRIPTION s.require_path = 'lib' s.files = Dir.glob('{bin,lib,config}/**/*') + %w(README.md CHANGELOG.md CONTRIBUTORS Gemfile neo4j.gemspec) - s.executables = ['neo4j-jars'] + s.executables = [] s.extra_rdoc_files = %w( README.md ) s.rdoc_options = ['--quiet', '--title', 'Neo4j.rb', '--line-numbers', '--main', 'README.rdoc', '--inline-source'] s.metadata = { diff --git a/spec/e2e/active_rel_spec.rb b/spec/e2e/active_rel_spec.rb index 028026801..84d924498 100644 --- a/spec/e2e/active_rel_spec.rb +++ b/spec/e2e/active_rel_spec.rb @@ -465,37 +465,6 @@ class ActiveRelSpecTypesInheritedRelClass < ActiveRelSpecTypesAutomaticRelType expect(new_rel.to_node).not_to receive(:loaded) expect { new_rel.inspect }.not_to raise_error end - - context 'single from/to class' do - it 'inserts the class names in String' do - next if Neo4j::VERSION >= '6.0.0' - expect(new_rel.inspect).to include('(FromClass)-[:rel_class_type]->(ToClass)') - end - end - - context 'array of from/to class' do - before { MyRelClass.from_class([:FromClass, :ToClass]) } - - it 'joins with ||' do - next if Neo4j::VERSION >= '6.0.0' - expect(new_rel.inspect).to include('(FromClass || ToClass)-[:rel_class_type]->(ToClass)') - end - end - end - - context 'with set, unloaded from_node/to_node' do - let(:new_rel) { MyRelClass.create(from_node: from_node, to_node: to_node) } - let(:reloaded) { Neo4j::Relationship.load(new_rel.id) } - let(:inspected) { reloaded.inspect } - - # Neo4j Embedded always returns nodes with rels. This is only possible in Server mode. - it 'notes the ids of the nodes' do - next if Neo4j::VERSION >= '6.0.0' - next if TEST_SESSION_MODE == :embedded - [from_node.neo_id, to_node.neo_id].each do |id| - expect(inspected).to include("(Node with neo_id #{id})") - end - end end end diff --git a/spec/e2e/enum_spec.rb b/spec/e2e/enum_spec.rb index b11563451..782bab9dc 100644 --- a/spec/e2e/enum_spec.rb +++ b/spec/e2e/enum_spec.rb @@ -252,18 +252,14 @@ context 'when using `ActionController::Parameters`' do let(:params) { action_controller_params('type' => 'image').permit! } it 'assigns enums correctly when instancing a new class' do - using_action_controller do - file = StoredFile.new(params) - expect(file.type).to eq('image') - end + file = StoredFile.new(params) + expect(file.type).to eq('image') end it 'assigns enums correctly when assigning to `attributes`' do - using_action_controller do - file = StoredFile.new - file.attributes = params - expect(file.type).to eq('image') - end + file = StoredFile.new + file.attributes = params + expect(file.type).to eq('image') end end diff --git a/spec/e2e/marshal_spec.rb b/spec/e2e/marshal_spec.rb index 5af47c9a3..67c3962d8 100644 --- a/spec/e2e/marshal_spec.rb +++ b/spec/e2e/marshal_spec.rb @@ -1,4 +1,4 @@ -describe Neo4j::Shared::Marshal do +describe Neo4j::Shared::Marshal, :ffi do describe 'ActiveNode' do before do stub_active_node_class('Parent') @@ -11,7 +11,6 @@ let(:node) { Child.create(foo: 'bar') } it 'marshals correctly' do - pending "Java type is not serializable, cannot be marshaled. Is this really necessary" id = node.id neo_id = node.neo_id unmarshaled = Marshal.load(Marshal.dump(node)) @@ -40,7 +39,6 @@ let(:rel) { HasParent.create(Person.create, Person.create, foo: 'bar') } it 'marshals correctly' do - pending "Java type is not serializable, cannot be marshaled. Is this really necessary" neo_id = rel.neo_id unmarshaled = Marshal.load(Marshal.dump(rel)) diff --git a/spec/neo4j_spec_helpers.rb b/spec/neo4j_spec_helpers.rb index 9fa4a98e9..50537b7c2 100644 --- a/spec/neo4j_spec_helpers.rb +++ b/spec/neo4j_spec_helpers.rb @@ -41,43 +41,6 @@ def action_controller_params(args) ActionController::Parameters.new(args) end - def handle_child_output(read, write) - read.close - begin - rest = yield - write.puts [Marshal.dump(rest)].pack('m') - rescue StandardError => e - write.puts [Marshal.dump(e)].pack('m') - end - exit! - end - - def do_in_child(&block) - read, write = IO.pipe - pid = fork do - handle_child_output(read, write, &block) - end - write.close - result = Marshal.load(read.read.unpack('m').first) - Process.wait2(pid) - - fail result if result.class < Exception - result - end - - # A trick to load action_controller without requiring in all specs. Not working in JRuby. - def using_action_controller - if RUBY_PLATFORM == 'java' - require 'action_controller' - yield - else - do_in_child do - require 'action_controller' - yield - end - end - end - class_methods do def let_config(var_name, value) around do |example| diff --git a/spec/shared_examples/forbidden_attributes_shared_examples.rb b/spec/shared_examples/forbidden_attributes_shared_examples.rb index 721a3c100..5e5465efc 100644 --- a/spec/shared_examples/forbidden_attributes_shared_examples.rb +++ b/spec/shared_examples/forbidden_attributes_shared_examples.rb @@ -1,63 +1,47 @@ shared_examples 'handles permitted parameters' do describe '#new' do it 'assigns permitted params' do - using_action_controller do - params.permit! - expect(klass.new(create_params).attributes).to include(params.to_h) - end + params.permit! + expect(klass.new(create_params).attributes).to include(params.to_h) end it 'fails on unpermitted parameters' do - using_action_controller do - expect { klass.new(create_params) }.to raise_error ActiveModel::ForbiddenAttributesError - end + expect { klass.new(create_params) }.to raise_error ActiveModel::ForbiddenAttributesError end end describe '#create' do it 'assigns permitted params' do - using_action_controller do - params.permit! - expect(klass.create(create_params).attributes).to include(params.to_h) - end + params.permit! + expect(klass.create(create_params).attributes).to include(params.to_h) end it 'fails on unpermitted parameters' do - using_action_controller do - expect { klass.create(create_params) }.to raise_error ActiveModel::ForbiddenAttributesError - end + expect { klass.create(create_params) }.to raise_error ActiveModel::ForbiddenAttributesError end end describe '#attributes=' do it 'assigns permitted params' do - using_action_controller do - params.permit! - subject.attributes = params - expect(subject.attributes).to include(params.to_h) - end + params.permit! + subject.attributes = params + expect(subject.attributes).to include(params.to_h) end it 'fails on unpermitted parameters' do - using_action_controller do - expect { subject.attributes = params }.to raise_error ActiveModel::ForbiddenAttributesError - end + expect { subject.attributes = params }.to raise_error ActiveModel::ForbiddenAttributesError end end describe '#update' do it 'assigns permitted params' do - using_action_controller do - params.permit! - subject.update(params) - expect(subject.attributes).to include(params.to_h) - end + params.permit! + subject.update(params) + expect(subject.attributes).to include(params.to_h) end it 'fails on unpermitted parameters' do - using_action_controller do - expect { klass.new.update(params) }.to raise_error ActiveModel::ForbiddenAttributesError - end + expect { klass.new.update(params) }.to raise_error ActiveModel::ForbiddenAttributesError end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 43732b349..20ad833f4 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,24 +1,24 @@ # To run coverage via travis -# require 'simplecov' +require 'simplecov' require 'dotenv' require 'timecop' Dotenv.load -# SimpleCov.start do -# add_filter 'spec' -# end -# if ENV['CI'] == 'true' -# require 'codecov' -# SimpleCov.formatter = SimpleCov::Formatter::Codecov -# end +SimpleCov.start do + add_filter 'spec' +end +if ENV['CI'] == 'true' + require 'codecov' + SimpleCov.formatter = SimpleCov::Formatter::Codecov +end # To run it manually via Rake -# if ENV['COVERAGE'] -# require 'simplecov' -# SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter -# SimpleCov.start -# end +if ENV['COVERAGE'] + require 'simplecov' + SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter + SimpleCov.start +end require 'bundler/setup' require 'rspec' @@ -37,6 +37,7 @@ require 'dryspec/helpers' require 'neo4j_spec_helpers' +require 'action_controller' class MockLogger def debug(*_args) @@ -225,4 +226,7 @@ def let_context(*args, &block) @active_base_logger = spy('ActiveBase logger') allow(Neo4j::ActiveBase).to receive(:logger).and_return(@active_base_logger) end + + # TODO marshalling java objects, is it necessary? + config.filter_run_excluding ffi: !RUBY_PLATFORM =~ /java/ end