Skip to content

Commit

Permalink
Merge pull request #9 from pocke/Write_spec
Browse files Browse the repository at this point in the history
Write spec
  • Loading branch information
pocke committed Mar 13, 2024
2 parents 7f8bd3a + 779d705 commit 644e32b
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 10 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ gem "rspec", "~> 3.0", require: false
gem "rubocop", "~> 1.21", require: false

gem 'steep', require: false

gem 'sqlite3'
5 changes: 4 additions & 1 deletion lib/activerecord/originator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

require 'active_record'
require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/class/subclasses'

require_relative "originator/version"

require_relative "originator/arel_node_extension"
require_relative "originator/arel_visitor_extension"
require_relative "originator/collector_proxy"

Arel::Nodes::Node.include ActiveRecord::Originator::ArelNodeExtension
Arel::Nodes::Node.descendants.each do |klass|
klass.prepend ActiveRecord::Originator::ArelNodeExtension
end
Arel::Visitors::ToSql.prepend ActiveRecord::Originator::ArelVisitorExtension

module ActiveRecord
Expand Down
2 changes: 1 addition & 1 deletion lib/activerecord/originator/arel_node_extension.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module ActiveRecord
module Originator
module ArelNodeExtension
def initialize
def initialize(...)
__skip__ = super
@ar_originator_backtrace = caller
end
Expand Down
21 changes: 14 additions & 7 deletions lib/activerecord/originator/arel_visitor_extension.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,19 @@ def accept(object, collector)
private

%i[
visit_Arel_Nodes_Ascending
visit_Arel_Nodes_Descending
visit_Arel_Nodes_Equality
visit_Arel_Nodes_InnerJoin
].each do |method_name|
define_method(method_name) do |o, collector|
Ascending
Descending
Equality
NotEqual
InnerJoin
HomogeneousIn
GreaterThanOrEqual
GreaterThan
LessThan
LessThanOrEqual
GreaterThanOrEqual
].each do |klass_name|
define_method(:"visit_Arel_Nodes_#{klass_name}") do |o, collector|
__skip__ = begin
comment = originator_comment(o)
res = super(o, collector)
Expand All @@ -38,7 +45,7 @@ def originator_comment(o)
" /* #{escape_comment(frame)} */\n"
end

def escape_coment(comment)
def escape_comment(comment)
while comment.include?('/*') || comment.include?('*/')
comment = comment.gsub('/*', '').gsub('*/', '')
end
Expand Down
65 changes: 64 additions & 1 deletion spec/activerecord/originator_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,68 @@
# frozen_string_literal: true

RSpec.describe ActiveRecord::Originator do
pending
describe '#to_sql' do
context 'with a WHERE clause' do
it 'annotates single = operator' do
expect(Post.hello.to_sql).to eq(<<~SQL)
SELECT "posts".* FROM "posts" WHERE "posts"."title" = 'hello' /* /spec/support/post.rb:4 */
SQL
end

it 'annotates multiple = operator' do
expect(Post.hello.draft.to_sql).to eq(<<~SQL)
SELECT "posts".* FROM "posts" WHERE "posts"."title" = 'hello' /* /spec/support/post.rb:4 */
AND "posts"."state" = 'draft' /* /spec/support/post.rb:5 */
SQL
end

it 'annotates != operator' do
expect(Post.not_eq.to_sql).to eq(<<~SQL)
SELECT "posts".* FROM "posts" WHERE "posts"."title" != 'hello' /* /spec/support/post.rb:9 */
SQL
end

it 'annotates IN operator' do
expect(Post.state_for(['draft', 'published']).to_sql).to eq(<<~SQL)
SELECT "posts".* FROM "posts" WHERE "posts"."state" IN ('draft', 'published') /* /spec/support/post.rb:6 */
SQL
end

it 'annotates NOT IN operator' do
expect(Post.not_state_for(['draft', 'published']).to_sql).to eq(<<~SQL)
SELECT "posts".* FROM "posts" WHERE "posts"."state" NOT IN ('draft', 'published') /* /spec/support/post.rb:7 */
SQL
end

it 'annotates >= operator' do
expect(Post.compare_id(42..).to_sql).to eq(<<~SQL)
SELECT "posts".* FROM "posts" WHERE "posts"."id" >= 42 /* /spec/support/post.rb:8 */
SQL
end

it 'annotates >= operator' do
expect(Post.compare_id(..42).to_sql).to eq(<<~SQL)
SELECT "posts".* FROM "posts" WHERE "posts"."id" <= 42 /* /spec/support/post.rb:8 */
SQL
end

it 'annotates < operator' do
expect(Post.compare_id(...42).to_sql).to eq(<<~SQL)
SELECT "posts".* FROM "posts" WHERE "posts"."id" < 42 /* /spec/support/post.rb:8 */
SQL
end
end

it 'annotates a ORDER BY asc clause' do
expect(Post.order_by_title(:asc).to_sql).to eq(<<~SQL)
SELECT "posts".* FROM "posts" ORDER BY "posts"."title" ASC /* /spec/support/post.rb:10 */
SQL
end

it 'annotates a ORDER BY desc clause' do
expect(Post.order_by_title(:desc).to_sql).to eq(<<~SQL)
SELECT "posts".* FROM "posts" ORDER BY "posts"."title" DESC /* /spec/support/post.rb:10 */
SQL
end
end
end
9 changes: 9 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,12 @@
c.syntax = :expect
end
end

ActiveRecord::Originator.backtrace_cleaner = ActiveSupport::BacktraceCleaner.new.tap do |bc|
root_dir = File.expand_path("..", __dir__)
bc.add_filter { |line| line.gsub(root_dir, "") }
bc.add_filter { |line| line.gsub(/:in .+$/, "") }
bc.add_silencer { |line| not line.start_with?('/spec/') }
end

Pathname(__dir__).glob('support/*.rb').each { |f| require f }
11 changes: 11 additions & 0 deletions spec/support/001_setup_db.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Schema.define do
create_table :posts, force: true do |t|
t.string :title, null: false
t.string :state, null: false
end

create_table :comments, force: true do |t|
t.integer :post_id
end
end
3 changes: 3 additions & 0 deletions spec/support/comment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Comment < ActiveRecord::Base
belongs_to :post
end
11 changes: 11 additions & 0 deletions spec/support/post.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Post < ActiveRecord::Base
has_many :comments

scope :hello, -> { where(title: "hello") }
scope :draft, -> { where(state: "draft") }
scope :state_for, ->(state) { where(state: state) }
scope :not_state_for, ->(state) { where.not(state: state) }
scope :compare_id, ->(range) { where(id: range) }
scope :not_eq, -> { where.not(title: 'hello') }
scope :order_by_title, ->(direction) { order(title: direction) }
end

0 comments on commit 644e32b

Please sign in to comment.