Skip to content

Commit

Permalink
Spec for from_sql, and a big mock for the DB class (#133)
Browse files Browse the repository at this point in the history
* Spec for from_sql, and a big mock for the DB class

* Updates to work with sqlite timestamp hack

* cleanup and documentation
  • Loading branch information
robacarp authored and drujensen committed Apr 22, 2018
1 parent 40f4a09 commit 7581ecd
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 2 deletions.
41 changes: 41 additions & 0 deletions spec/granite_orm/querying/from_sql_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require "../../spec_helper"

macro build_review_emitter(driver)
{%
timestamp = if driver == "sqlite"
"2018-04-09 13:33:46"
else
"Time.now".id
end
%}

FieldEmitter.new.tap do |e|
e._set_values(
[
8_i64,
"name",
nil, # downvotes
nil, # upvotes
nil, # sentiment
nil, # interest
true, # published
{{ timestamp }} # created_at
]
)
end
end

def method_which_takes_any_model(model : Granite::ORM::Base.class)
model.as(Granite::ORM::Base).from_sql build_review_emitter
end

{% for adapter in GraniteExample::ADAPTERS %}
module {{ adapter.capitalize.id }}
describe "{{ adapter.id }} #from_sql" do
it "Builds a model from a resultset" do
model = Review.from_sql build_review_emitter({{ adapter }})
model.class.should eq Review
end
end
end
{% end %}
89 changes: 89 additions & 0 deletions spec/mocks/db_mock.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
class FakeStatement < DB::Statement
protected def perform_query(args : Enumerable) : DB::ResultSet
FieldEmitter.new
end

protected def perform_exec(args : Enumerable)
DB::ExecResult.new 0_i64, 0_i64
end
end

class FakeContext
include DB::ConnectionContext

def uri
URI.new ""
end

def prepared_statements?
false
end

def discard(connection); end
def release(connection); end
end

class FakeConnection < DB::Connection
def initialize
@context = FakeContext.new
@prepared_statements = false
end

def build_unprepared_statement(query : String)
FakeStatement.new self
end

def build_prepared_statement(query : String)
FakeStatement.new self
end
end

# FieldEmitter emulates the subtle and uninformed way that
# DB::ResultSet emits data. To be used in testing interactions
# with raw data sets.
class FieldEmitter < DB::ResultSet
# 1. Override `#move_next` to move to the next row.
# 2. Override `#read` returning the next value in the row.
# 3. (Optional) Override `#read(t)` for some types `t` for which custom logic other than a simple cast is needed.
# 4. Override `#column_count`, `#column_name`.

@position = 0
@field_position = 0
@values = [] of DB::Any

def initialize
@statement = FakeStatement.new FakeConnection.new
end

def _set_values(values : Array(DB::Any))
@values = [] of DB::Any
values.each do |v|
@values << v
end
end

def move_next
@position += 1
@field_position = 0
end

def read
if @position >= @values.size
raise "Overread"
end


@values[@position].tap do |v|
@position += 1
end
end

def column_count
@values.size
end

def column_name(index : Int32)
"Column #{index}"
end
end

1 change: 1 addition & 0 deletions spec/spec_helper.cr
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ end

require "../src/granite_orm"
require "./spec_models"
require "./mocks/**"

Granite::ORM.settings.logger = ::Logger.new(nil)
3 changes: 1 addition & 2 deletions spec/spec_models.cr
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,7 @@ end
sentiment FLOAT,
interest REAL,
published BOOL,
{{ created_at_sql }},
{{ updated_at_sql }}
{{ created_at_sql }}
)
SQL
end
Expand Down

0 comments on commit 7581ecd

Please sign in to comment.