Skip to content
This repository has been archived by the owner on Jun 16, 2021. It is now read-only.

Commit

Permalink
Merge pull request #826 from omu/develop
Browse files Browse the repository at this point in the history
Merge develop into master
  • Loading branch information
msdundar authored Feb 22, 2019
2 parents 3142c35 + dc00d60 commit ed89d7d
Show file tree
Hide file tree
Showing 70 changed files with 612 additions and 476 deletions.
12 changes: 0 additions & 12 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,9 @@ Metrics/BlockLength:
Exclude:
- config/routes/**/*
- lib/tasks/**/*.rake # Won't fix
- test/models/concerns/validation_test_module.rb # Won't fix
Metrics/MethodLength:
Exclude:
- test/models/concerns/validation_test_module.rb # Won't fix
Metrics/AbcSize:
Exclude:
- test/models/concerns/validation_test_module.rb # Won't fix
Metrics/ClassLength:
Exclude:
- test/**/*.rb
Naming/PredicateName:
Exclude:
- test/models/concerns/association_test_module.rb # Won't fix
- test/models/concerns/enumeration_test_module.rb # Won't fix

# Do not exclude files from ALL COPS unless it's really necessary!
AllCops:
Exclude:
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ ENV NODE_ENV=production
ENV NODE_ENV=$NODE_ENV

RUN case $RAILS_ENV in \
test) apt-get -y update && apt-get -y install --no-install-recommends chromedriver && \
test) scripts runtime/chrome chrome_install_upstream=true && \
apt-get clean && rm -rf /var/lib/apt/lists/* ;; \
esac

Expand Down
2 changes: 1 addition & 1 deletion app/lib/nokul/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Nokul
VERSION = '0.5.4'
VERSION = '0.5.5'
end
83 changes: 70 additions & 13 deletions doc/development/test-unit.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ author: M. Serhat Dundar

# Unit Tests

- Unit Test yazarken ilgili modülleri testinize include ederek aşağıda örneklenen test yardımcılarını kullanabilirsiniz.
- Unit Test yazarken ilgili modülleri testinize `extend` ederek aşağıda örneklenen test yardımcılarını kullanabilirsiniz.
- Nokul'da kullanılan stil, her satırda bir attribute'ün test edilmesidir!

--------------------------------------------------

## Associations

- Support::Minitest::AssociationHelper

### has_one

```ruby
Expand All @@ -23,38 +25,57 @@ author: M. Serhat Dundar
```ruby
has_many :addresses
has_many :addresses, :identities
has_many :addresses, through: :foo, dependent: :destroy
```

### belongs_to

```ruby
belongs_to :user
belongs_to :user, :unit
belongs_to :user, optional: true
```

### accepts_nested_attributes_for

```ruby
accepts_nested_attributes_for :units, allow_destroy: true
```

--------------------------------------------------

## Callbacks

- Mümkün olan key değerleri `:before`, `:after` ve `:around`'tur.
- Support::Minitest::CallbackHelper

```ruby
has_initialize_callback :method_name, :key
has_find_callback :method_name, :key
has_touch_callback :method_name, :key
has_validation_callback :method_name, :key
has_save_callback :method_name, :key
has_create_callback :method_name, :key
has_update_callback :method_name, :key
has_destroy_callback :method_name, :key
has_commit_callback :method_name, :key
has_rollback_callback :method_name, :key
after_commit :method_name
after_create :method_name
after_destroy :method_name
after_find :method_name
after_initialize :method_name
after_rollback :method_name
after_save :method_name
after_touch :method_name
after_update :method_name
after_validation :method_name
around_create :method_name
around_destroy :method_name
around_save :method_name
around_update :method_name
before_create :method_name
before_destroy :method_name
before_save :method_name
before_update :method_name
before_validation :method_name
```

--------------------------------------------------

## Validations

- Support::Minitest::ValidationHelper

### Presence

```ruby
Expand Down Expand Up @@ -105,6 +126,42 @@ validates_numerical_range :yoksis_code, less_than_or_equal_to: 2000

## Enums

- Support::Minitest::EnumerationHelper

```ruby
enum term: { fall: 0, spring: 1, summer: 2 }
```

## Example

```ruby
has_enum :term, fall: 0, spring: 1, summer: 2
class AcademicTermTest < ActiveSupport::TestCase
extend Support::Minitest::AssociationHelper
extend Support::Minitest::CallbackHelper
extend Support::Minitest::EnumerationHelper
extend Support::Minitest::ValidationHelper

# relations
has_many :calendars, dependent: :nullify
has_many :registration_documents, dependent: :nullify

# validations: presence
validates_presence_of :active
validates_presence_of :end_of_term
validates_presence_of :start_of_term
validates_presence_of :term
validates_presence_of :year

# validations: uniqueness
validates_uniqueness_of :year

# validations: length
validates_length_of :year

# enums
enum term: { fall: 0, spring: 1, summer: 2 }

# callbacks
after_save :deactivate_academic_terms
end
```
6 changes: 6 additions & 0 deletions plugins/support/.rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@ Metrics/LineLength:
Naming/FileName:
Exclude:
- lib/nokul-support.rb
Metrics/MethodLength:
Exclude:
- lib/nokul/support/minitest/validation_helper.rb # Won't fix
Metrics/AbcSize:
Exclude:
- lib/nokul/support/minitest/validation_helper.rb # Won't fix
2 changes: 2 additions & 0 deletions plugins/support/lib/nokul/support.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@
require_relative 'support/coding'
require_relative 'support/sensitive'
require_relative 'support/rest_client'

require_relative 'support/minitest'
6 changes: 6 additions & 0 deletions plugins/support/lib/nokul/support/minitest.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

require_relative 'minitest/association_helper'
require_relative 'minitest/callback_helper'
require_relative 'minitest/enumeration_helper'
require_relative 'minitest/validation_helper'
48 changes: 48 additions & 0 deletions plugins/support/lib/nokul/support/minitest/association_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

module Nokul
module Support
module Minitest
module AssociationHelper
SUFFIX = 'Test'
RELATIONS = %i[belongs_to has_many has_one has_and_belongs_to_many].freeze

RELATIONS.each do |relation|
define_method(relation) do |attribute, **options|
association = relations_for(relation, attribute)

test "can respond to #{relation} #{attribute}" do
assert association
options.each do |key, value|
assert_equal association.options[key], value, "Option: #{key}"
end
end
end
end

def accepts_nested_attributes_for(attribute, **options)
nested_attributes_options = klass.nested_attributes_options[attribute]

test "#{attribute} must be nested attribute" do
assert nested_attributes_options
options.each do |key, value|
assert_equal nested_attributes_options[key], value, "Option: #{key}"
end
end
end

private

def relations_for(relation, attribute)
klass.reflect_on_all_associations(relation).select do |association|
association.name == attribute
end.first
end

def klass
to_s.delete_suffix(SUFFIX).constantize
end
end
end
end
end
42 changes: 42 additions & 0 deletions plugins/support/lib/nokul/support/minitest/callback_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true

module Nokul
module Support
module Minitest
module CallbackHelper
CALLBACKS = %i[
after_commit
after_create
after_destroy
after_find
after_initialize
after_rollback
after_save
after_touch
after_update
after_validation
around_create
around_destroy
around_save
around_update
before_create
before_destroy
before_save
before_update
before_validation
].freeze

CALLBACKS.each do |callback|
define_method(callback) do |action|
test "has #{callback} for #{action}" do
kind, method = callback.to_s.split('_')
klass = class_name.delete_suffix('Test').constantize
callbacks = klass.send("_#{method}_callbacks")
assert callbacks.select { |cb| cb.filter.eql?(action.to_sym) && cb.kind.eql?(kind.to_sym) }.any?
end
end
end
end
end
end
end
21 changes: 21 additions & 0 deletions plugins/support/lib/nokul/support/minitest/enumeration_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

module Nokul
module Support
module Minitest
module EnumerationHelper
def enum(definitions)
definitions.each do |attribute, values|
values.each do |key, value|
test "has a enum key (#{key}) with a value of #{value}" do
klass = class_name.delete_suffix('Test').constantize
defined_value = klass.defined_enums.dig(attribute.to_s, key.to_s)
assert_equal defined_value, value, "Enum: #{attribute}"
end
end
end
end
end
end
end
end
90 changes: 90 additions & 0 deletions plugins/support/lib/nokul/support/minitest/validation_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# frozen_string_literal: true

module Nokul
module Support
module Minitest
module ValidationHelper
SUFFIX = 'Test'

def validates_presence_of(*attributes)
attributes.each do |attribute|
test "#{attribute} must be present (presence: true)" do
object = class_name.delete_suffix(SUFFIX).constantize.take
object.send("#{attribute}=", nil)
assert_not object.valid?
assert_not_empty object.errors[attribute]
end
end
end

def validates_presence_of_nested_model(attribute, ids: nil)
test "nested model (#{attribute}) must be present" do
ids ||= "#{attribute.to_s.singularize}_ids"
object = class_name.delete_suffix(SUFFIX).constantize.take
object.send("#{ids}=", nil)
assert_not object.valid?
assert_not_empty object.errors[attribute]
end
end

def validates_uniqueness_of(*attributes)
attributes.each do |attribute|
test "#{attribute} must be unique (uniqueness: true)" do
duplicate_object = class_name.delete_suffix(SUFFIX).constantize.take.dup
assert_not duplicate_object.valid?
assert_not_empty duplicate_object.errors[attribute]
end
end
end

def validates_length_of(attribute, **option)
option[:maximum] = 255 if option.blank?

controls = {
is: { value: 1, error_key: :wrong_length },
minimum: { value: -1, error_key: :too_short },
maximum: { value: 1, error_key: :too_long }
}
key = option.keys.first
value = option[key].to_i + controls.dig(key, :value).to_i
error_key = controls.dig(key, :error_key)

test "#{attribute} length must be #{option}" do
object = class_name.delete_suffix(SUFFIX).constantize.take
object.send("#{attribute}=", (0..value).map { ('a'..'z').to_a[rand(26)] }.join)
assert_not object.valid?
assert object.errors.details[attribute].map { |err| err[:error] }.include?(error_key)
end
end

def validates_numericality_of(attribute)
test "#{attribute} must be a number" do
object = class_name.delete_suffix(SUFFIX).constantize.take
object.send("#{attribute}=", 'some string')
assert_not object.valid?
assert object.errors.details[attribute].map { |err| err[:error] }.include?(:not_a_number)
end
end

def validates_numerical_range(attribute, **option)
controls = {
greater_than: 0,
less_than: 0,
greater_than_or_equal_to: -1,
less_than_or_equal_to: 1
}

key = option.keys.first
value = option[key].to_i + controls[key].to_i

test "#{attribute} must be #{key} #{value}" do
object = class_name.delete_suffix(SUFFIX).constantize.take
object.send("#{attribute}=", value)
assert_not object.valid?
assert object.errors.details[attribute].map { |err| err[:error] }.include?(key)
end
end
end
end
end
end
Loading

0 comments on commit ed89d7d

Please sign in to comment.