Skip to content

Commit

Permalink
start adding tests
Browse files Browse the repository at this point in the history
  • Loading branch information
danielfornarini committed Oct 20, 2023
1 parent 187aa31 commit 396654d
Show file tree
Hide file tree
Showing 14 changed files with 386 additions and 91 deletions.
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 0 additions & 8 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
# frozen_string_literal: true

source "https://rubygems.org"

# Specify your gem's dependencies in deep_versionable.gemspec
gemspec

gem "rake", "~> 13.0"

gem "rspec", "~> 3.0"

gem "rubocop", "~> 1.7"
96 changes: 96 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
PATH
remote: .
specs:
deep_versionable (0.1.0)
activerecord

GEM
remote: https://rubygems.org/
specs:
actionpack (6.1.7.6)
actionview (= 6.1.7.6)
activesupport (= 6.1.7.6)
rack (~> 2.0, >= 2.0.9)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actionview (6.1.7.6)
activesupport (= 6.1.7.6)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
activemodel (6.1.7.6)
activesupport (= 6.1.7.6)
activerecord (6.1.7.6)
activemodel (= 6.1.7.6)
activesupport (= 6.1.7.6)
activesupport (6.1.7.6)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
builder (3.2.4)
concurrent-ruby (1.2.2)
crass (1.0.6)
diff-lcs (1.4.4)
erubi (1.12.0)
generator_spec (0.9.4)
activesupport (>= 3.0.0)
railties (>= 3.0.0)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
loofah (2.21.4)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
method_source (1.0.0)
minitest (5.19.0)
nokogiri (1.15.4-x86_64-darwin)
racc (~> 1.4)
racc (1.7.1)
rack (2.2.8)
rack-test (2.1.0)
rack (>= 1.3)
rails-dom-testing (2.2.0)
activesupport (>= 5.0.0)
minitest
nokogiri (>= 1.6)
rails-html-sanitizer (1.6.0)
loofah (~> 2.21)
nokogiri (~> 1.14)
railties (6.1.7.6)
actionpack (= 6.1.7.6)
activesupport (= 6.1.7.6)
method_source
rake (>= 12.2)
thor (~> 1.0)
rake (13.0.6)
rspec (3.10.0)
rspec-core (~> 3.10.0)
rspec-expectations (~> 3.10.0)
rspec-mocks (~> 3.10.0)
rspec-core (3.10.1)
rspec-support (~> 3.10.0)
rspec-expectations (3.10.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.10.0)
rspec-mocks (3.10.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.10.0)
rspec-support (3.10.2)
thor (1.3.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
zeitwerk (2.6.11)

PLATFORMS
x86_64-darwin-22

DEPENDENCIES
deep_versionable!
generator_spec (~> 0.9.4)
rspec

BUNDLED WITH
2.2.15
18 changes: 11 additions & 7 deletions deep_versionable.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ Gem::Specification.new do |spec|
spec.authors = ["Daniel Fornarini"]
spec.email = ["[email protected]"]

spec.summary = "TODO: Write a short summary, because RubyGems requires one."
spec.description = "TODO: Write a longer description or delete this line."
spec.homepage = "TODO: Put your gem's website or public repo URL here."
spec.summary = "Write a short summary, because RubyGems requires one."
# spec.description = "TODO: Write a longer description or delete this line."
# spec.homepage = "TODO: Put your gem's website or public repo URL here."
spec.license = "MIT"
spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")

spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"

spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
# spec.metadata["homepage_uri"] = spec.homepage
# spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
# spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."

# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
Expand All @@ -34,4 +34,8 @@ Gem::Specification.new do |spec|

# For more information and examples about making a new gem, checkout our
# guide at: https://bundler.io/guides/creating_gem.html

spec.add_dependency "activerecord"
spec.add_development_dependency "rspec"
spec.add_development_dependency "generator_spec", "~> 0.9.4"
end
5 changes: 3 additions & 2 deletions lib/deep_versionable.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require 'active_support/concern'
require 'active_record'

module DeepVersionable
extend ActiveSupport::Concern
Expand Down Expand Up @@ -80,7 +81,7 @@ def load_class(klass, key)
end
end

def versionize
def versionize!
object = to_json(self.class._deep_versionable_relations)

versions.create!(version: versions.count + 1, object: object)
Expand All @@ -89,4 +90,4 @@ def versionize

# rubocop:disable Lint/SendWithMixinArgument
ActiveRecord::Base.send(:extend, DeepVersionable::Initializer)
# rubocop:enable Lint/SendWithMixinArgument
# rubocop:enable Lint/SendWithMixinArgument
66 changes: 0 additions & 66 deletions lib/generators/deep_versionable/install/install_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@

module DeepVersionable
class InstallGenerator < MigrationGenerator
# Class names of MySQL adapters.
# - `MysqlAdapter` - Used by gems: `mysql`, `activerecord-jdbcmysql-adapter`.
# - `Mysql2Adapter` - Used by `mysql2` gem.
MYSQL_ADAPTERS = [
"ActiveRecord::ConnectionAdapters::MysqlAdapter",
"ActiveRecord::ConnectionAdapters::Mysql2Adapter"
].freeze

source_root File.expand_path("templates", __dir__)
class_option(
:with_changes,
Expand All @@ -32,65 +24,7 @@ class InstallGenerator < MigrationGenerator
def create_migration_file
add_deep_versionable_migration(
"create_versions",
item_type_options: item_type_options,
versions_table_options: versions_table_options,
item_id_type_options: item_id_type_options,
version_table_primary_key_type: version_table_primary_key_type
)
if options.with_changes?
add_paper_trail_migration("add_object_changes_to_versions")
end
end

private

# To use uuid instead of integer for primary key
def item_id_type_options
options.uuid? ? "string" : "bigint"
end

# To use uuid for version table primary key
def version_table_primary_key_type
if options.uuid?
", id: :uuid"
else
""
end
end

def item_type_options
if mysql?
", null: false, limit: 191"
else
", null: false"
end
end

def mysql?
MYSQL_ADAPTERS.include?(ActiveRecord::Base.connection.class.name)
end

# Even modern versions of MySQL still use `latin1` as the default character
# encoding. Many users are not aware of this, and run into trouble when they
# try to use PaperTrail in apps that otherwise tend to use UTF-8. Postgres, by
# comparison, uses UTF-8 except in the unusual case where the OS is configured
# with a custom locale.
#
# - https://dev.mysql.com/doc/refman/5.7/en/charset-applications.html
# - http://www.postgresql.org/docs/9.4/static/multibyte.html
#
# Furthermore, MySQL's original implementation of UTF-8 was flawed, and had
# to be fixed later by introducing a new charset, `utf8mb4`.
#
# - https://mathiasbynens.be/notes/mysql-utf8mb4
# - https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html
#
def versions_table_options
if mysql?
', options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci"'
else
""
end
end
end
end
7 changes: 3 additions & 4 deletions lib/generators/deep_versionable/migration_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
require "rails/generators/active_record"

module DeepVersionable
# Basic structure to support a generator that builds a migration
class MigrationGenerator < ::Rails::Generators::Base
include ::Rails::Generators::Migration

Expand All @@ -14,15 +13,15 @@ def self.next_migration_number(dirname)

protected

def add_deep_versionable_migration(template, extra_options = {})
def add_deep_versionable_migration(template)
migration_dir = File.expand_path("db/migrate")
if self.class.migration_exists?(migration_dir, template)
::Kernel.warn "Migration already exists: #{template}"
else
migration_template(
"#{template}.rb.erb",
"db/migrate/#{template}.rb",
{ migration_version: migration_version }.merge(extra_options)
{ migration_version: migration_version }
)
end
end
Expand All @@ -35,4 +34,4 @@ def migration_version
)
end
end
end
end
88 changes: 88 additions & 0 deletions spec/deep_versionable/models/version_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Version, type: :model do
it 'should correctly reify a version' do
post = Post.create!(
body: 'Body Post',
user: User.create!(
first_name: 'John',
last_name: 'Doe'
),
comments: [
Comment.create!(
text: 'Comment 1',
reactions: [
Reaction.create!(
emoji: Emoji.create!(name: 'Emoji 1'),
),
Reaction.create!(
emoji: Emoji.create!(name: 'Emoji 2'),
)
]
),
Comment.create!(
text: 'Comment 2',
reactions: [
Reaction.create!(
emoji: Emoji.create!(name: 'Emoji 3'),
),
Reaction.create!(
emoji: Emoji.create!(name: 'Emoji 4'),
)
]
)
]
)

post.versionize!

reified_post = post.versions.last.reify

expect(reified_post).to be_a(Version::Post)
expect(reified_post.id).to eq(1)
expect(reified_post.body).to eq('Body Post')

expect(reified_post.user).to be_a(Version::User)
expect(reified_post.user.id).to eq(1)
expect(reified_post.user.first_name).to eq('John')
expect(reified_post.user.last_name).to eq('Doe')

expect(reified_post.comments).to be_a(Array)
expect(reified_post.comments.length).to eq(2)

expect(reified_post.comments[0]).to be_a(Version::Comment)
expect(reified_post.comments[0].id).to eq(1)
expect(reified_post.comments[0].text).to eq('Comment 1')
expect(reified_post.comments[0].reactions).to be_a(Array)
expect(reified_post.comments[0].reactions.length).to eq(2)
expect(reified_post.comments[0].reactions[0]).to be_a(Version::Reaction)
expect(reified_post.comments[0].reactions[0].id).to eq(1)
expect(reified_post.comments[0].reactions[0].emoji).to be_a(Version::Emoji)
expect(reified_post.comments[0].reactions[0].emoji.id).to eq(1)
expect(reified_post.comments[0].reactions[0].emoji.name).to eq('Emoji 1')
expect(reified_post.comments[0].reactions[1]).to be_a(Version::Reaction)
expect(reified_post.comments[0].reactions[1].id).to eq(2)
expect(reified_post.comments[0].reactions[1].emoji).to be_a(Version::Emoji)
expect(reified_post.comments[0].reactions[1].emoji.id).to eq(2)
expect(reified_post.comments[0].reactions[1].emoji.name).to eq('Emoji 2')

expect(reified_post.comments[1]).to be_a(Version::Comment)
expect(reified_post.comments[1].id).to eq(2)
expect(reified_post.comments[1].text).to eq('Comment 2')
expect(reified_post.comments[1].likes).to be_a(Array)
expect(reified_post.comments[1].likes.length).to eq(2)
expect(reified_post.comments[1].likes[0]).to be_a(Version::Like)
expect(reified_post.comments[1].likes[0].id).to eq(3)
expect(reified_post.comments[1].likes[0].user).to be_a(Version::User)
expect(reified_post.comments[1].likes[0].user.id).to eq(4)
expect(reified_post.comments[1].likes[0].user.name).to eq('User 2')
expect(reified_post.comments[1].likes[1]).to be_a(Version::Like)
expect(reified_post.comments[1].likes[1].id).to eq(4)
expect(reified_post.comments[1].likes[1].user).to be_a(Version::User)
expect(reified_post.comments[1].likes[1].user.id).to eq(5)
expect(reified_post.comments[1].likes[1].user.name).to eq('User 4')
end
end

Loading

0 comments on commit 396654d

Please sign in to comment.