From ccf2edf9c10a708505fe06486429fc553d819187 Mon Sep 17 00:00:00 2001 From: Abdelkader Boudih Date: Sat, 27 Jun 2020 01:47:42 +0100 Subject: [PATCH] wip version 0.5.0 --- .rubocop.yml | 4 + .travis.yml | 48 +---- Appraisals | 20 ++ CHANGES.md | 5 + Gemfile | 9 +- LICENSE.txt | 2 +- Rakefile | 2 +- disposable.gemspec | 6 +- gemfiles/5.1.gemfile | 14 ++ gemfiles/5.1.gemfile.lock | 121 ++++++++++++ gemfiles/5.2.gemfile | 14 ++ gemfiles/5.2.gemfile.lock | 121 ++++++++++++ gemfiles/6.0.gemfile | 14 ++ gemfiles/6.0.gemfile.lock | 121 ++++++++++++ lib/disposable/twin.rb | 2 +- lib/disposable/twin/coercion.rb | 19 +- lib/disposable/twin/property/hash.rb | 2 +- lib/disposable/twin/struct.rb | 10 - lib/disposable/version.rb | 2 +- test/api_semantics_test.rb | 263 --------------------------- test/callback_group_test.rb | 126 ++++++------- test/callbacks_test.rb | 172 +++++++++--------- test/example.rb | 10 +- test/expose_test.rb | 64 ++++--- test/persisted_test.rb | 69 ++++--- test/rescheme_test.rb | 114 ++++++------ test/skip_getter_test.rb | 43 +++-- test/test_helper.rb | 22 +-- test/twin/benchmarking.rb | 9 +- test/twin/builder_test.rb | 15 +- test/twin/changed_test.rb | 106 +++++------ test/twin/coercion_test.rb | 178 +++++------------- test/twin/collection_test.rb | 142 +++++++-------- test/twin/composition_test.rb | 67 +++---- test/twin/default_test.rb | 47 ++--- test/twin/expose_test.rb | 45 ++--- test/twin/feature_test.rb | 36 ++-- test/twin/from_collection_test.rb | 18 +- test/twin/from_test.rb | 16 +- test/twin/hash_test.rb | 139 +++++++------- test/twin/inherit_test.rb | 28 +-- test/twin/inheritance_test.rb | 28 +-- test/twin/option_test.rb | 2 +- test/twin/parent_test.rb | 22 ++- test/twin/process_inline_test.rb | 3 +- test/twin/property_processor_test.rb | 48 ++--- test/twin/readable_test.rb | 28 +-- test/twin/save_test.rb | 125 ++++++------- test/twin/setup_test.rb | 80 ++++---- test/twin/skip_unchanged_test.rb | 49 +++-- test/twin/struct/coercion_test.rb | 29 +-- test/twin/struct_test.rb | 178 +++++++++--------- test/twin/sync_option_test.rb | 10 +- test/twin/sync_test.rb | 116 ++++++------ test/twin/twin_test.rb | 70 ++++--- test/twin/unnest_test.rb | 31 ++-- test/twin/virtual_test.rb | 18 +- test/twin/writeable_test.rb | 28 +-- 58 files changed, 1573 insertions(+), 1557 deletions(-) create mode 100644 .rubocop.yml create mode 100644 Appraisals create mode 100644 gemfiles/5.1.gemfile create mode 100644 gemfiles/5.1.gemfile.lock create mode 100644 gemfiles/5.2.gemfile create mode 100644 gemfiles/5.2.gemfile.lock create mode 100644 gemfiles/6.0.gemfile create mode 100644 gemfiles/6.0.gemfile.lock delete mode 100644 lib/disposable/twin/struct.rb delete mode 100644 test/api_semantics_test.rb diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..8da1442 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,4 @@ +require: + - rubocop-minitest + - rubocop-performance + diff --git a/.travis.yml b/.travis.yml index 3f47ef8..08805f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,44 +1,14 @@ language: ruby +cache: bundler +before_install: gem install bundler +install: bundle install +script: "bundle exec rake test" rvm: - - ruby-head + - 2.7 - 2.6 - 2.5 - - 2.4 -env: - - "ACTIVERECORD=5.0 DRY_TYPES=0.13" - - "ACTIVERECORD=5.0 DRY_TYPES=0.14" - - "ACTIVERECORD=5.0 DRY_TYPES=0.15" - - "ACTIVERECORD=5.0 DRY_TYPES=1.0" - - "ACTIVERECORD=5.0 DRY_TYPES=1.1" - - "ACTIVERECORD=5.0 DRY_TYPES=1.2" - - "ACTIVERECORD=5.1 DRY_TYPES=0.13" - - "ACTIVERECORD=5.1 DRY_TYPES=0.14" - - "ACTIVERECORD=5.1 DRY_TYPES=0.15" - - "ACTIVERECORD=5.1 DRY_TYPES=1.0" - - "ACTIVERECORD=5.1 DRY_TYPES=1.1" - - "ACTIVERECORD=5.1 DRY_TYPES=1.2" - - "ACTIVERECORD=5.2 DRY_TYPES=0.13" - - "ACTIVERECORD=5.2 DRY_TYPES=0.14" - - "ACTIVERECORD=5.2 DRY_TYPES=0.15" - - "ACTIVERECORD=5.2 DRY_TYPES=1.0" - - "ACTIVERECORD=5.2 DRY_TYPES=1.1" - - "ACTIVERECORD=5.2 DRY_TYPES=1.2" - - "ACTIVERECORD=6.0 DRY_TYPES=0.13" - - "ACTIVERECORD=6.0 DRY_TYPES=0.14" - - "ACTIVERECORD=6.0 DRY_TYPES=0.15" - - "ACTIVERECORD=6.0 DRY_TYPES=1.0" - - "ACTIVERECORD=6.0 DRY_TYPES=1.1" - - "ACTIVERECORD=6.0 DRY_TYPES=1.2" gemfile: - - Gemfile -matrix: - fast_finish: true - allow_failures: - - rvm: ruby-head - exclude: - - {rvm: 2.4, env: "ACTIVERECORD=6.0 DRY_TYPES=0.13"} - - {rvm: 2.4, env: "ACTIVERECORD=6.0 DRY_TYPES=0.14"} - - {rvm: 2.4, env: "ACTIVERECORD=6.0 DRY_TYPES=0.15"} - - {rvm: 2.4, env: "ACTIVERECORD=6.0 DRY_TYPES=1.0"} - - {rvm: 2.4, env: "ACTIVERECORD=6.0 DRY_TYPES=1.1"} - - {rvm: 2.4, env: "ACTIVERECORD=6.0 DRY_TYPES=1.2"} + - gemfiles/6.0.gemfile + - gemfiles/5.2.gemfile + - gemfiles/5.1.gemfile + diff --git a/Appraisals b/Appraisals new file mode 100644 index 0000000..a694330 --- /dev/null +++ b/Appraisals @@ -0,0 +1,20 @@ +appraise "6.0" do + gem 'dry-types' + gem 'activerecord', '6.0' + gem 'sqlite3', '~> 1.4' + gem "representable", github: "trailblazer/representable" +end + +appraise "5.2" do + gem 'dry-types' + gem 'activerecord', '5.2' + gem 'sqlite3', '~> 1.3.13' + gem "representable", github: "trailblazer/representable" +end + +appraise "5.1" do + gem 'dry-types' + gem 'activerecord', '5.1' + gem 'sqlite3', '~> 1.3.13' + gem "representable", github: "trailblazer/representable" +end diff --git a/CHANGES.md b/CHANGES.md index f1288f9..c44afe7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,8 @@ +# 0.5.0 +* Drop support for legacy version of dry-types +* Remove Disposable::Twin::Struct +* Removal of nilify option + # 0.4.7 * Deprecation warning for nilify options for dry-v >= 1.x diff --git a/Gemfile b/Gemfile index 78a6288..3ee8eae 100644 --- a/Gemfile +++ b/Gemfile @@ -2,9 +2,6 @@ source "https://rubygems.org" gemspec gem "minitest-line" -{ "dry-types" => ENV['DRY_TYPES'], "activerecord" => ENV['ACTIVERECORD']}.each do |gem_name, dependency| - next if dependency.nil? - gem gem_name, dependency -end - -gem "sqlite3", ENV.fetch('ACTIVERECORD', '5.2').to_f >= 6 ? '~> 1.4' : '~> 1.3.0' +gem "appraisal", "~> 2.3" +gem 'rubocop-minitest', require: false +gem 'rubocop-performance', require: false diff --git a/LICENSE.txt b/LICENSE.txt index b3de891..fcffe14 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2013 Nick Sutterer +Copyright (c) 2013-2020 Nick Sutterer MIT License diff --git a/Rakefile b/Rakefile index e355dc5..9e4c4cc 100644 --- a/Rakefile +++ b/Rakefile @@ -6,4 +6,4 @@ Rake::TestTask.new(:test) do |test| test.libs << 'test' test.test_files = FileList['test/**/*_test.rb'] test.verbose = true -end \ No newline at end of file +end diff --git a/disposable.gemspec b/disposable.gemspec index de91b91..49e3370 100644 --- a/disposable.gemspec +++ b/disposable.gemspec @@ -20,12 +20,10 @@ Gem::Specification.new do |spec| spec.add_dependency "declarative", ">= 0.0.9", "< 1.0.0" spec.add_dependency "declarative-builder", "< 0.2.0" spec.add_dependency "declarative-option", "< 0.2.0" - spec.add_dependency "representable", ">= 2.4.0", "<= 3.1.0" + spec.add_dependency "representable"#, ">= 3.1.0.beta" - spec.add_development_dependency "bundler"#, "~> 1.3" + spec.add_development_dependency "bundler" spec.add_development_dependency "rake" spec.add_development_dependency "minitest" - spec.add_development_dependency "activerecord"#, "4.2.5" - spec.add_development_dependency "dry-types"# "~> 0.6" # spec.add_development_dependency "database_cleaner" end diff --git a/gemfiles/5.1.gemfile b/gemfiles/5.1.gemfile new file mode 100644 index 0000000..392f8bb --- /dev/null +++ b/gemfiles/5.1.gemfile @@ -0,0 +1,14 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "minitest-line" +gem "appraisal", "~> 2.3" +gem "rubocop-minitest", require: false +gem "rubocop-performance", require: false +gem "dry-types" +gem "activerecord", "5.1" +gem "sqlite3", "~> 1.3.13" +gem "representable", github: "trailblazer/representable" + +gemspec path: "../" diff --git a/gemfiles/5.1.gemfile.lock b/gemfiles/5.1.gemfile.lock new file mode 100644 index 0000000..e193923 --- /dev/null +++ b/gemfiles/5.1.gemfile.lock @@ -0,0 +1,121 @@ +GIT + remote: https://github.com/trailblazer/representable.git + revision: fa537cbfd8ba7202e9542db67fd82011d382772c + specs: + representable (3.1.0.beta1) + declarative (< 0.1.0) + declarative-option (< 0.2.0) + uber (< 0.2.0) + +PATH + remote: .. + specs: + disposable (0.5.0.beta1) + declarative (>= 0.0.9, < 1.0.0) + declarative-builder (< 0.2.0) + declarative-option (< 0.2.0) + representable + uber (< 0.2.0) + +GEM + remote: https://rubygems.org/ + specs: + activemodel (5.1.0) + activesupport (= 5.1.0) + activerecord (5.1.0) + activemodel (= 5.1.0) + activesupport (= 5.1.0) + arel (~> 8.0) + activesupport (5.1.0) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (~> 0.7) + minitest (~> 5.1) + tzinfo (~> 1.1) + appraisal (2.3.0) + bundler + rake + thor (>= 0.14.0) + arel (8.0.0) + ast (2.4.1) + concurrent-ruby (1.1.6) + declarative (0.0.10) + declarative-builder (0.1.0) + declarative-option (< 0.2.0) + declarative-option (0.1.0) + dry-configurable (0.11.6) + concurrent-ruby (~> 1.0) + dry-core (~> 0.4, >= 0.4.7) + dry-equalizer (~> 0.2) + dry-container (0.7.2) + concurrent-ruby (~> 1.0) + dry-configurable (~> 0.1, >= 0.1.3) + dry-core (0.4.9) + concurrent-ruby (~> 1.0) + dry-equalizer (0.3.0) + dry-inflector (0.2.0) + dry-logic (1.0.6) + concurrent-ruby (~> 1.0) + dry-core (~> 0.2) + dry-equalizer (~> 0.2) + dry-types (1.4.0) + concurrent-ruby (~> 1.0) + dry-container (~> 0.3) + dry-core (~> 0.4, >= 0.4.4) + dry-equalizer (~> 0.3) + dry-inflector (~> 0.1, >= 0.1.2) + dry-logic (~> 1.0, >= 1.0.2) + i18n (0.9.5) + concurrent-ruby (~> 1.0) + minitest (5.14.1) + minitest-line (0.6.5) + minitest (~> 5.0) + parallel (1.19.2) + parser (2.7.1.4) + ast (~> 2.4.1) + rainbow (3.0.0) + rake (13.0.1) + regexp_parser (1.7.1) + rexml (3.2.4) + rubocop (0.86.0) + parallel (~> 1.10) + parser (>= 2.7.0.1) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.7) + rexml + rubocop-ast (>= 0.0.3, < 1.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 2.0) + rubocop-ast (0.1.0) + parser (>= 2.7.0.1) + rubocop-minitest (0.9.0) + rubocop (>= 0.74) + rubocop-performance (1.6.1) + rubocop (>= 0.71.0) + ruby-progressbar (1.10.1) + sqlite3 (1.3.13) + thor (1.0.1) + thread_safe (0.3.6) + tzinfo (1.2.7) + thread_safe (~> 0.1) + uber (0.1.0) + unicode-display_width (1.7.0) + +PLATFORMS + ruby + +DEPENDENCIES + activerecord (= 5.1) + appraisal (~> 2.3) + bundler + disposable! + dry-types + minitest + minitest-line + rake + representable! + rubocop-minitest + rubocop-performance + sqlite3 (~> 1.3.13) + +BUNDLED WITH + 2.1.4 diff --git a/gemfiles/5.2.gemfile b/gemfiles/5.2.gemfile new file mode 100644 index 0000000..74874bb --- /dev/null +++ b/gemfiles/5.2.gemfile @@ -0,0 +1,14 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "minitest-line" +gem "appraisal", "~> 2.3" +gem "rubocop-minitest", require: false +gem "rubocop-performance", require: false +gem "dry-types" +gem "activerecord", "5.2" +gem "sqlite3", "~> 1.3.13" +gem "representable", github: "trailblazer/representable" + +gemspec path: "../" diff --git a/gemfiles/5.2.gemfile.lock b/gemfiles/5.2.gemfile.lock new file mode 100644 index 0000000..b5d6d5f --- /dev/null +++ b/gemfiles/5.2.gemfile.lock @@ -0,0 +1,121 @@ +GIT + remote: https://github.com/trailblazer/representable.git + revision: fa537cbfd8ba7202e9542db67fd82011d382772c + specs: + representable (3.1.0.beta1) + declarative (< 0.1.0) + declarative-option (< 0.2.0) + uber (< 0.2.0) + +PATH + remote: .. + specs: + disposable (0.5.0.beta1) + declarative (>= 0.0.9, < 1.0.0) + declarative-builder (< 0.2.0) + declarative-option (< 0.2.0) + representable + uber (< 0.2.0) + +GEM + remote: https://rubygems.org/ + specs: + activemodel (5.2.0) + activesupport (= 5.2.0) + activerecord (5.2.0) + activemodel (= 5.2.0) + activesupport (= 5.2.0) + arel (>= 9.0) + activesupport (5.2.0) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + appraisal (2.3.0) + bundler + rake + thor (>= 0.14.0) + arel (9.0.0) + ast (2.4.1) + concurrent-ruby (1.1.6) + declarative (0.0.10) + declarative-builder (0.1.0) + declarative-option (< 0.2.0) + declarative-option (0.1.0) + dry-configurable (0.11.6) + concurrent-ruby (~> 1.0) + dry-core (~> 0.4, >= 0.4.7) + dry-equalizer (~> 0.2) + dry-container (0.7.2) + concurrent-ruby (~> 1.0) + dry-configurable (~> 0.1, >= 0.1.3) + dry-core (0.4.9) + concurrent-ruby (~> 1.0) + dry-equalizer (0.3.0) + dry-inflector (0.2.0) + dry-logic (1.0.6) + concurrent-ruby (~> 1.0) + dry-core (~> 0.2) + dry-equalizer (~> 0.2) + dry-types (1.4.0) + concurrent-ruby (~> 1.0) + dry-container (~> 0.3) + dry-core (~> 0.4, >= 0.4.4) + dry-equalizer (~> 0.3) + dry-inflector (~> 0.1, >= 0.1.2) + dry-logic (~> 1.0, >= 1.0.2) + i18n (1.8.3) + concurrent-ruby (~> 1.0) + minitest (5.14.1) + minitest-line (0.6.5) + minitest (~> 5.0) + parallel (1.19.2) + parser (2.7.1.4) + ast (~> 2.4.1) + rainbow (3.0.0) + rake (13.0.1) + regexp_parser (1.7.1) + rexml (3.2.4) + rubocop (0.86.0) + parallel (~> 1.10) + parser (>= 2.7.0.1) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.7) + rexml + rubocop-ast (>= 0.0.3, < 1.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 2.0) + rubocop-ast (0.1.0) + parser (>= 2.7.0.1) + rubocop-minitest (0.9.0) + rubocop (>= 0.74) + rubocop-performance (1.6.1) + rubocop (>= 0.71.0) + ruby-progressbar (1.10.1) + sqlite3 (1.3.13) + thor (1.0.1) + thread_safe (0.3.6) + tzinfo (1.2.7) + thread_safe (~> 0.1) + uber (0.1.0) + unicode-display_width (1.7.0) + +PLATFORMS + ruby + +DEPENDENCIES + activerecord (= 5.2) + appraisal (~> 2.3) + bundler + disposable! + dry-types + minitest + minitest-line + rake + representable! + rubocop-minitest + rubocop-performance + sqlite3 (~> 1.3.13) + +BUNDLED WITH + 2.1.4 diff --git a/gemfiles/6.0.gemfile b/gemfiles/6.0.gemfile new file mode 100644 index 0000000..5df14a0 --- /dev/null +++ b/gemfiles/6.0.gemfile @@ -0,0 +1,14 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "minitest-line" +gem "appraisal", "~> 2.3" +gem "rubocop-minitest", require: false +gem "rubocop-performance", require: false +gem "dry-types" +gem "activerecord", "6.0" +gem "sqlite3", "~> 1.4" +gem "representable", github: "trailblazer/representable" + +gemspec path: "../" diff --git a/gemfiles/6.0.gemfile.lock b/gemfiles/6.0.gemfile.lock new file mode 100644 index 0000000..5017622 --- /dev/null +++ b/gemfiles/6.0.gemfile.lock @@ -0,0 +1,121 @@ +GIT + remote: https://github.com/trailblazer/representable.git + revision: fa537cbfd8ba7202e9542db67fd82011d382772c + specs: + representable (3.1.0.beta1) + declarative (< 0.1.0) + declarative-option (< 0.2.0) + uber (< 0.2.0) + +PATH + remote: .. + specs: + disposable (0.5.0.beta1) + declarative (>= 0.0.9, < 1.0.0) + declarative-builder (< 0.2.0) + declarative-option (< 0.2.0) + representable + uber (< 0.2.0) + +GEM + remote: https://rubygems.org/ + specs: + activemodel (6.0.0) + activesupport (= 6.0.0) + activerecord (6.0.0) + activemodel (= 6.0.0) + activesupport (= 6.0.0) + activesupport (6.0.0) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + zeitwerk (~> 2.1, >= 2.1.8) + appraisal (2.3.0) + bundler + rake + thor (>= 0.14.0) + ast (2.4.1) + concurrent-ruby (1.1.6) + declarative (0.0.10) + declarative-builder (0.1.0) + declarative-option (< 0.2.0) + declarative-option (0.1.0) + dry-configurable (0.11.6) + concurrent-ruby (~> 1.0) + dry-core (~> 0.4, >= 0.4.7) + dry-equalizer (~> 0.2) + dry-container (0.7.2) + concurrent-ruby (~> 1.0) + dry-configurable (~> 0.1, >= 0.1.3) + dry-core (0.4.9) + concurrent-ruby (~> 1.0) + dry-equalizer (0.3.0) + dry-inflector (0.2.0) + dry-logic (1.0.6) + concurrent-ruby (~> 1.0) + dry-core (~> 0.2) + dry-equalizer (~> 0.2) + dry-types (1.4.0) + concurrent-ruby (~> 1.0) + dry-container (~> 0.3) + dry-core (~> 0.4, >= 0.4.4) + dry-equalizer (~> 0.3) + dry-inflector (~> 0.1, >= 0.1.2) + dry-logic (~> 1.0, >= 1.0.2) + i18n (1.8.3) + concurrent-ruby (~> 1.0) + minitest (5.14.1) + minitest-line (0.6.5) + minitest (~> 5.0) + parallel (1.19.2) + parser (2.7.1.4) + ast (~> 2.4.1) + rainbow (3.0.0) + rake (13.0.1) + regexp_parser (1.7.1) + rexml (3.2.4) + rubocop (0.86.0) + parallel (~> 1.10) + parser (>= 2.7.0.1) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.7) + rexml + rubocop-ast (>= 0.0.3, < 1.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 2.0) + rubocop-ast (0.1.0) + parser (>= 2.7.0.1) + rubocop-minitest (0.9.0) + rubocop (>= 0.74) + rubocop-performance (1.6.1) + rubocop (>= 0.71.0) + ruby-progressbar (1.10.1) + sqlite3 (1.4.2) + thor (1.0.1) + thread_safe (0.3.6) + tzinfo (1.2.7) + thread_safe (~> 0.1) + uber (0.1.0) + unicode-display_width (1.7.0) + zeitwerk (2.3.0) + +PLATFORMS + ruby + +DEPENDENCIES + activerecord (= 6.0) + appraisal (~> 2.3) + bundler + disposable! + dry-types + minitest + minitest-line + rake + representable! + rubocop-minitest + rubocop-performance + sqlite3 (~> 1.4) + +BUNDLED WITH + 2.1.4 diff --git a/lib/disposable/twin.rb b/lib/disposable/twin.rb index 461e375..75db00c 100644 --- a/lib/disposable/twin.rb +++ b/lib/disposable/twin.rb @@ -1,6 +1,6 @@ require "uber/inheritable_attr" require "declarative/schema" -require "representable/decorator" +require "representable" # Twin.new(model/composition hash/hash, options) # assign hash to @fields diff --git a/lib/disposable/twin/coercion.rb b/lib/disposable/twin/coercion.rb index b360962..97d8842 100644 --- a/lib/disposable/twin/coercion.rb +++ b/lib/disposable/twin/coercion.rb @@ -1,29 +1,20 @@ +gem 'dry-types', '~> 1.0' require "dry-types" module Disposable::Twin::Coercion module Types - # NOTE: Use Dry.Types() instead. Beware, it exports strict types by default, for old behavior use Dry.Types(default: :nominal) - DRY_MODULE = Gem::Version.new(Dry::Types::VERSION) < Gem::Version.new("0.15.0") ? Dry::Types.module : Dry.Types() - include DRY_MODULE + include Dry.Types() end - DRY_TYPES_VERSION = Gem::Version.new(Dry::Types::VERSION) - DRY_TYPES_CONSTANT = DRY_TYPES_VERSION < Gem::Version.new("0.13.0") ? Types::Form : Types::Params - module ClassMethods def property(name, options={}, &block) super(name, options, &block).tap do - coercing_setter!(name, options[:type], options[:nilify]) if options[:type] || options[:nilify] + coercing_setter!(name, options[:type]) if options[:type] end end - def coercing_setter!(name, type, nilify=false) - # TODO: remove nilily with next release (0.5) for new dry-type versions - type = type ? (DRY_TYPES_CONSTANT::Nil | type) : DRY_TYPES_CONSTANT::Nil if nilify - - warn "DEPRECATION WARNING [Disposable]: nilify is deprecated and it will be removed with the next release" if nilify && DRY_TYPES_VERSION >= Gem::Version.new("1.0.0") - - mod = Module.new do + def coercing_setter!(name, type) + mod = Module.new do define_method("#{name}=") do |value| super type.(value) end diff --git a/lib/disposable/twin/property/hash.rb b/lib/disposable/twin/property/hash.rb index 72d865a..0d8f038 100644 --- a/lib/disposable/twin/property/hash.rb +++ b/lib/disposable/twin/property/hash.rb @@ -1,4 +1,4 @@ -require "disposable/twin/struct" +require "disposable/twin/property/struct" class Disposable::Twin module Property diff --git a/lib/disposable/twin/struct.rb b/lib/disposable/twin/struct.rb deleted file mode 100644 index 589b1f7..0000000 --- a/lib/disposable/twin/struct.rb +++ /dev/null @@ -1,10 +0,0 @@ -require "disposable/twin/property/struct" - -class Disposable::Twin - module Struct - def self.included(includer) - warn "[Disposable] The Struct module is deprecated, please use Property::Struct." - includer.send(:include, Property::Struct) - end - end -end diff --git a/lib/disposable/version.rb b/lib/disposable/version.rb index 25de848..a1b913e 100644 --- a/lib/disposable/version.rb +++ b/lib/disposable/version.rb @@ -1,3 +1,3 @@ module Disposable - VERSION = "0.4.7" + VERSION = "0.5.0.beta1" end diff --git a/test/api_semantics_test.rb b/test/api_semantics_test.rb deleted file mode 100644 index 6149a3b..0000000 --- a/test/api_semantics_test.rb +++ /dev/null @@ -1,263 +0,0 @@ -# require "test_helper" -# require "disposable/twin" -# require "ostruct" - -# module Model -# Song = Struct.new(:id, :title) -# Album = Struct.new(:id, :name, :songs) -# end - -# # thoughts: -# # a twin should be a proxy between the incoming API instructions (form hash) and the models to write to. -# # e.g. when deleting certain items in a collection, this could be held in memory before written to DB. -# # reason: a twin can be validated (e.g. is current user allowed to remove item 1 from collection abc?) -# # before the application state is actually altered in the DB. -# # that would open a clean workflow: API calls --> twin state change --> validation --> "rollback" / save - -# module Representable -# class Semantics -# class Semantic -# def self.existing_item_for(fragment, options) -# # return unless model.songs.collect { |s| s.id.to_s }.include?(fragment["id"].to_s) -# options.binding.get.find { |s| s.id.to_s == fragment["id"].to_s } -# end -# end - -# class SkipExisting < Semantic -# def self.call(model, fragment, index, options) -# return unless existing_item_for(fragment, options) - -# Skip.new(fragment) -# end -# end - -# class Add < Semantic # old representable behavior. -# def self.call(model, fragment, index, options) -# binding = options.binding.clone -# binding.instance_variable_get(:@definition).delete!(:instance) # FIXME: sucks! -# Representable::Deserializer.new(binding).(fragment, options.user_options) # Song.new -# end -# end - -# class UpdateExisting < Semantic -# def self.call(model, fragment, index, options) -# return unless res = existing_item_for(fragment, options) - -# Update.new(res) -# end -# end - - -# class Skip < OpenStruct -# end - -# class Remove < Skip -# def self.call(model, fragment, index, options) -# return unless fragment["_action"] == "remove" # TODO: check if feature enabled. - -# Remove.new(fragment) -# end -# end - -# require 'delegate' -# class Update < SimpleDelegator -# end - -# # Per parsed collection item, mark the to-be-populated model for removal, skipping or adding. -# # This code is called right before #from_format is called on the model. -# # Semantical behavior is inferred from the fragment making this code document- and format-specific. - -# # remove: unlink from association -# # skip_existing -# # update_existing -# # add -# # [destroy] -# # callable - -# # default behavior: - add_new - -# class Instance -# include Uber::Callable - -# def call(model, fragment, index, options) -# semantics = options.binding[:semantics] - -# # loop through semantics, the first that returns something wins. -# semantics.each do |semantic| -# res = semantic.(model, fragment, index, options) and return res -# end -# end -# end - -# class Setter -# include Uber::Callable - -# def call(model, values, options) -# remove_items = values.find_all { |i| i.instance_of?(Representable::Semantics::Remove) } -# # add_items = values.find_all { |i| i.instance_of?(Add) }.collect(&:model) -# add_items = values - remove_items - -# skip_items = values.find_all { |i| i.instance_of?(Representable::Semantics::Skip) } -# skip_items += values.find_all { |i| i.instance_of?(Representable::Semantics::Update) } # TODO: merge with above! - -# # add_items = values.find_all { |i| i.instance_of?(Add) }.collect(&:model) -# add_items = add_items - skip_items - -# # DISCUSS: collection#[]= will call save -# # what does #+= and #-= do? -# # how do we prevent adding already existing items twice? - -# model.songs += add_items -# model.songs -= remove_items.collect { |i| model.songs.find { |s| s.id.to_s == i.id.to_s } } -# end -# end -# end -# end - -# class AlbumDecorator < Representable::Decorator -# include Representable::Hash - -# collection :songs, - -# # semantics: [:skip_existing, :add, :remove], -# semantics: [Representable::Semantics::Remove, Representable::Semantics::SkipExisting, Representable::Semantics::Add], - -# instance: Representable::Semantics::Instance.new, -# pass_options: true, -# setter: Representable::Semantics::Setter.new, - - -# class: Model::Song do # add new to existing collection. - -# # only add new songs -# property :title -# end -# end - - - -# class ApiSemanticsTest < MiniTest::Spec -# it "xxx" do -# album = Model::Album.new(1, "And So I Watch You From Afar", [Model::Song.new(2, "Solidarity"), Model::Song.new(0, "Tale That Wasn't Right")]) - -# decorator = AlbumDecorator.new(album) -# decorator.from_hash({"songs" => [ -# {"id" => 2, "title" => "Solidarity, but wrong title"}, # skip -# {"id" => 0, "title" => "Tale That Wasn't Right, but wrong title", "_action" => "remove"}, # delete -# {"id" => 4, "title" => "Capture Castles"} # add, default. -# ]}) -# # missing: allow updating specific/all items in collection. - -# decorator.represented.songs.inspect.must_equal %{[#, #]} -# end - -# end - -# class RemoveFlagSetButNotEnabled < MiniTest::Spec -# class AlbumDecorator < Representable::Decorator -# include Representable::Hash - -# collection :songs, -# # semantics: [:skip_existing, :add, :remove], -# semantics: [Representable::Semantics::SkipExisting, Representable::Semantics::Add], - -# instance: Representable::Semantics::Instance.new, -# pass_options: true, -# setter: Representable::Semantics::Setter.new, -# class: Model::Song do -# property :title -# end -# end - -# it "doesn't remove when semantic is not enabled" do -# album = Model::Album.new(1, "And So I Watch You From Afar", [Model::Song.new(2, "Solidarity"), Model::Song.new(0, "Tale That Wasn't Right")]) - -# decorator = AlbumDecorator.new(album) -# decorator.from_hash({"songs" => [ -# {"id" => 2, "title" => "Solidarity, updated!"}, # update -# {"id" => 0, "title" => "Tale That Wasn't Right, but wrong title", "_action" => "remove"}, # delete, but don't! -# {"title" => "Rise And Fall"} -# ]}) - -# decorator.represented.songs.inspect.must_equal %{[#, #, #]} -# end -# end - -# class UserCallableTest < MiniTest::Spec -# class MyOwnSemantic < Representable::Semantics::Semantic -# def self.call(model, fragment, index, options) -# if fragment["title"] =~ /Solidarity/ -# return Representable::Semantics::Skip.new(fragment) -# end -# end -# end - -# class AlbumDecorator < Representable::Decorator -# include Representable::Hash - -# collection :songs, -# semantics: [MyOwnSemantic, Representable::Semantics::Add], - -# instance: Representable::Semantics::Instance.new, -# pass_options: true, -# setter: Representable::Semantics::Setter.new, -# class: Model::Song do -# property :title -# end -# end - -# it do -# album = Model::Album.new(1, "And So I Watch You From Afar", [Model::Song.new(2, "Solidarity"), Model::Song.new(0, "Tale That Wasn't Right")]) - -# decorator = AlbumDecorator.new(album) -# decorator.from_hash({"songs" => [ -# {"id" => 2, "title" => "Solidarity, updated!"}, # update -# {"title" => "Rise And Fall"} -# ]}) - -# decorator.represented.songs.inspect.must_equal %{[#, #, #]} -# end -# end - - -# class ApiSemanticsWithUpdate < MiniTest::Spec -# class AlbumDecorator < Representable::Decorator -# include Representable::Hash - -# collection :songs, - -# semantics: [Representable::Semantics::Remove, Representable::Semantics::UpdateExisting, Representable::Semantics::Add], - -# instance: Representable::Semantics::Instance.new, -# pass_options: true, -# class: Model::Song, - -# setter: Representable::Semantics::Setter.new do # add new to existing collection. - -# # only add new songs -# property :title -# end -# end - -# it do -# album = Model::Album.new(1, "And So I Watch You From Afar", [Model::Song.new(2, "Solidarity"), Model::Song.new(0, "Tale That Wasn't Right")]) - -# decorator = AlbumDecorator.new(album) -# decorator.from_hash({"songs" => [ -# {"id" => 2, "title" => "Solidarity, updated!"}, # update -# {"id" => 0, "title" => "Tale That Wasn't Right, but wrong title", "_action" => "remove"}, # delete -# {"id" => 4, "title" => "Capture Castles"}, # add, default. # FIXME: this tests adding with id, keep this. -# {"title" => "Rise And Fall"} -# ]}) -# # missing: allow updating specific/all items in collection. - -# puts decorator.represented.songs.inspect - - -# decorator.represented.songs.inspect.must_equal %{[#, #, #]} -# end -# end -# # [ -# # {"_action": "add"}, -# # {"id": 2, "_action": "remove"} -# # ] \ No newline at end of file diff --git a/test/callback_group_test.rb b/test/callback_group_test.rb index ec9956a..6d93b39 100644 --- a/test/callback_group_test.rb +++ b/test/callback_group_test.rb @@ -1,5 +1,5 @@ -require "test_helper" -require "disposable/callback" +require 'test_helper' +require 'disposable/callback' class CallbackGroupTest < MiniTest::Spec class Group < Disposable::Callback::Group @@ -13,27 +13,25 @@ class Group < Disposable::Callback::Group # on_delete :notify_deleted_author! # in Update! - def notify_album!(twin, options) - options[:content] << "notify_album!" + def notify_album!(_twin, options) + options[:content] << 'notify_album!' end - def reset_song!(twin, options) - options[:content] << "reset_song!" + def reset_song!(_twin, options) + options[:content] << 'reset_song!' end end on_change :rehash_name!, property: :title - on_create :expire_cache! # on_change on_update :expire_cache! - def change!(twin, options) - @output = "Album has changed!" + def change!(_twin, _options) + @output = 'Album has changed!' end end - class AlbumTwin < Disposable::Twin feature Sync, Save feature Persisted, Changed @@ -49,100 +47,94 @@ class AlbumTwin < Disposable::Twin end end - # empty. it do - album = Album.new(songs: [Song.new(title: "Dead To Me"), Song.new(title: "Diesel Boy")]) + album = Album.new(songs: [Song.new(title: 'Dead To Me'), Song.new(title: 'Diesel Boy')]) twin = AlbumTwin.new(album) - expect(Group.new(twin).().invocations).must_equal [ + _(Group.new(twin).call.invocations).must_equal [ [:on_change, :change!, []], [:on_add, :notify_album!, []], [:on_add, :reset_song!, []], [:on_change, :rehash_name!, []], [:on_create, :expire_cache!, []], - [:on_update, :expire_cache!, []], + [:on_update, :expire_cache!, []] ] end # trigger songs:on_add, and on_change. - let (:content) { "" } + let(:content) { '' } it do twin = AlbumTwin.new(Album.new) - twin.songs << Song.new(title: "Dead To Me") - twin.songs << Song.new(title: "Diesel Boy") + twin.songs << Song.new(title: 'Dead To Me') + twin.songs << Song.new(title: 'Diesel Boy') - twin.name = "Dear Landlord" + twin.name = 'Dear Landlord' - group = Group.new(twin).(content: content) + group = Group.new(twin).call(content: content) - expect(group.invocations).must_equal [ + _(group.invocations).must_equal [ [:on_change, :change!, [twin]], [:on_add, :notify_album!, [twin.songs[0], twin.songs[1]]], [:on_add, :reset_song!, [twin.songs[0], twin.songs[1]]], [:on_change, :rehash_name!, []], [:on_create, :expire_cache!, []], - [:on_update, :expire_cache!, []], + [:on_update, :expire_cache!, []] ] - expect(content).must_equal "notify_album!notify_album!reset_song!reset_song!" - expect(group.output).must_equal "Album has changed!" + _(content).must_equal 'notify_album!notify_album!reset_song!reset_song!' + _(group.output).must_equal 'Album has changed!' end - - - - # context. class Operation attr_reader :output - def change!(twin, options) + def change!(_twin, options) options[:content] << "Op: changed! [#{options[:context].class}]" end - def notify_album!(twin, options) + def notify_album!(_twin, options) options[:content] << "Op: notify_album! [#{options[:context].class}]" end - def reset_song!(twin, options) + def reset_song!(_twin, options) options[:content] << "Op: reset_song! [#{options[:context].class}]" end - def rehash_name!(twin, options) + def rehash_name!(_twin, options) options[:content] << "Op: rehash_name! [#{options[:context].class}]" end - def expire_cache!(twin, options) + def expire_cache!(_twin, options) options[:content] << "Op: expire_cache! [#{options[:context].class}]" end end it do twin = AlbumTwin.new(Album.new) - twin.songs << Song.new(title: "Dead To Me") + twin.songs << Song.new(title: 'Dead To Me') - twin.name = "Dear Landlord" + twin.name = 'Dear Landlord' - group = Group.new(twin).(context: Operation.new, content: content) + group = Group.new(twin).call(context: Operation.new, content: content) # Disposable::Callback::Dispatch.new(twin).on_change{ |twin| puts twin;puts } # pp group.invocations - expect(group.invocations).must_equal [ + _(group.invocations).must_equal [ [:on_change, :change!, [twin]], [:on_add, :notify_album!, [twin.songs[0]]], [:on_add, :reset_song!, [twin.songs[0]]], [:on_change, :rehash_name!, []], [:on_create, :expire_cache!, []], - [:on_update, :expire_cache!, []], + [:on_update, :expire_cache!, []] ] - expect(content).must_equal "Op: changed! [CallbackGroupTest::Operation]Op: notify_album! [CallbackGroupTest::Operation]Op: reset_song! [CallbackGroupTest::Operation]" + _(content).must_equal 'Op: changed! [CallbackGroupTest::Operation]Op: notify_album! [CallbackGroupTest::Operation]Op: reset_song! [CallbackGroupTest::Operation]' end end - class CallbackGroupInheritanceTest < MiniTest::Spec class Group < Disposable::Callback::Group on_change :change! @@ -157,21 +149,19 @@ class Group < Disposable::Callback::Group end it do - expect(Group.hooks.size).must_equal 4 - expect(Group.hooks[0].to_s).must_equal "[:on_change, :change!, {}]" + _(Group.hooks.size).must_equal 4 + _(Group.hooks[0].to_s).must_equal '[:on_change, :change!, {}]' # Group.hooks[1][1][:nested].hooks.to_s.must_equal "[[:on_add, [:notify_album!]],[:on_add, [:reset_song!]]]" - expect(Group.hooks[2].to_s).must_equal "[:on_change, :rehash_name!, {:property=>:title}]" + _(Group.hooks[2].to_s).must_equal '[:on_change, :rehash_name!, {:property=>:title}]' - expect(Group.definitions.get(Group.hooks[3][1])[:nested].hooks.to_s).must_equal "[[:on_change, :sing!, {}]]" + _(Group.definitions.get(Group.hooks[3][1])[:nested].hooks.to_s).must_equal '[[:on_change, :sing!, {}]]' end class EmptyGroup < Group end - - it do - expect(EmptyGroup.hooks.size).must_equal 4 + _(EmptyGroup.hooks.size).must_equal 4 # TODO: end @@ -183,10 +173,10 @@ class EnhancedGroup < Group end it do - expect(Group.hooks.size).must_equal 4 + _(Group.hooks.size).must_equal 4 # pp EnhancedGroup.hooks - expect(EnhancedGroup.hooks.size).must_equal 6 - expect(EnhancedGroup.definitions.get(EnhancedGroup.hooks[5][1])[:nested].hooks.to_s).must_equal "[[:on_add, :rewind!, {}]]" + _(EnhancedGroup.hooks.size).must_equal 6 + _(EnhancedGroup.definitions.get(EnhancedGroup.hooks[5][1])[:nested].hooks.to_s).must_equal '[[:on_add, :rewind!, {}]]' end class EnhancedWithInheritGroup < EnhancedGroup @@ -199,13 +189,13 @@ class EnhancedWithInheritGroup < EnhancedGroup end it do - expect(Group.hooks.size).must_equal 4 - expect(EnhancedGroup.hooks.size).must_equal 6 + _(Group.hooks.size).must_equal 4 + _(EnhancedGroup.hooks.size).must_equal 6 - expect(EnhancedGroup.definitions.get(EnhancedGroup.hooks[5][1])[:nested].hooks.to_s).must_equal "[[:on_add, :rewind!, {}]]" - expect(EnhancedWithInheritGroup.hooks.size).must_equal 6 - expect(EnhancedWithInheritGroup.definitions.get(EnhancedWithInheritGroup.hooks[1][1])[:nested].hooks.to_s).must_equal "[[:on_add, :rewind!, {}], [:on_add, :eat!, {}]]" - expect(EnhancedWithInheritGroup.definitions.get(EnhancedWithInheritGroup.hooks[3][1])[:nested].hooks.to_s).must_equal "[[:on_change, :sing!, {}], [:on_delete, :yell!, {}]]" + _(EnhancedGroup.definitions.get(EnhancedGroup.hooks[5][1])[:nested].hooks.to_s).must_equal '[[:on_add, :rewind!, {}]]' + _(EnhancedWithInheritGroup.hooks.size).must_equal 6 + _(EnhancedWithInheritGroup.definitions.get(EnhancedWithInheritGroup.hooks[1][1])[:nested].hooks.to_s).must_equal '[[:on_add, :rewind!, {}], [:on_add, :eat!, {}]]' + _(EnhancedWithInheritGroup.definitions.get(EnhancedWithInheritGroup.hooks[3][1])[:nested].hooks.to_s).must_equal '[[:on_change, :sing!, {}], [:on_delete, :yell!, {}]]' end class RemovingInheritGroup < Group @@ -215,21 +205,21 @@ class RemovingInheritGroup < Group end end -# # puts "@@@@@ #{Group.hooks.object_id.inspect}" -# # puts "@@@@@ #{EmptyGroup.hooks.object_id.inspect}" -# puts "@@@@@ Group: #{Group.definitions.get(:songs)[:nested].hooks.inspect}" -# puts "@@@@@ EnhancedGroup: #{EnhancedGroup.definitions.get(:songs)[:nested].hooks.inspect}" -# puts "@@@@@ InheritGroup: #{EnhancedWithInheritGroup.definitions.get(:songs)[:nested].hooks.inspect}" -# puts "@@@@@ RemovingGroup: #{RemovingInheritGroup.definitions.get(:songs)[:nested].hooks.inspect}" -# # puts "@@@@@ #{EnhancedWithInheritGroup.definitions.get(:songs)[:nested].hooks.object_id.inspect}" + # # puts "@@@@@ #{Group.hooks.object_id.inspect}" + # # puts "@@@@@ #{EmptyGroup.hooks.object_id.inspect}" + # puts "@@@@@ Group: #{Group.definitions.get(:songs)[:nested].hooks.inspect}" + # puts "@@@@@ EnhancedGroup: #{EnhancedGroup.definitions.get(:songs)[:nested].hooks.inspect}" + # puts "@@@@@ InheritGroup: #{EnhancedWithInheritGroup.definitions.get(:songs)[:nested].hooks.inspect}" + # puts "@@@@@ RemovingGroup: #{RemovingInheritGroup.definitions.get(:songs)[:nested].hooks.inspect}" + # # puts "@@@@@ #{EnhancedWithInheritGroup.definitions.get(:songs)[:nested].hooks.object_id.inspect}" # TODO: object_id tests for all nested representers. it do - expect(Group.hooks.size).must_equal 4 - expect(RemovingInheritGroup.hooks.size).must_equal 3 - expect(RemovingInheritGroup.definitions.get(RemovingInheritGroup.hooks[0][1])[:nested].hooks.to_s).must_equal "[[:on_add, :reset_song!, {}]]" - expect(RemovingInheritGroup.definitions.get(RemovingInheritGroup.hooks[2][1])[:nested].hooks.to_s).must_equal "[[:on_change, :sing!, {}]]" + _(Group.hooks.size).must_equal 4 + _(RemovingInheritGroup.hooks.size).must_equal 3 + _(RemovingInheritGroup.definitions.get(RemovingInheritGroup.hooks[0][1])[:nested].hooks.to_s).must_equal '[[:on_add, :reset_song!, {}]]' + _(RemovingInheritGroup.definitions.get(RemovingInheritGroup.hooks[2][1])[:nested].hooks.to_s).must_equal '[[:on_change, :sing!, {}]]' end # Group::clone @@ -239,7 +229,7 @@ class RemovingInheritGroup < Group end it do - expect(Group.hooks.size).must_equal 4 - expect(ClonedGroup.hooks.size).must_equal 3 + _(Group.hooks.size).must_equal 4 + _(ClonedGroup.hooks.size).must_equal 3 end end diff --git a/test/callbacks_test.rb b/test/callbacks_test.rb index 594e3e1..3fb7151 100644 --- a/test/callbacks_test.rb +++ b/test/callbacks_test.rb @@ -1,5 +1,7 @@ -require "test_helper" -require "disposable/callback" +# frozen_string_literal: true + +require 'test_helper' +require 'disposable/callback' class CallbacksTest < MiniTest::Spec before do @@ -31,22 +33,22 @@ class AlbumTwin < Disposable::Twin # - Callbacks don't have before and after. This is up to the caller. Callback = Disposable::Callback::Dispatch - # collection :songs do - # after_add :song_added! # , context: :operation - # after_create :notify_album! - # after_remove :notify_artist! - # end + # collection :songs do + # after_add :song_added! # , context: :operation + # after_create :notify_album! + # after_remove :notify_artist! + # end - let (:twin) { AlbumTwin.new(album) } + let(:twin) { AlbumTwin.new(album) } - describe "#on_create" do - let (:album) { Album.new } + describe '#on_create' do + let(:album) { Album.new } # after initialization it do invokes = [] Callback.new(twin).on_create { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] end # save, without any attributes changed. @@ -55,136 +57,134 @@ class AlbumTwin < Disposable::Twin invokes = [] Callback.new(twin).on_create { |t| invokes << t } - expect(invokes).must_equal [twin] + _(invokes).must_equal [twin] end # before and after save, with attributes changed it do # state change, but not persisted, yet. - twin.name = "Run For Cover" + twin.name = 'Run For Cover' invokes = [] Callback.new(twin).on_create { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] twin.save Callback.new(twin).on_create { |t| invokes << t } - expect(invokes).must_equal [twin] + _(invokes).must_equal [twin] end # for collections. it do album.songs << Song.new - album.songs << Song.create(title: "Run For Cover") + album.songs << Song.create(title: 'Run For Cover') album.songs << Song.new invokes = [] Callback.new(twin.songs).on_create { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] twin.save Callback.new(twin.songs).on_create { |t| invokes << t } - expect(invokes).must_equal [twin.songs[0], twin.songs[2]] + _(invokes).must_equal [twin.songs[0], twin.songs[2]] end end - describe "#on_update" do - let (:album) { Album.new } + describe '#on_update' do + let(:album) { Album.new } # after initialization. it do invokes = [] Callback.new(twin).on_update { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] end # single twin. # on_update only works on persisted objects. it do - twin.name = "After The War" # change but not persisted + twin.name = 'After The War' # change but not persisted invokes = [] Callback.new(twin).on_update { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] invokes = [] twin.save Callback.new(twin).on_update { |t| invokes << t } - expect(invokes).must_equal [] - + _(invokes).must_equal [] # now with the persisted album. twin = AlbumTwin.new(album) # Album is persisted now. Callback.new(twin).on_update { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] invokes = [] twin.save # nothing has changed, yet. Callback.new(twin).on_update { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] - twin.name= "Corridors Of Power" + twin.name = 'Corridors Of Power' # this will even trigger on_update before saving. Callback.new(twin).on_update { |t| invokes << t } - expect(invokes).must_equal [twin] + _(invokes).must_equal [twin] invokes = [] twin.save # name changed. Callback.new(twin).on_update { |t| invokes << t } - expect(invokes).must_equal [twin] + _(invokes).must_equal [twin] end # for collections. it do album.songs << Song.new - album.songs << Song.create(title: "Run For Cover") + album.songs << Song.create(title: 'Run For Cover') album.songs << Song.new invokes = [] Callback.new(twin.songs).on_update { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] invokes = [] twin.save # initial save is no update. Callback.new(twin.songs).on_update { |t| invokes << t } - expect(invokes).must_equal [] - + _(invokes).must_equal [] # now with the persisted album. twin = AlbumTwin.new(album) # Album is persisted now. Callback.new(twin.songs).on_update { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] invokes = [] twin.save # nothing has changed, yet. Callback.new(twin.songs).on_update { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] - twin.songs[1].title= "After The War" - twin.songs[2].title= "Run For Cover" + twin.songs[1].title = 'After The War' + twin.songs[2].title = 'Run For Cover' # # this will even trigger on_update before saving. Callback.new(twin.songs).on_update { |t| invokes << t } - expect(invokes).must_equal [twin.songs[1], twin.songs[2]] + _(invokes).must_equal [twin.songs[1], twin.songs[2]] invokes = [] twin.save Callback.new(twin.songs).on_update { |t| invokes << t } - expect(invokes).must_equal [twin.songs[1], twin.songs[2]] + _(invokes).must_equal [twin.songs[1], twin.songs[2]] end # it do # album.songs << song1 = Song.new @@ -202,70 +202,69 @@ class AlbumTwin < Disposable::Twin # end end - - describe "#on_add" do - let (:album) { Album.new } + describe '#on_add' do + let(:album) { Album.new } # empty collection. it do invokes = [] Callback.new(twin.songs).on_add { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] end # collection present on initialize are not added. it do - ex_song = Song.create(title: "Run For Cover") + ex_song = Song.create(title: 'Run For Cover') song = Song.new album.songs = [ex_song, song] Callback.new(twin.songs).on_add { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] end # items added after initialization are added. it do - ex_song = Song.create(title: "Run For Cover") + ex_song = Song.create(title: 'Run For Cover') song = Song.new album.songs = [ex_song] twin.songs << song Callback.new(twin.songs).on_add { |t| invokes << t } - expect(invokes).must_equal [twin.songs[1]] + _(invokes).must_equal [twin.songs[1]] twin.save # still shows the added after save. invokes = [] Callback.new(twin.songs).on_add { |t| invokes << t } - expect(invokes).must_equal [twin.songs[1]] + _(invokes).must_equal [twin.songs[1]] end end - describe "#on_add(:created)" do - let (:album) { Album.new } + describe '#on_add(:created)' do + let(:album) { Album.new } # empty collection. it do invokes = [] Callback.new(twin.songs).on_add(:created) { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] end # collection present on initialize are not added. it do - ex_song = Song.create(title: "Run For Cover") + ex_song = Song.create(title: 'Run For Cover') song = Song.new album.songs = [ex_song, song] Callback.new(twin.songs).on_add(:created) { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] end # items added after initialization are added. it do - ex_song = Song.create(title: "Run For Cover") + ex_song = Song.create(title: 'Run For Cover') song = Song.new album.songs = [ex_song] @@ -273,99 +272,99 @@ class AlbumTwin < Disposable::Twin twin.songs << ex_song # already created. Callback.new(twin.songs).on_add(:created) { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] twin.save # still shows the added after save. invokes = [] Callback.new(twin.songs).on_add(:created) { |t| invokes << t } - expect(invokes).must_equal [twin.songs[1]] # only the created is invoked. + _(invokes).must_equal [twin.songs[1]] # only the created is invoked. end end - describe "#on_delete" do - let (:album) { Album.new } + describe '#on_delete' do + let(:album) { Album.new } # empty collection. it do invokes = [] Callback.new(twin.songs).on_delete { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] end # collection present but nothing deleted. it do - ex_song = Song.create(title: "Run For Cover") + ex_song = Song.create(title: 'Run For Cover') song = Song.new album.songs = [ex_song, song] Callback.new(twin.songs).on_delete { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] end # items deleted. it do - ex_song = Song.create(title: "Run For Cover") + ex_song = Song.create(title: 'Run For Cover') song = Song.new album.songs = [ex_song, song] twin.songs.delete(deleted = twin.songs[0]) Callback.new(twin.songs).on_delete { |t| invokes << t } - expect(invokes).must_equal [deleted] + _(invokes).must_equal [deleted] twin.save # still shows the deleted after save. invokes = [] Callback.new(twin.songs).on_delete { |t| invokes << t } - expect(invokes).must_equal [deleted] + _(invokes).must_equal [deleted] end end - describe "#on_destroy" do - let (:album) { Album.new } + describe '#on_destroy' do + let(:album) { Album.new } # empty collection. it do invokes = [] Callback.new(twin.songs).on_destroy { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] end # collection present but nothing deleted. it do - ex_song = Song.create(title: "Run For Cover") + ex_song = Song.create(title: 'Run For Cover') song = Song.new album.songs = [ex_song, song] Callback.new(twin.songs).on_destroy { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] end # items deleted, doesn't trigger on_destroy. it do - ex_song = Song.create(title: "Run For Cover") + ex_song = Song.create(title: 'Run For Cover') song = Song.new album.songs = [ex_song, song] twin.songs.delete(twin.songs[0]) Callback.new(twin.songs).on_destroy { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] end # items destroyed. it do - ex_song = Song.create(title: "Run For Cover") + ex_song = Song.create(title: 'Run For Cover') song = Song.new album.songs = [ex_song, song] twin.songs.destroy(deleted = twin.songs[0]) Callback.new(twin.songs).on_destroy { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] twin.extend(Disposable::Twin::Collection::Semantics) # now #save will destroy. twin.save @@ -373,18 +372,17 @@ class AlbumTwin < Disposable::Twin # still shows the deleted after save. invokes = [] Callback.new(twin.songs).on_destroy { |t| invokes << t } - expect(invokes).must_equal [deleted] + _(invokes).must_equal [deleted] end end - - describe "#on_change" do - let (:album) { Album.new } + describe '#on_change' do + let(:album) { Album.new } # after initialization it do Callback.new(twin).on_change { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] end # save, without any attributes changed. unpersisted before. @@ -394,7 +392,7 @@ class AlbumTwin < Disposable::Twin twin.save Callback.new(twin).on_change { |t| invokes << t } - expect(invokes).must_equal [] # nothing has changed, not even persisted?. + _(invokes).must_equal [] # nothing has changed, not even persisted?. end # save, without any attributes changed. persisted before. @@ -402,33 +400,33 @@ class AlbumTwin < Disposable::Twin twin.save Callback.new(twin).on_change { |t| invokes << t } - expect(invokes).must_equal [twin] + _(invokes).must_equal [twin] end # before and after save, with attributes changed it do # state change, but not persisted, yet. - twin.name = "Run For Cover" + twin.name = 'Run For Cover' invokes = [] Callback.new(twin).on_change { |t| invokes << t } - expect(invokes).must_equal [twin] + _(invokes).must_equal [twin] twin.save invokes = [] Callback.new(twin).on_change { |t| invokes << t } - expect(invokes).must_equal [twin] + _(invokes).must_equal [twin] end # for scalars: on_change(:email). it do Callback.new(twin).on_change(property: :name) { |t| invokes << t } - expect(invokes).must_equal [] + _(invokes).must_equal [] - twin.name = "Unforgiven" + twin.name = 'Unforgiven' Callback.new(twin).on_change(property: :name) { |t| invokes << t } - expect(invokes).must_equal [twin] + _(invokes).must_equal [twin] end # for collections. diff --git a/test/example.rb b/test/example.rb index fc4a737..f8d4cd3 100644 --- a/test/example.rb +++ b/test/example.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + # run me with bundle exec ruby -Itest test/example.rb -require "test_helper" +require 'test_helper' ActiveRecord::Base.logger = Logger.new(STDOUT) @@ -8,7 +10,7 @@ module Twin class Album < Disposable::Twin property :id # DISCUSS: needed for #save. property :name - collection :songs, :twin => lambda { |*| Song } + collection :songs, twin: ->(*) { Song } extend Representer include Setup @@ -33,8 +35,8 @@ class Song < Disposable::Twin # this is what basically should happen in the representer, returning a Twin. twin.songs << Song.new -twin.songs.last.title = "Back To Allentown" +twin.songs.last.title = 'Back To Allentown' puts "new songs (#{twin.songs.size}): #{twin.songs.inspect}" -twin.sync \ No newline at end of file +twin.sync diff --git a/test/expose_test.rb b/test/expose_test.rb index afd2665..7bee50b 100644 --- a/test/expose_test.rb +++ b/test/expose_test.rb @@ -1,6 +1,8 @@ -require "test_helper" -require "disposable/expose" -require "disposable/composition" +# frozen_string_literal: true + +require 'test_helper' +require 'disposable/expose' +require 'disposable/composition' # Disposable::Expose. class ExposeTest < MiniTest::Spec @@ -19,31 +21,29 @@ class AlbumExpose < Disposable::Expose from Twin::Album.definitions.values end - let (:album) { Model::Album.new(1, "Dick Sandwich") } + let(:album) { Model::Album.new(1, 'Dick Sandwich') } subject { AlbumExpose.new(album) } - describe "readers" do - it do - expect(subject.id).must_equal 1 - expect(subject.title).must_equal "Dick Sandwich" + describe 'readers' do + it do + _(subject.id).must_equal 1 + _(subject.title).must_equal 'Dick Sandwich' end end - - describe "writers" do + describe 'writers' do it do subject.id = 3 - subject.title = "Eclipse" + subject.title = 'Eclipse' - expect(subject.id).must_equal 3 - expect(subject.title).must_equal "Eclipse" - expect(album.id).must_equal 3 - expect(album.name).must_equal "Eclipse" + _(subject.id).must_equal 3 + _(subject.title).must_equal 'Eclipse' + _(album.id).must_equal 3 + _(album.name).must_equal 'Eclipse' end end end - # Disposable::Composition. class ExposeCompositionTest < MiniTest::Spec module Model @@ -63,30 +63,28 @@ class AlbumComposition < Disposable::Composition end end - let (:band) { Model::Band.new(1) } - let (:album) { Model::Album.new(2, "Dick Sandwich") } + let(:band) { Model::Band.new(1) } + let(:album) { Model::Album.new(2, 'Dick Sandwich') } subject { Twin::AlbumComposition.new(album: album, band: band) } - - describe "readers" do - it { expect(subject.id).must_equal 2 } - it { expect(subject.band_id).must_equal 1 } - it { expect(subject.name).must_equal "Dick Sandwich" } + describe 'readers' do + it { _(subject.id).must_equal 2 } + it { _(subject.band_id).must_equal 1 } + it { _(subject.name).must_equal 'Dick Sandwich' } end - - describe "writers" do + describe 'writers' do it do subject.id = 3 subject.band_id = 4 - subject.name = "Eclipse" - - expect(subject.id).must_equal 3 - expect(subject.band_id).must_equal 4 - expect(subject.name).must_equal "Eclipse" - expect(band.id).must_equal 4 - expect(album.id).must_equal 3 - expect(album.name).must_equal "Eclipse" + subject.name = 'Eclipse' + + _(subject.id).must_equal 3 + _(subject.band_id).must_equal 4 + _(subject.name).must_equal 'Eclipse' + _(band.id).must_equal 4 + _(album.id).must_equal 3 + _(album.name).must_equal 'Eclipse' end end end diff --git a/test/persisted_test.rb b/test/persisted_test.rb index c86eea2..a171db1 100644 --- a/test/persisted_test.rb +++ b/test/persisted_test.rb @@ -1,4 +1,6 @@ -require "test_helper" +# frozen_string_literal: true + +require 'test_helper' class PersistedTest < MiniTest::Spec class AlbumTwin < Disposable::Twin @@ -24,63 +26,60 @@ class AlbumTwin < Disposable::Twin it do artist = Artist.new - ex_song = Song.create(title: "Run For Cover") + ex_song = Song.create(title: 'Run For Cover') song = Song.new album = Album.new(artist: artist, songs: [ex_song, song]) - - expect(artist.persisted?).must_equal false - expect(album.persisted?).must_equal false - expect(ex_song.persisted?).must_equal true - expect(song.persisted?).must_equal false + _(artist.persisted?).must_equal false + _(album.persisted?).must_equal false + _(ex_song.persisted?).must_equal true + _(song.persisted?).must_equal false twin = AlbumTwin.new(album) - expect(twin.persisted?).must_equal false - expect(twin.changed?(:persisted?)).must_equal false - expect(twin.artist.persisted?).must_equal false - expect(twin.artist.changed?(:persisted?)).must_equal false - expect(twin.songs[0].persisted?).must_equal true - expect(twin.songs[0].changed?(:persisted?)).must_equal false - expect(twin.songs[1].persisted?).must_equal false - expect(twin.songs[1].changed?(:persisted?)).must_equal false + _(twin.persisted?).must_equal false + _(twin.changed?(:persisted?)).must_equal false + _(twin.artist.persisted?).must_equal false + _(twin.artist.changed?(:persisted?)).must_equal false + _(twin.songs[0].persisted?).must_equal true + _(twin.songs[0].changed?(:persisted?)).must_equal false + _(twin.songs[1].persisted?).must_equal false + _(twin.songs[1].changed?(:persisted?)).must_equal false twin.save - expect(artist.persisted?).must_equal true - expect(album.persisted?).must_equal true - expect(ex_song.persisted?).must_equal true - expect(song.persisted?).must_equal true - - expect(twin.persisted?).must_equal true - expect(twin.changed?(:persisted?)).must_equal true - expect(twin.artist.persisted?).must_equal true - expect(twin.artist.changed?(:persisted?)).must_equal true - expect(twin.songs[0].persisted?).must_equal true - expect(twin.songs[0].changed?(:persisted?)).must_equal false - expect(twin.songs[1].persisted?).must_equal true - expect(twin.songs[1].changed?(:persisted?)).must_equal true + _(artist.persisted?).must_equal true + _(album.persisted?).must_equal true + _(ex_song.persisted?).must_equal true + _(song.persisted?).must_equal true + + _(twin.persisted?).must_equal true + _(twin.changed?(:persisted?)).must_equal true + _(twin.artist.persisted?).must_equal true + _(twin.artist.changed?(:persisted?)).must_equal true + _(twin.songs[0].persisted?).must_equal true + _(twin.songs[0].changed?(:persisted?)).must_equal false + _(twin.songs[1].persisted?).must_equal true + _(twin.songs[1].changed?(:persisted?)).must_equal true end - - describe "#created?" do + describe '#created?' do it do twin = AlbumTwin.new(Album.new) - expect(twin.created?).must_equal false + _(twin.created?).must_equal false twin.save - expect(twin.created?).must_equal true + _(twin.created?).must_equal true end it do twin = AlbumTwin.new(Album.create) - expect(twin.created?).must_equal false + _(twin.created?).must_equal false twin.save - expect(twin.created?).must_equal false + _(twin.created?).must_equal false end end - # describe "#updated?" do # it do # twin = AlbumTwin.new(Album.new) diff --git a/test/rescheme_test.rb b/test/rescheme_test.rb index cdde8ef..0babf61 100644 --- a/test/rescheme_test.rb +++ b/test/rescheme_test.rb @@ -1,25 +1,27 @@ -require "test_helper" +# frozen_string_literal: true + +require 'test_helper' class ReschemeTest < MiniTest::Spec module Representer include Representable property :id - property :title, writeable: false, deserializer: {skip_parse: "skip lambda"} - property :songs, readable: false, deserializer: {skip_parse: "another lambda", music: true, writeable: false} do - property :name, as: "Name", deserializer: {skip_parse: "a crazy cool instance method"} + property :title, writeable: false, deserializer: { skip_parse: 'skip lambda' } + property :songs, readable: false, deserializer: { skip_parse: 'another lambda', music: true, writeable: false } do + property :name, as: 'Name', deserializer: { skip_parse: 'a crazy cool instance method' } end end module Hello def hello - "hello" + 'hello' end end module Ciao def ciao - "ciao" + 'ciao' end end @@ -31,103 +33,94 @@ def hello it do decorator = Disposable::Rescheme.from(Representer, superclass: Representable::Decorator, - include: [Representable::Hash, Hello, Gday, Ciao], # Hello will win over Gday. - options_from: :deserializer, - definitions_from: lambda { |nested| nested.definitions } - ) + include: [Representable::Hash, Hello, Gday, Ciao], # Hello will win over Gday. + options_from: :deserializer, + definitions_from: ->(nested) { nested.definitions }) # include: works. - expect(decorator.new(nil).hello).must_equal "hello" - expect(decorator.new(nil).ciao).must_equal "ciao" + _(decorator.new(nil).hello).must_equal 'hello' + _(decorator.new(nil).ciao).must_equal 'ciao' - expect(decorator.representable_attrs.get(:id).inspect).must_equal "#id @options={:name=>\"id\", :parse_filter=>[], :render_filter=>[]}>" - expect(decorator.representable_attrs.get(:title).inspect).must_equal "#title @options={:writeable=>false, :deserializer=>{:skip_parse=>\"skip lambda\"}, :name=>\"title\", :parse_filter=>[], :render_filter=>[], :skip_parse=>\"skip lambda\"}>" + _(decorator.representable_attrs.get(:id).inspect).must_equal '#id @options={:name=>"id", :parse_filter=>[], :render_filter=>[]}>' + _(decorator.representable_attrs.get(:title).inspect).must_equal '#title @options={:writeable=>false, :deserializer=>{:skip_parse=>"skip lambda"}, :name=>"title", :parse_filter=>[], :render_filter=>[], :skip_parse=>"skip lambda"}>' songs = decorator.representable_attrs.get(:songs) options = songs.instance_variable_get(:@options) options[:nested].extend(Declarative::Inspect) - expect(options.inspect).must_equal "{:readable=>false, :deserializer=>{:skip_parse=>\"another lambda\", :music=>true, :writeable=>false}, :nested=>#, :extend=>#, :name=>\"songs\", :parse_filter=>[], :render_filter=>[], :skip_parse=>\"another lambda\", :music=>true, :writeable=>false}" + _(options.inspect).must_equal '{:readable=>false, :deserializer=>{:skip_parse=>"another lambda", :music=>true, :writeable=>false}, :nested=>#, :extend=>#, :name=>"songs", :parse_filter=>[], :render_filter=>[], :skip_parse=>"another lambda", :music=>true, :writeable=>false}' # nested works. - expect(options[:nested].new(nil).hello).must_equal "hello" - expect(options[:nested].new(nil).ciao).must_equal "ciao" + _(options[:nested].new(nil).hello).must_equal 'hello' + _(options[:nested].new(nil).ciao).must_equal 'ciao' - expect(options[:nested].representable_attrs.get(:name).inspect).must_equal "#name @options={:as=>\"Name\", :deserializer=>{:skip_parse=>\"a crazy cool instance method\"}, :name=>\"name\", :parse_filter=>[], :render_filter=>[], :skip_parse=>\"a crazy cool instance method\"}>" + _(options[:nested].representable_attrs.get(:name).inspect).must_equal '#name @options={:as=>"Name", :deserializer=>{:skip_parse=>"a crazy cool instance method"}, :name=>"name", :parse_filter=>[], :render_filter=>[], :skip_parse=>"a crazy cool instance method"}>' end # :options_from and :include is optional it do decorator = Disposable::Rescheme.from(Representer, superclass: Representable::Decorator, include: [Representable::Hash], - definitions_from: lambda { |nested| nested.definitions } - ) + definitions_from: ->(nested) { nested.definitions }) - expect(decorator.representable_attrs.get(:id).inspect).must_equal "#id @options={:name=>\"id\", :parse_filter=>[], :render_filter=>[]}>" - expect(decorator.representable_attrs.get(:title).inspect).must_equal "#title @options={:writeable=>false, :deserializer=>{:skip_parse=>\"skip lambda\"}, :name=>\"title\", :parse_filter=>[], :render_filter=>[]}>" + _(decorator.representable_attrs.get(:id).inspect).must_equal '#id @options={:name=>"id", :parse_filter=>[], :render_filter=>[]}>' + _(decorator.representable_attrs.get(:title).inspect).must_equal '#title @options={:writeable=>false, :deserializer=>{:skip_parse=>"skip lambda"}, :name=>"title", :parse_filter=>[], :render_filter=>[]}>' end - # :exclude_options allows skipping particular options when copying. it do decorator = Disposable::Rescheme.from(Representer, superclass: Representable::Decorator, include: [Representable::Hash], - definitions_from: lambda { |nested| nested.definitions }, - exclude_options: [:deserializer] - ) + definitions_from: ->(nested) { nested.definitions }, + exclude_options: [:deserializer]) - expect(decorator.representable_attrs.get(:id).inspect).must_equal "#id @options={:name=>\"id\", :parse_filter=>[], :render_filter=>[]}>" - expect(decorator.representable_attrs.get(:title).inspect).must_equal "#title @options={:writeable=>false, :name=>\"title\", :parse_filter=>[], :render_filter=>[]}>" - expect(decorator.representable_attrs.get(:songs).representer_module.representable_attrs.get(:name).inspect).must_equal "#name @options={:as=>\"Name\", :name=>\"name\", :parse_filter=>[], :render_filter=>[]}>" + _(decorator.representable_attrs.get(:id).inspect).must_equal '#id @options={:name=>"id", :parse_filter=>[], :render_filter=>[]}>' + _(decorator.representable_attrs.get(:title).inspect).must_equal '#title @options={:writeable=>false, :name=>"title", :parse_filter=>[], :render_filter=>[]}>' + _(decorator.representable_attrs.get(:songs).representer_module.representable_attrs.get(:name).inspect).must_equal '#name @options={:as=>"Name", :name=>"name", :parse_filter=>[], :render_filter=>[]}>' end - - it "::from with block allows customizing every definition and returns representer" do + it '::from with block allows customizing every definition and returns representer' do decorator = Disposable::Rescheme.from(Representer, include: [Representable::Hash], - superclass: Representable::Decorator, - definitions_from: lambda { |nested| nested.definitions }, - ) { |dfn| dfn.merge!(amazing: true) } + superclass: Representable::Decorator, + definitions_from: ->(nested) { nested.definitions }) { |dfn| dfn.merge!(amazing: true) } - expect(decorator.representable_attrs.get(:id).inspect).must_equal "#id @options={:name=>\"id\", :parse_filter=>[], :render_filter=>[], :amazing=>true}>" - expect(decorator.representable_attrs.get(:songs).representer_module.representable_attrs.get(:name).inspect).must_equal "#name @options={:as=>\"Name\", :deserializer=>{:skip_parse=>\"a crazy cool instance method\"}, :name=>\"name\", :parse_filter=>[], :render_filter=>[], :amazing=>true}>" + _(decorator.representable_attrs.get(:id).inspect).must_equal '#id @options={:name=>"id", :parse_filter=>[], :render_filter=>[], :amazing=>true}>' + _(decorator.representable_attrs.get(:songs).representer_module.representable_attrs.get(:name).inspect).must_equal '#name @options={:as=>"Name", :deserializer=>{:skip_parse=>"a crazy cool instance method"}, :name=>"name", :parse_filter=>[], :render_filter=>[], :amazing=>true}>' end - it "recursive: false only copies first level" do + it 'recursive: false only copies first level' do decorator = Disposable::Rescheme.from(Representer, include: [Representable::Hash], - superclass: Representable::Decorator, - definitions_from: lambda { |nested| nested.definitions }, - recursive: false, - exclude_options: [:deserializer] - ) - - expect(decorator.representable_attrs.get(:title).inspect).must_equal "#title @options={:writeable=>false, :name=>\"title\", :parse_filter=>[], :render_filter=>[]}>" - expect(decorator.representable_attrs.get(:songs).representer_module.representable_attrs.get(:name).inspect).must_equal "#name @options={:as=>\"Name\", :deserializer=>{:skip_parse=>\"a crazy cool instance method\"}, :name=>\"name\", :parse_filter=>[], :render_filter=>[]}>" + superclass: Representable::Decorator, + definitions_from: ->(nested) { nested.definitions }, + recursive: false, + exclude_options: [:deserializer]) + + _(decorator.representable_attrs.get(:title).inspect).must_equal '#title @options={:writeable=>false, :name=>"title", :parse_filter=>[], :render_filter=>[]}>' + _(decorator.representable_attrs.get(:songs).representer_module.representable_attrs.get(:name).inspect).must_equal '#name @options={:as=>"Name", :deserializer=>{:skip_parse=>"a crazy cool instance method"}, :name=>"name", :parse_filter=>[], :render_filter=>[]}>' end - describe ":exclude_properties" do + describe ':exclude_properties' do module SmallRepresenter include Representable property :id property :songs do property :id - property :name, as: "Name" + property :name, as: 'Name' end end it do decorator = Disposable::Rescheme.from(SmallRepresenter, - include: [Representable::Hash], - superclass: Representable::Decorator, - definitions_from: lambda { |nested| nested.definitions }, - recursive: true, - exclude_properties: [:id] - ) - - expect(decorator.definitions.keys).must_equal ["songs"] - expect(decorator.definitions.get(:songs).representer_module.definitions.keys).must_equal ["name"] + include: [Representable::Hash], + superclass: Representable::Decorator, + definitions_from: ->(nested) { nested.definitions }, + recursive: true, + exclude_properties: [:id]) + + _(decorator.definitions.keys).must_equal ['songs'] + _(decorator.definitions.get(:songs).representer_module.definitions.keys).must_equal ['name'] end end end - class TwinReschemeTest < MiniTest::Spec class Artist < Disposable::Twin property :name @@ -139,14 +132,13 @@ class Album < Disposable::Twin it do decorator = Disposable::Rescheme.from(Album, superclass: Representable::Decorator, include: [Representable::Hash], - definitions_from: lambda { |nested| nested.definitions } - ) + definitions_from: ->(nested) { nested.definitions }) artist = decorator.representable_attrs.get(:artist) options = artist.instance_variable_get(:@options) nested_extend = options[:nested] - expect(options.extend(Declarative::Inspect).inspect).must_equal "{:private_name=>:artist, :nested=>#, :name=>\"artist\", :extend=>#, :parse_filter=>[], :render_filter=>[]}" + _(options.extend(Declarative::Inspect).inspect).must_equal '{:private_name=>:artist, :nested=>#, :name=>"artist", :extend=>#, :parse_filter=>[], :render_filter=>[]}' assert nested_extend < Representable::Decorator - expect(nested_extend.representable_attrs.get(:name).inspect).must_equal "#name @options={:private_name=>:name, :name=>\"name\", :parse_filter=>[], :render_filter=>[]}>" + _(nested_extend.representable_attrs.get(:name).inspect).must_equal '#name @options={:private_name=>:name, :name=>"name", :parse_filter=>[], :render_filter=>[]}>' end end diff --git a/test/skip_getter_test.rb b/test/skip_getter_test.rb index 402f636..6ad2304 100644 --- a/test/skip_getter_test.rb +++ b/test/skip_getter_test.rb @@ -1,4 +1,6 @@ -require "test_helper" +# frozen_string_literal: true + +require 'test_helper' class SkipGetterTest < MiniTest::Spec Album = Struct.new(:title, :artist) @@ -23,27 +25,26 @@ def title end it do - album = Album.new("Wild Frontier", Artist.new("Gary Moore")) + album = Album.new('Wild Frontier', Artist.new('Gary Moore')) twin = AlbumTwin.new(album) - expect(twin.title).must_equal "reitnorF dliW" - expect(twin.artist.name).must_equal "GARY MOORE" + _(twin.title).must_equal 'reitnorF dliW' + _(twin.artist.name).must_equal 'GARY MOORE' twin.sync # does NOT call getter. - expect(album.title).must_equal "Wild Frontier" - expect(album.artist.name).must_equal "Gary Moore" + _(album.title).must_equal 'Wild Frontier' + _(album.artist.name).must_equal 'Gary Moore' # nested hash. nested_hash = nil twin.sync do |hash| nested_hash = hash end - expect(nested_hash).must_equal({"title"=>"Wild Frontier", "artist"=>{"name"=>"Gary Moore"}}) + _(nested_hash).must_equal({ 'title' => 'Wild Frontier', 'artist' => { 'name' => 'Gary Moore' } }) end end - class SkipSetterTest < MiniTest::Spec Album = Struct.new(:title, :artist) Artist = Struct.new(:name) @@ -66,14 +67,13 @@ def title=(v) end it do - twin = AlbumTwin.new(Album.new("Wild Frontier", Artist.new("Gary Moore"))) + twin = AlbumTwin.new(Album.new('Wild Frontier', Artist.new('Gary Moore'))) - expect(twin.title).must_equal "Wild Frontier" - expect(twin.artist.name).must_equal "Gary Moore" + _(twin.title).must_equal 'Wild Frontier' + _(twin.artist.name).must_equal 'Gary Moore' end end - class SkipGetterAndSetterWithChangedTest < MiniTest::Spec Album = Struct.new(:title, :artist) Artist = Struct.new(:name) @@ -107,22 +107,21 @@ def title=(v) end it do - album = Album.new("Wild Frontier", Artist.new("Gary Moore")) + album = Album.new('Wild Frontier', Artist.new('Gary Moore')) twin = AlbumTwin.new(album) # does not call getter (Changed). + _(twin.title).must_equal 'reitnorF dliW' + _(twin.artist.name).must_equal 'GARY MOORE' - expect(twin.title).must_equal "reitnorF dliW" - expect(twin.artist.name).must_equal "GARY MOORE" - - expect(twin.changed?).must_equal false - expect(twin.artist.changed?).must_equal false + _(twin.changed?).must_equal false + _(twin.artist.changed?).must_equal false - twin.title = "Self-Entitled" - twin.artist.name = "Nofx" + twin.title = 'Self-Entitled' + twin.artist.name = 'Nofx' twin.sync # does NOT call getter. - expect(album.title).must_equal "deltitnE-fleS" - expect(album.artist.name).must_equal "Nof" + _(album.title).must_equal 'deltitnE-fleS' + _(album.artist.name).must_equal 'Nof' end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 41f4fec..2bdba07 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,15 +1,14 @@ -require "disposable" -require "minitest/autorun" -require "representable/debug" -# require "pp" -require "declarative/testing" +# frozen_string_literal: true -require "disposable/twin/coercion" -DRY_TYPES_CONSTANT = Disposable::Twin::Coercion::DRY_TYPES_CONSTANT -DRY_TYPES_INT_CONSTANT = Disposable::Twin::Coercion::DRY_TYPES_VERSION < Gem::Version.new("0.13.0") ? 'Int' : 'Integer' +require 'disposable' +require 'minitest/autorun' +require 'representable/debug' +require 'declarative/testing' + +require 'disposable/twin/coercion' class Track - def initialize(options={}) + def initialize(options = {}) @title = options[:title] end @@ -35,8 +34,8 @@ class Album < ActiveRecord::Base end ActiveRecord::Base.establish_connection( - :adapter => "sqlite3", - :database => ":memory:" + adapter: 'sqlite3', + database: ':memory:' ) ActiveRecord::Schema.define do @@ -78,4 +77,3 @@ def saved? end end end - diff --git a/test/twin/benchmarking.rb b/test/twin/benchmarking.rb index 40f2ed0..d2ccfac 100644 --- a/test/twin/benchmarking.rb +++ b/test/twin/benchmarking.rb @@ -1,4 +1,6 @@ -require "disposable/twin" +# frozen_string_literal: true + +require 'disposable/twin' require 'ostruct' require 'benchmark' @@ -10,8 +12,8 @@ class Band < Disposable::Twin end end -songs = 50.times.collect { Struct.new(:title).new("Be Stag") } -band = Struct.new(:name, :songs).new("Teenage Bottlerock", songs) +songs = 50.times.collect { Struct.new(:title).new('Be Stag') } +band = Struct.new(:name, :songs).new('Teenage Bottlerock', songs) time = Benchmark.measure do 1000.times do @@ -27,6 +29,5 @@ class Band < Disposable::Twin # with setup and new(fields).from_object(twin) instead of Fields.new(to_hash) # 3.680000 0.000000 3.680000 ( 3.685796) - # 06/01 # 0.300000 0.000000 0.300000 ( 0.298956) diff --git a/test/twin/builder_test.rb b/test/twin/builder_test.rb index a3a3c79..09fea96 100644 --- a/test/twin/builder_test.rb +++ b/test/twin/builder_test.rb @@ -1,4 +1,6 @@ -require "test_helper" +# frozen_string_literal: true + +require 'test_helper' class BuilderTest < MiniTest::Spec module Model @@ -13,10 +15,10 @@ class Twin < Disposable::Twin # option :is_released include Builder - builds ->(model, options) do + builds lambda { |model, options| return Hit if model.is_a? Model::Hit return Evergreen if options[:evergreen] - end + } end class Hit < Twin @@ -25,8 +27,7 @@ class Hit < Twin class Evergreen < Twin end - - it { expect(Twin.build(Model::Song.new)).must_be_instance_of Twin } - it { expect(Twin.build(Model::Hit.new)).must_be_instance_of Hit } - it { expect(Twin.build(Model::Evergreen.new, evergreen: true)).must_be_instance_of Evergreen } + it { _(Twin.build(Model::Song.new)).must_be_instance_of Twin } + it { _(Twin.build(Model::Hit.new)).must_be_instance_of Hit } + it { _(Twin.build(Model::Evergreen.new, evergreen: true)).must_be_instance_of Evergreen } end diff --git a/test/twin/changed_test.rb b/test/twin/changed_test.rb index 7bf78d1..2e10172 100644 --- a/test/twin/changed_test.rb +++ b/test/twin/changed_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' # require 'reform/form/coercion' @@ -29,84 +31,82 @@ class Album < Disposable::Twin end end - - let (:song) { Model::Song.new("Broken") } - let (:composer) { Model::Artist.new(2) } - let (:song_with_composer) { Model::Song.new("Broken", 246, composer) } - let (:artist) { Model::Artist.new("Randy") } - let (:album) { Model::Album.new("The Rest Is Silence", [song, song_with_composer], artist) } - let (:twin) { Twin::Album.new(album) } + let(:song) { Model::Song.new('Broken') } + let(:composer) { Model::Artist.new(2) } + let(:song_with_composer) { Model::Song.new('Broken', 246, composer) } + let(:artist) { Model::Artist.new('Randy') } + let(:album) { Model::Album.new('The Rest Is Silence', [song, song_with_composer], artist) } + let(:twin) { Twin::Album.new(album) } # setup: changed? is always false it do - expect(twin.changed?(:name)).must_equal false - expect(twin.changed?).must_equal false + _(twin.changed?(:name)).must_equal false + _(twin.changed?).must_equal false - expect(twin.songs[0].changed?).must_equal false - expect(twin.songs[0].changed?(:title)).must_equal false - expect(twin.songs[1].changed?).must_equal false - expect(twin.songs[1].changed?(:title)).must_equal false + _(twin.songs[0].changed?).must_equal false + _(twin.songs[0].changed?(:title)).must_equal false + _(twin.songs[1].changed?).must_equal false + _(twin.songs[1].changed?(:title)).must_equal false - expect(twin.songs[1].composer.changed?(:name)).must_equal false - expect(twin.songs[1].composer.changed?).must_equal false + _(twin.songs[1].composer.changed?(:name)).must_equal false + _(twin.songs[1].composer.changed?).must_equal false - expect(twin.artist.changed?(:name)).must_equal false - expect(twin.artist.changed?).must_equal false + _(twin.artist.changed?(:name)).must_equal false + _(twin.artist.changed?).must_equal false end # only when a property is assigned, it's changed. it do - twin.name= "Out Of Bounds" - twin.songs[0].title= "I Have Seen" - twin.songs[1].title= "In A Rhyme" - twin.songs[1].composer.name= "Ingemar Jansson & Mikael Danielsson" - twin.artist.name = "No Fun At All" + twin.name = 'Out Of Bounds' + twin.songs[0].title = 'I Have Seen' + twin.songs[1].title = 'In A Rhyme' + twin.songs[1].composer.name = 'Ingemar Jansson & Mikael Danielsson' + twin.artist.name = 'No Fun At All' - expect(twin.changed?(:name)).must_equal true - expect(twin.changed?).must_equal true + _(twin.changed?(:name)).must_equal true + _(twin.changed?).must_equal true - expect(twin.songs[0].changed?).must_equal true - expect(twin.songs[0].changed?(:title)).must_equal true - expect(twin.songs[1].changed?).must_equal true - expect(twin.songs[1].changed?(:title)).must_equal true + _(twin.songs[0].changed?).must_equal true + _(twin.songs[0].changed?(:title)).must_equal true + _(twin.songs[1].changed?).must_equal true + _(twin.songs[1].changed?(:title)).must_equal true - expect(twin.songs[1].composer.changed?(:name)).must_equal true - expect(twin.songs[1].composer.changed?).must_equal true + _(twin.songs[1].composer.changed?(:name)).must_equal true + _(twin.songs[1].composer.changed?).must_equal true - expect(twin.artist.changed?(:name)).must_equal true - expect(twin.artist.changed?).must_equal true + _(twin.artist.changed?(:name)).must_equal true + _(twin.artist.changed?).must_equal true # you can also ask for nested twins by name. - expect(twin.changed?(:songs)).must_equal true - expect(twin.songs[0].changed?(:composer)).must_equal false - expect(twin.songs[1].changed?(:composer)).must_equal true - expect(twin.changed?(:artist)).must_equal true + _(twin.changed?(:songs)).must_equal true + _(twin.songs[0].changed?(:composer)).must_equal false + _(twin.songs[1].changed?(:composer)).must_equal true + _(twin.changed?(:artist)).must_equal true end # nested changes should propagate up. it do - expect(twin.changed?).must_equal false + _(twin.changed?).must_equal false - twin.songs[1].composer.name = "Nofx" + twin.songs[1].composer.name = 'Nofx' - expect(twin.changed?).must_equal true + _(twin.changed?).must_equal true assert twin.songs.changed? - expect(twin.songs[1].changed?).must_equal true - expect(twin.songs[0].changed?).must_equal false + _(twin.songs[1].changed?).must_equal true + _(twin.songs[0].changed?).must_equal false - expect(twin.artist.changed?).must_equal false + _(twin.artist.changed?).must_equal false end # setting identical value doesn't change. it do - twin.name = "The Rest Is Silence" - expect(twin.changed?).must_equal false + twin.name = 'The Rest Is Silence' + _(twin.changed?).must_equal false end end - -require "disposable/twin/coercion" +require 'disposable/twin/coercion' class ChangedWithCoercionTest < MiniTest::Spec Song = Struct.new(:released) @@ -114,23 +114,23 @@ class SongTwin < Disposable::Twin include Changed include Coercion - property :released, type: DRY_TYPES_CONSTANT::Bool | DRY_TYPES_CONSTANT::Nil + property :released, type: Types::Params::Bool | Types::Params::Nil end it do twin = SongTwin.new(Song.new) - expect(twin.changed?(:released)).must_equal false + _(twin.changed?(:released)).must_equal false twin.released = 'true' - expect(twin.released).must_equal true - expect(twin.changed?(:released)).must_equal true + _(twin.released).must_equal true + _(twin.changed?(:released)).must_equal true end it do twin = SongTwin.new(Song.new(true)) - expect(twin.changed?(:released)).must_equal false + _(twin.changed?(:released)).must_equal false twin.released = 'true' # it coerces, then assigns, then compares, which makes this NOT changed. - expect(twin.changed?(:released)).must_equal false + _(twin.changed?(:released)).must_equal false twin.released = 'false' - expect(twin.changed?(:released)).must_equal true + _(twin.changed?(:released)).must_equal true end end diff --git a/test/twin/coercion_test.rb b/test/twin/coercion_test.rb index 7b0f8ca..39cb469 100644 --- a/test/twin/coercion_test.rb +++ b/test/twin/coercion_test.rb @@ -1,6 +1,8 @@ -require "test_helper" +# frozen_string_literal: true -require "disposable/twin/coercion" +require 'test_helper' + +require 'disposable/twin/coercion' class CoercionTest < MiniTest::Spec class TwinWithSkipSetter < Disposable::Twin @@ -8,11 +10,11 @@ class TwinWithSkipSetter < Disposable::Twin feature Setup::SkipSetter property :id - property :released_at, type: DRY_TYPES_CONSTANT::DateTime + property :released_at, type: Types::Params::DateTime property :hit do - property :length, type: const_get("Types::Coercible::#{DRY_TYPES_INT_CONSTANT}") - property :good, type: Types::Bool + property :length, type: Types::Params::Integer + property :good, type: Types::Params::Bool end property :band do @@ -22,133 +24,54 @@ class TwinWithSkipSetter < Disposable::Twin end end - describe "with Setup::SkipSetter" do + describe 'with Setup::SkipSetter' do subject do TwinWithSkipSetter.new(album) end - let (:album) { + let(:album) do OpenStruct.new( id: 1, - :released_at => "31/03/1981", - :hit => OpenStruct.new(:length => "312"), - :band => OpenStruct.new(:label => OpenStruct.new(:value => "9999.99")) + released_at: '31/03/1981', + hit: OpenStruct.new(length: '312'), + band: OpenStruct.new(label: OpenStruct.new(value: '9999.99')) ) - } - - it "NOT coerce values in setup" do - expect(subject.released_at).must_equal "31/03/1981" - expect(subject.hit.length).must_equal "312" - expect(subject.band.label.value).must_equal "9999.99" end + it 'NOT coerce values in setup' do + _(subject.released_at).must_equal '31/03/1981' + _(subject.hit.length).must_equal '312' + _(subject.band.label.value).must_equal '9999.99' + end - it "coerce values when using a setter" do + it 'coerce values when using a setter' do subject.id = Object - subject.released_at = "30/03/1981" - subject.hit.length = "312" - subject.band.label.value = "9999.99" - - expect(subject.released_at).must_be_kind_of DateTime - expect(subject.released_at).must_equal DateTime.parse("30/03/1981") - expect(subject.hit.length).must_equal 312 - expect(subject.hit.good).must_be_nil - expect(subject.band.label.value).must_equal 9999.99 + subject.released_at = '30/03/1981' + subject.hit.length = '312' + subject.band.label.value = '9999.99' + + _(subject.released_at).must_be_kind_of DateTime + _(subject.released_at).must_equal DateTime.parse('30/03/1981') + _(subject.hit.length).must_equal 312 + _(subject.hit.good).must_be_nil + _(subject.band.label.value).must_equal 9999.99 end end class TwinWithoutSkipSetter < Disposable::Twin feature Coercion - property :id, type: const_get("Types::Coercible::#{DRY_TYPES_INT_CONSTANT}") + property :id, type: Types::Params::Integer end - describe "without Setup::SkipSetter" do - + describe 'without Setup::SkipSetter' do subject do - TwinWithoutSkipSetter.new(OpenStruct.new(id: "1")) + TwinWithoutSkipSetter.new(OpenStruct.new(id: '1')) end - it "coerce values in setup and when using a setter" do - expect(subject.id).must_equal 1 - subject.id = "2" - expect(subject.id).must_equal 2 - end - end - - class TwinWithNilify < Disposable::Twin - feature Coercion - - property :date_of_birth, - type: DRY_TYPES_CONSTANT::Date, nilify: true - property :date_of_death_by_unicorns, - type: DRY_TYPES_CONSTANT::Nil | DRY_TYPES_CONSTANT::Date - property :id, type: const_get("Types::Coercible::#{DRY_TYPES_INT_CONSTANT}"), nilify: true - end - - class TwinWithoutTypeWithNilify < Disposable::Twin - feature Coercion - - property :date_of_birth, nilify: true - property :date_of_death_by_unicorns, type: DRY_TYPES_CONSTANT::Nil | DRY_TYPES_CONSTANT::Date - property :id, type: const_get("Types::Coercible::#{DRY_TYPES_INT_CONSTANT}"), nilify: true - end - - describe "with Nilify" do - subject do - TwinWithNilify.new(OpenStruct.new(date_of_birth: '1990-01-12', - date_of_death_by_unicorns: '2037-02-18', - id: 1)) - end - - it "coerce values correctly" do - expect(subject.date_of_birth).must_equal Date.parse('1990-01-12') - expect(subject.date_of_death_by_unicorns).must_equal Date.parse('2037-02-18') - end - - it "coerce empty values to nil when using option nilify: true" do - subject.date_of_birth = "" - expect(subject.date_of_birth).must_be_nil - end - - it "coerce empty values to nil when using dry-types | operator" do - subject.date_of_death_by_unicorns = "" - expect(subject.date_of_death_by_unicorns).must_be_nil - end - - it "converts blank string to nil, without :type option" do - subject.id = "" - expect(subject.id).must_be_nil - end - end - - describe "without Type With Nilify" do - let(:date_of_birth) { '1990-01-12' } - subject do - TwinWithoutTypeWithNilify.new( - OpenStruct.new( - date_of_birth: date_of_birth, - date_of_death_by_unicorns: '2037-02-18', - id: 1 - ) - ) - end - - it 'raise error for new dry-types v - work as expected for older versions' do - if Disposable::Twin::Coercion::DRY_TYPES_VERSION >= Gem::Version.new("1.0") - assert_raises(Dry::Types::CoercionError) { subject.date_of_birth } - assert_raises(Dry::Types::CoercionError) { subject.date_of_death_by_unicorns } - else - expect(subject.date_of_birth).must_equal '1990-01-12' - expect(subject.date_of_death_by_unicorns).must_equal Date.parse('2037-02-18') - end - end - - describe 'when passing nil' do - let(:date_of_birth) { '' } - - it 'coerce values correctly' do - expect(subject.date_of_birth).must_be_nil - end + it 'coerce values in setup and when using a setter' do + _(subject.id).must_equal 1 + subject.id = '2' + _(subject.id).must_equal 2 end end end @@ -173,13 +96,13 @@ class Song < Disposable::Twin # with type: Dry::Types::Strict::String # assert_raises(Dry::Types::ConstraintError) { twin.title = nil } twin.title = nil - expect(twin.title).must_be_nil + _(twin.title).must_be_nil - twin.title = "Yo" - expect(twin.title).must_equal "Yo" + twin.title = 'Yo' + _(twin.title).must_equal 'Yo' - twin.title = "" - expect(twin.title).must_equal "" + twin.title = '' + _(twin.title).must_equal '' assert_raises(Dry::Types::ConstraintError) { twin.title = :bla } assert_raises(Dry::Types::ConstraintError) { twin.title = 1 } @@ -190,40 +113,35 @@ class Form < Disposable::Twin include Coercion include Setup::SkipSetter - # property :title, type: Dry::Types::Strict::String.constructor(Dry::Types::Params.method(:to_nil)) - property :title, type: DRY_TYPES_CONSTANT::Nil | Types::Strict::String # this is the behavior of the "DB" data twin. this is NOT the form. + property :title, type: Types::Params::Nil | Types::Strict::String # this is the behavior of the "DB" data twin. this is NOT the form. # property :name, type: Types::Params::String - property :enabled, type: DRY_TYPES_CONSTANT::Bool + property :enabled, type: Types::Params::Bool # property :enabled, Bool.constructor(:trim!) end it do - twin =Form.new(Struct.new(:title, :enabled).new) + twin = Form.new(Struct.new(:title, :enabled).new) # assert_raises(Dry::Types::ConstraintError) { twin.title = nil } # in form, we either have a blank string or the key's not present at all. twin.title = nil - expect(twin.title).must_be_nil + _(twin.title).must_be_nil - twin.title = "" # nilify blank strings - expect(twin.title).must_be_nil + twin.title = '' # nilify blank strings + _(twin.title).must_be_nil - twin.title = "Yo" - expect(twin.title).must_equal "Yo" + twin.title = 'Yo' + _(twin.title).must_equal 'Yo' # twin.enabled = " TRUE" - #expect(twin.enabled).must_equal true + # twin.enabled.must_equal true end end - # def title=(String value) # allow obj.title = "bla" # def title=(Nil) # allow obj.title = nil - - # active = " TRUE HACK" # how to test/validate if active is boolean? - diff --git a/test/twin/collection_test.rb b/test/twin/collection_test.rb index 51133db..d0bcb59 100644 --- a/test/twin/collection_test.rb +++ b/test/twin/collection_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' # reason: unique API for collection (adding, removing, deleting, etc.) @@ -11,7 +13,6 @@ module Model Album = Struct.new(:id, :name, :songs, :artist) end - module Twin class Song < Disposable::Twin property :id # DISCUSS: needed for #save. @@ -26,33 +27,32 @@ class Album < Disposable::Twin end end - let (:song) { Model::Song.new(1, "Broken", nil) } - let (:album) { Model::Album.new(1, "The Rest Is Silence", [song]) } + let(:song) { Model::Song.new(1, 'Broken', nil) } + let(:album) { Model::Album.new(1, 'The Rest Is Silence', [song]) } - describe "reader for collection" do + describe 'reader for collection' do it do twin = Twin::Album.new(album) - expect(twin.songs.size).must_equal 1 - expect(twin.songs[0].title).must_equal "Broken" - expect(twin.songs).must_be_instance_of Disposable::Twin::Collection - + _(twin.songs.size).must_equal 1 + _(twin.songs[0].title).must_equal 'Broken' + _(twin.songs).must_be_instance_of Disposable::Twin::Collection end end - describe "#find_by" do - let (:album) { Model::Album.new(1, "The Rest Is Silence", [Model::Song.new(3), Model::Song.new(4)]) } - let (:twin) { Twin::Album.new(album) } + describe '#find_by' do + let(:album) { Model::Album.new(1, 'The Rest Is Silence', [Model::Song.new(3), Model::Song.new(4)]) } + let(:twin) { Twin::Album.new(album) } - it { expect(twin.songs.find_by(id: 1)).must_be_nil } - it { expect(twin.songs.find_by(id: 3)).must_equal twin.songs[0] } - it { expect(twin.songs.find_by(id: 4)).must_equal twin.songs[1] } - it { expect(twin.songs.find_by(id: "4")).must_equal twin.songs[1] } + it { _(twin.songs.find_by(id: 1)).must_be_nil } + it { _(twin.songs.find_by(id: 3)).must_equal twin.songs[0] } + it { _(twin.songs.find_by(id: 4)).must_equal twin.songs[1] } + it { _(twin.songs.find_by(id: '4')).must_equal twin.songs[1] } end end -require "disposable/twin/sync" -require "disposable/twin/save" +require 'disposable/twin/sync' +require 'disposable/twin/save' class TwinCollectionActiveRecordTest < MiniTest::Spec module Twin @@ -82,128 +82,126 @@ class Album < Disposable::Twin end end - let (:album) { Album.create(name: "The Rest Is Silence") } - let (:song1) { Song.new(title: "Snorty Pacifical Rascal") } # unsaved. - let (:song2) { Song.create(title: "At Any Cost") } # saved. - let (:twin) { Twin::Album.new(album) } + let(:album) { Album.create(name: 'The Rest Is Silence') } + let(:song1) { Song.new(title: 'Snorty Pacifical Rascal') } # unsaved. + let(:song2) { Song.create(title: 'At Any Cost') } # saved. + let(:twin) { Twin::Album.new(album) } it do # TODO: test all writers. twin.songs << song1 # assuming that we add AR model here. twin.songs << song2 - expect(twin.songs.size).must_equal 2 + _(twin.songs.size).must_equal 2 - expect(twin.songs[0]).must_be_instance_of Twin::Song # twin wraps << added in twin. - expect(twin.songs[1]).must_be_instance_of Twin::Song + _(twin.songs[0]).must_be_instance_of Twin::Song # twin wraps << added in twin. + _(twin.songs[1]).must_be_instance_of Twin::Song - # expect(twin.songs[0].persisted?).must_equal false - expect(twin.songs[0].send(:model).persisted?).must_equal false - expect(twin.songs[1].send(:model).persisted?).must_equal true + # twin.songs[0].persisted?.must_equal false + _(twin.songs[0].send(:model).persisted?).must_equal false + _(twin.songs[1].send(:model).persisted?).must_equal true - expect(album.songs.size).must_equal 0 # nothing synced, yet. + _(album.songs.size).must_equal 0 # nothing synced, yet. # sync: delete removed items, add new? # save twin.save - expect(album.persisted?).must_equal true - expect(album.name).must_equal "The Rest Is Silence" + _(album.persisted?).must_equal true + _(album.name).must_equal 'The Rest Is Silence' - expect(album.songs.size).must_equal 2 # synced! + _(album.songs.size).must_equal 2 # synced! - expect(album.songs[0].persisted?).must_equal true - expect(album.songs[1].persisted?).must_equal true - expect(album.songs[0].title).must_equal "Snorty Pacifical Rascal" - expect(album.songs[1].title).must_equal "At Any Cost" + _(album.songs[0].persisted?).must_equal true + _(album.songs[1].persisted?).must_equal true + _(album.songs[0].title).must_equal 'Snorty Pacifical Rascal' + _(album.songs[1].title).must_equal 'At Any Cost' end # test with adding to existing collection [song1] << song2 # TODO: #delete non-existent twin. - describe "#delete" do - let (:album) { Album.create(name: "The Rest Is Silence", songs: [song1]) } + describe '#delete' do + let(:album) { Album.create(name: 'The Rest Is Silence', songs: [song1]) } it do twin.songs.delete(twin.songs.first) - expect(twin.songs.size).must_equal 0 - expect(album.songs.size).must_equal 1 # not synced, yet. + _(twin.songs.size).must_equal 0 + _(album.songs.size).must_equal 1 # not synced, yet. twin.save - expect(twin.songs.size).must_equal 0 - expect(album.songs.size).must_equal 0 - expect(song1.persisted?).must_equal true + _(twin.songs.size).must_equal 0 + _(album.songs.size).must_equal 0 + _(song1.persisted?).must_equal true end # non-existant delete. it do - twin.songs.delete("non-existant") # won't delete anything. - expect(twin.songs.size).must_equal 1 + twin.songs.delete('non-existant') # won't delete anything. + _(twin.songs.size).must_equal 1 end end - describe "#destroy" do - let (:album) { Album.create(name: "The Rest Is Silence", songs: [song1]) } + describe '#destroy' do + let(:album) { Album.create(name: 'The Rest Is Silence', songs: [song1]) } it do twin.songs.destroy(twin.songs.first) - expect(twin.songs.size).must_equal 0 - expect(album.songs.size).must_equal 1 # not synced, yet. + _(twin.songs.size).must_equal 0 + _(album.songs.size).must_equal 1 # not synced, yet. twin.save - expect(twin.songs.size).must_equal 0 - expect(album.songs.size).must_equal 0 - expect(song1.persisted?).must_equal false + _(twin.songs.size).must_equal 0 + _(album.songs.size).must_equal 0 + _(song1.persisted?).must_equal false end end - - describe "#added" do - let (:album) { Album.create(name: "The Rest Is Silence", songs: [song1]) } + describe '#added' do + let(:album) { Album.create(name: 'The Rest Is Silence', songs: [song1]) } it do twin = Twin::Album.new(album) - expect(twin.songs.added).must_equal [] + _(twin.songs.added).must_equal [] twin.songs << song2 - expect(twin.songs.added).must_equal [twin.songs[1]] + _(twin.songs.added).must_equal [twin.songs[1]] twin.songs.insert(2, Song.new) - expect(twin.songs.added).must_equal [twin.songs[1], twin.songs[2]] + _(twin.songs.added).must_equal [twin.songs[1], twin.songs[2]] # TODO: what to do if we override an item (insert)? end end - describe "#deleted" do - let (:album) { Album.create(name: "The Rest Is Silence", songs: [song1, song2, Song.new]) } + describe '#deleted' do + let(:album) { Album.create(name: 'The Rest Is Silence', songs: [song1, song2, Song.new]) } it do twin = Twin::Album.new(album) - expect(twin.songs.deleted).must_equal [] + _(twin.songs.deleted).must_equal [] twin.songs.delete(deleted1 = twin.songs[-1]) twin.songs.delete(deleted2 = twin.songs[-1]) - expect(twin.songs).must_equal [twin.songs[0]] + _(twin.songs).must_equal [twin.songs[0]] - expect(twin.songs.deleted).must_equal [deleted1, deleted2] + _(twin.songs.deleted).must_equal [deleted1, deleted2] end # non-existant delete. it do - twin.songs.delete("non-existant") # won't delete anything. - expect(twin.songs.deleted).must_equal [] + twin.songs.delete('non-existant') # won't delete anything. + _(twin.songs.deleted).must_equal [] end end end - class CollectionUnitTest < MiniTest::Spec module Twin class Album < Disposable::Twin @@ -223,24 +221,24 @@ module Model # #insert(index, model) it do - expect(collection.insert(0, Model::Album.new)).must_be_instance_of Twin::Album + _(collection.insert(0, Model::Album.new)).must_be_instance_of Twin::Album end # #append(model) it do - expect(collection.append(Model::Album.new)).must_be_instance_of Twin::Album - expect(collection[0]).must_be_instance_of Twin::Album + _(collection.append(Model::Album.new)).must_be_instance_of Twin::Album + _(collection[0]).must_be_instance_of Twin::Album # allows subsequent calls. collection.append(Model::Album.new) - expect(collection[1]).must_be_instance_of Twin::Album + _(collection[1]).must_be_instance_of Twin::Album - expect(collection.size).must_equal 2 + _(collection.size).must_equal 2 end # #<< it do - expect((collection << Model::Album.new)).must_be_instance_of Array - expect(collection[0]).must_be_instance_of Twin::Album + _((collection << Model::Album.new)).must_be_instance_of Array + _(collection[0]).must_be_instance_of Twin::Album end end diff --git a/test/twin/composition_test.rb b/test/twin/composition_test.rb index c6bd92c..569bcae 100644 --- a/test/twin/composition_test.rb +++ b/test/twin/composition_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' # Disposable::Twin::Composition. @@ -20,65 +22,66 @@ module Model Requester = Struct.new(:id, :name) end - let (:requester) { Model::Requester.new(1, "Greg Howe").extend(Disposable::Saveable) } - let (:song) { Model::Song.new(2, "Extraction").extend(Disposable::Saveable) } + let(:requester) { Model::Requester.new(1, 'Greg Howe').extend(Disposable::Saveable) } + let(:song) { Model::Song.new(2, 'Extraction').extend(Disposable::Saveable) } - let (:request) { Request.new(song: song, requester: requester) } + let(:request) { Request.new(song: song, requester: requester) } it do - expect(request.song_title).must_equal "Extraction" - expect(request.song_id).must_equal 2 - expect(request.name).must_equal "Greg Howe" - expect(request.id).must_equal 1 - - request.song_title = "Tease" - request.name = "Wooten" + _(request.song_title).must_equal 'Extraction' + _(request.song_id).must_equal 2 + _(request.name).must_equal 'Greg Howe' + _(request.id).must_equal 1 + request.song_title = 'Tease' + request.name = 'Wooten' - expect(request.song_title).must_equal "Tease" - expect(request.name).must_equal "Wooten" + _(request.song_title).must_equal 'Tease' + _(request.name).must_equal 'Wooten' # does not write to model. - expect(song.title).must_equal "Extraction" - expect(requester.name).must_equal "Greg Howe" - + _(song.title).must_equal 'Extraction' + _(requester.name).must_equal 'Greg Howe' res = request.save - expect(res).must_equal true + _(res).must_equal true # make sure models got synced and saved. - expect(song.id).must_equal 2 - expect(song.title).must_equal "Tease" - expect(requester.id).must_equal 1 - expect(requester.name).must_equal "Wooten" + _(song.id).must_equal 2 + _(song.title).must_equal 'Tease' + _(requester.id).must_equal 1 + _(requester.name).must_equal 'Wooten' - expect(song.saved?).must_equal true - expect(requester.saved?).must_equal true + _(song.saved?).must_equal true + _(requester.saved?).must_equal true end # save with block. it do - request.song_title = "Tease" - request.name = "Wooten" - request.captcha = "Awesome!" + request.song_title = 'Tease' + request.name = 'Wooten' + request.captcha = 'Awesome!' # does not write to model. - expect(song.title).must_equal "Extraction" - expect(requester.name).must_equal "Greg Howe" - + _(song.title).must_equal 'Extraction' + _(requester.name).must_equal 'Greg Howe' nested_hash = nil request.save do |hash| nested_hash = hash end - expect(nested_hash).must_equal(:song=>{"title"=>"Tease", "id"=>2}, :requester=>{"name"=>"Wooten", "id"=>1, "captcha"=>"Awesome!"}) + _(nested_hash).must_equal(song: { 'title' => 'Tease', 'id' => 2 }, requester: { 'name' => 'Wooten', 'id' => 1, 'captcha' => 'Awesome!' }) end # save with one unsaveable model. - #save returns result. + # save returns result. it do - song.instance_eval { def save; false; end } - expect(request.save).must_equal false + song.instance_eval do + def save + false + end + end + _(request.save).must_equal false end end diff --git a/test/twin/default_test.rb b/test/twin/default_test.rb index 9149e58..77d5df1 100644 --- a/test/twin/default_test.rb +++ b/test/twin/default_test.rb @@ -1,4 +1,6 @@ -require "test_helper" +# frozen_string_literal: true + +require 'test_helper' class DefaultTest < Minitest::Spec Song = Struct.new(:title, :new_album, :published, :genre, :composer) @@ -7,10 +9,10 @@ class DefaultTest < Minitest::Spec class Twin < Disposable::Twin feature Default - property :title, default: "Medio-Core" + property :title, default: 'Medio-Core' property :genre, default: -> { "Punk Rock #{model.class}" } property :composer, default: Composer.new do - property :name, default: "NOFX" + property :name, default: 'NOFX' end property :published, default: false property :new_album, default: true @@ -18,40 +20,40 @@ class Twin < Disposable::Twin # all given. it do - twin = Twin.new(Song.new("Anarchy Camp", false, true, "Punk", Composer.new("Nofx"))) - expect(twin.title).must_equal "Anarchy Camp" - expect(twin.genre).must_equal "Punk" - expect(twin.composer.name).must_equal "Nofx" - expect(twin.published).must_equal true - expect(twin.new_album).must_equal false + twin = Twin.new(Song.new('Anarchy Camp', false, true, 'Punk', Composer.new('Nofx'))) + _(twin.title).must_equal 'Anarchy Camp' + _(twin.genre).must_equal 'Punk' + _(twin.composer.name).must_equal 'Nofx' + _(twin.published).must_equal true + _(twin.new_album).must_equal false end # defaults, please. it do twin = Twin.new(Song.new) - expect(twin.title).must_equal "Medio-Core" - expect(twin.composer.name).must_equal "NOFX" - expect(twin.genre).must_equal "Punk Rock DefaultTest::Song" - expect(twin.published).must_equal false - expect(twin.new_album).must_equal true + _(twin.title).must_equal 'Medio-Core' + _(twin.composer.name).must_equal 'NOFX' + _(twin.genre).must_equal 'Punk Rock DefaultTest::Song' + _(twin.published).must_equal false + _(twin.new_album).must_equal true end # false value is not defaulted. it do twin = Twin.new(Song.new(false, false)) - expect(twin.title).must_equal false - expect(twin.new_album).must_equal false + _(twin.title).must_equal false + _(twin.new_album).must_equal false end - describe "inheritance" do + describe 'inheritance' do class SuperTwin < Disposable::Twin feature Default - property :name, default: "n/a" + property :name, default: 'n/a' end class MegaTwin < SuperTwin end - it { expect(MegaTwin.new(Composer.new).name).must_equal "n/a" } + it { _(MegaTwin.new(Composer.new).name).must_equal 'n/a' } end end @@ -60,13 +62,12 @@ class Twin < Disposable::Twin feature Default feature Changed - property :title, default: "0", virtual: true + property :title, default: '0', virtual: true end it do twin = Twin.new(Object.new) - expect(twin.title).must_equal "0" - # expect(twin.changed).must_equal [] + _(twin.title).must_equal '0' + # twin.changed.must_equal [] end end - diff --git a/test/twin/expose_test.rb b/test/twin/expose_test.rb index 41f4b0e..ad5a311 100644 --- a/test/twin/expose_test.rb +++ b/test/twin/expose_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' # Disposable::Twin::Expose. @@ -10,7 +12,7 @@ class Request < Disposable::Twin property :song_title, from: :title property :id # virtual. - property :captcha, readable: false, writeable: false + property :captcha, readable: false, writeable: false # nested. property :album do property :name, from: :getName @@ -22,52 +24,51 @@ module Model Album = Struct.new(:getName) end - let (:album) { Model::Album.new("Appeal To Reason").extend(Disposable::Saveable) } - let (:song) { Model::Song.new(2, "Extraction", album).extend(Disposable::Saveable) } + let(:album) { Model::Album.new('Appeal To Reason').extend(Disposable::Saveable) } + let(:song) { Model::Song.new(2, 'Extraction', album).extend(Disposable::Saveable) } - let (:request) { Request.new(song) } + let(:request) { Request.new(song) } it do - expect(request.song_title).must_equal "Extraction" - expect(request.id).must_equal 2 + _(request.song_title).must_equal 'Extraction' + _(request.id).must_equal 2 - request.song_title = "Tease" + request.song_title = 'Tease' request.id = 1 - - expect(request.song_title).must_equal "Tease" - expect(request.id).must_equal 1 + _(request.song_title).must_equal 'Tease' + _(request.id).must_equal 1 # does not write to model. - expect(song.title).must_equal "Extraction" - expect(song.id).must_equal 2 + _(song.title).must_equal 'Extraction' + _(song.id).must_equal 2 request.save # make sure models got synced and saved. - expect(song.id).must_equal 1 - expect(song.title).must_equal "Tease" - expect(song.album).must_equal album # nested objects don't get twinned or anything. + _(song.id).must_equal 1 + _(song.title).must_equal 'Tease' + _(song.album).must_equal album # nested objects don't get twinned or anything. - expect(song.saved?).must_equal true + _(song.saved?).must_equal true end # save with block. it do - request.song_title = "Tease" + request.song_title = 'Tease' request.id = 1 - request.captcha = "Awesome!" + request.captcha = 'Awesome!' nested_hash = nil request.save do |hash| nested_hash = hash end - expect(nested_hash).must_equal({"title"=>"Tease", "id"=>1, "captcha" => "Awesome!", "album"=>{"getName"=>"Appeal To Reason"}}) + _(nested_hash).must_equal({ 'title' => 'Tease', 'id' => 1, 'captcha' => 'Awesome!', 'album' => { 'getName' => 'Appeal To Reason' } }) # does not write to model. - expect(song.title).must_equal "Extraction" - expect(song.id).must_equal 2 - expect(album.getName).must_equal "Appeal To Reason" + _(song.title).must_equal 'Extraction' + _(song.id).must_equal 2 + _(album.getName).must_equal 'Appeal To Reason' end end diff --git a/test/twin/feature_test.rb b/test/twin/feature_test.rb index 5e76d7c..bbdf35c 100644 --- a/test/twin/feature_test.rb +++ b/test/twin/feature_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class FeatureTest < MiniTest::Spec @@ -7,13 +9,13 @@ class FeatureTest < MiniTest::Spec module Date def date - "May 16" + 'May 16' end end module Instrument def instrument - "Violins" + 'Violins' end end @@ -35,23 +37,23 @@ class AlbumForm < Disposable::Twin end end - let (:song) { Song.new("Broken") } - let (:song_with_composer) { Song.new("Resist Stance", nil, composer) } - let (:composer) { Artist.new("Greg Graffin") } - let (:artist) { Artist.new("Bad Religion") } - let (:album) { Album.new("The Dissent Of Man", [song, song_with_composer], artist) } + let(:song) { Song.new('Broken') } + let(:song_with_composer) { Song.new('Resist Stance', nil, composer) } + let(:composer) { Artist.new('Greg Graffin') } + let(:artist) { Artist.new('Bad Religion') } + let(:album) { Album.new('The Dissent Of Man', [song, song_with_composer], artist) } - let (:form) { AlbumForm.new(album) } + let(:form) { AlbumForm.new(album) } it do - expect(form.date).must_equal "May 16" - expect(form.artist.date).must_equal "May 16" - expect(form.songs[0].date).must_equal "May 16" - expect(form.songs[1].date).must_equal "May 16" - expect(form.songs[1].composer.date).must_equal "May 16" - expect(form.songs[1]).wont_be_kind_of(Instrument) - expect(form.songs[1].composer).must_be_kind_of(Instrument) - expect(form.songs[1].composer.instrument).must_equal "Violins" - expect(form.artist.date).must_equal "May 16" + _(form.date).must_equal 'May 16' + _(form.artist.date).must_equal 'May 16' + _(form.songs[0].date).must_equal 'May 16' + _(form.songs[1].date).must_equal 'May 16' + _(form.songs[1].composer.date).must_equal 'May 16' + _(form.songs[1]).wont_be_kind_of(Instrument) + _(form.songs[1].composer).must_be_kind_of(Instrument) + _(form.songs[1].composer.instrument).must_equal 'Violins' + _(form.artist.date).must_equal 'May 16' end end diff --git a/test/twin/from_collection_test.rb b/test/twin/from_collection_test.rb index 4d3a3dd..b385f75 100644 --- a/test/twin/from_collection_test.rb +++ b/test/twin/from_collection_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class TwinFromCollectionDecoratorTest < MiniTest::Spec @@ -12,18 +14,18 @@ class Artist < Disposable::Twin end end - let (:artist1) { Model::Artist.new(1, "AFI") } - let (:artist2) { Model::Artist.new(2, "Gary Moore") } - let (:collection) { [artist1, artist2] } + let(:artist1) { Model::Artist.new(1, 'AFI') } + let(:artist2) { Model::Artist.new(2, 'Gary Moore') } + let(:collection) { [artist1, artist2] } - describe "from a collection" do + describe 'from a collection' do it do twined_collection = Twin::Artist.from_collection(collection) - expect(twined_collection[0]).must_be_instance_of Twin::Artist - expect(twined_collection[0].model).must_equal artist1 - expect(twined_collection[1]).must_be_instance_of Twin::Artist - expect(twined_collection[1].model).must_equal artist2 + _(twined_collection[0]).must_be_instance_of Twin::Artist + _(twined_collection[0].model).must_equal artist1 + _(twined_collection[1]).must_be_instance_of Twin::Artist + _(twined_collection[1].model).must_equal artist2 end end end diff --git a/test/twin/from_test.rb b/test/twin/from_test.rb index 550ca9d..4701e7d 100644 --- a/test/twin/from_test.rb +++ b/test/twin/from_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class FromTest < MiniTest::Spec @@ -6,7 +8,6 @@ module Model Artist = Struct.new(:realname) end - module Twin class Album < Disposable::Twin feature Sync @@ -21,17 +22,14 @@ class Album < Disposable::Twin end end - - let (:composer) { Model::Artist.new("AFI").extend(Disposable::Saveable) } - let (:album) { Model::Album.new("Black Sails In The Sunset", composer).extend(Disposable::Saveable) } - let (:twin) { Twin::Album.new(album) } + let(:composer) { Model::Artist.new('AFI').extend(Disposable::Saveable) } + let(:album) { Model::Album.new('Black Sails In The Sunset', composer).extend(Disposable::Saveable) } + let(:twin) { Twin::Album.new(album) } it do - expect(twin.full_name).must_equal "Black Sails In The Sunset" - expect(twin.artist.name).must_equal "AFI" + _(twin.full_name).must_equal 'Black Sails In The Sunset' + _(twin.artist.name).must_equal 'AFI' twin.save - - end end diff --git a/test/twin/hash_test.rb b/test/twin/hash_test.rb index 865acc6..8c67760 100644 --- a/test/twin/hash_test.rb +++ b/test/twin/hash_test.rb @@ -1,5 +1,7 @@ -require "test_helper" -require "disposable/twin/property/hash" +# frozen_string_literal: true + +require 'test_helper' +require 'disposable/twin/property/hash' class HashTest < MiniTest::Spec Model = Struct.new(:id, :content) @@ -27,86 +29,85 @@ class Song < Disposable::Twin # puts Song.definitions.get(:content)[:nested].definitions.get(:band).inspect - it "allows reading from existing hash" do + it 'allows reading from existing hash' do model = Model.new(1, {}) - expect(model.inspect).must_equal "#" + _(model.inspect).must_equal '#' song = Song.new(model) - expect(song.id).must_equal 1 - expect(song.content.title).must_be_nil - expect(song.content.band.name).must_be_nil - expect(song.content.band.label.location).must_be_nil - expect(song.content.releases).must_equal [] + _(song.id).must_equal 1 + _(song.content.title).must_be_nil + _(song.content.band.name).must_be_nil + _(song.content.band.label.location).must_be_nil + _(song.content.releases).must_equal [] # model's hash hasn't changed. - expect(model.inspect).must_equal "#" + _(model.inspect).must_equal '#' end - it "defaults to hash when value is nil" do + it 'defaults to hash when value is nil' do model = Model.new(1) - expect(model.inspect).must_equal "#" + _(model.inspect).must_equal '#' song = Song.new(model) - expect(song.id).must_equal 1 - expect(song.content.title).must_be_nil - expect(song.content.band.name).must_be_nil - expect(song.content.band.label.location).must_be_nil + _(song.id).must_equal 1 + _(song.content.title).must_be_nil + _(song.content.band.name).must_be_nil + _(song.content.band.label.location).must_be_nil # model's hash hasn't changed. - expect(model.inspect).must_equal "#" + _(model.inspect).must_equal '#' end - it "#sync writes to model" do + it '#sync writes to model' do model = Model.new song = Song.new(model) - song.content.band.label.location = "San Francisco" + song.content.band.label.location = 'San Francisco' song.sync - expect(model.inspect).must_equal "#{\"label\"=>{\"location\"=>\"San Francisco\"}}, \"releases\"=>[]}>" + _(model.inspect).must_equal '#{"label"=>{"location"=>"San Francisco"}}, "releases"=>[]}>' end - it "#appends to collections" do + it '#appends to collections' do model = Model.new song = Song.new(model) # song.content.releases.append(version: 1) # FIXME: yes, this happens! - song.content.releases.append("version" => 1) + song.content.releases.append('version' => 1) song.sync - expect(model.inspect).must_equal "#{\"label\"=>{}}, \"releases\"=>[{\"version\"=>1}]}>" + _(model.inspect).must_equal '#{"label"=>{}}, "releases"=>[{"version"=>1}]}>' end it "doesn't erase existing, undeclared content" do - model = Model.new(nil, {"artist"=>{}}) + model = Model.new(nil, { 'artist' => {} }) song = Song.new(model) - song.content.band.label.location = "San Francisco" + song.content.band.label.location = 'San Francisco' # puts song.content.class.ancestors song.sync - expect(model.inspect).must_equal "#{}, \"band\"=>{\"label\"=>{\"location\"=>\"San Francisco\"}}, \"releases\"=>[]}>" + _(model.inspect).must_equal '#{}, "band"=>{"label"=>{"location"=>"San Francisco"}}, "releases"=>[]}>' end it "doesn't erase existing, undeclared content in existing content" do - model = Model.new(nil, {"band"=>{ "label" => { "owner" => "Brett Gurewitz" }, "genre" => "Punkrock" }}) + model = Model.new(nil, { 'band' => { 'label' => { 'owner' => 'Brett Gurewitz' }, 'genre' => 'Punkrock' } }) song = Song.new(model) - song.content.band.label.location = "San Francisco" + song.content.band.label.location = 'San Francisco' song.sync - expect(model.inspect).must_equal "#{\"label\"=>{\"owner\"=>\"Brett Gurewitz\", \"location\"=>\"San Francisco\"}, \"genre\"=>\"Punkrock\"}, \"releases\"=>[]}>" + _(model.inspect).must_equal '#{"label"=>{"owner"=>"Brett Gurewitz", "location"=>"San Francisco"}, "genre"=>"Punkrock"}, "releases"=>[]}>' end - - describe "features propagation" do + describe 'features propagation' do module UUID def uuid - "1224" + '1224' end end @@ -123,21 +124,21 @@ class Hit < Disposable::Twin end end - it "includes features into all nested twins" do + it 'includes features into all nested twins' do song = Hit.new(Model.new) - expect(song.uuid).must_equal "1224" - expect(song.content.uuid).must_equal "1224" - expect(song.content.band.uuid).must_equal "1224" + _(song.uuid).must_equal '1224' + _(song.content.uuid).must_equal '1224' + _(song.content.band.uuid).must_equal '1224' end end - describe "coercion" do - require "disposable/twin/coercion" + describe 'coercion' do + require 'disposable/twin/coercion' class Coercing < Disposable::Twin include Property::Hash feature Coercion - property :id, type: const_get("Types::Coercible::#{DRY_TYPES_INT_CONSTANT}") + property :id, type: Types::Params::Integer property :content, field: :hash do property :title property :band do @@ -146,16 +147,16 @@ class Coercing < Disposable::Twin end end - it "coerces" do + it 'coerces' do song = Coercing.new(Model.new(1)) - song.id = "9" - expect(song.id).must_equal 9 + song.id = '9' + _(song.id).must_equal 9 song.content.band.name = 18 - expect(song.content.band.name).must_equal "18" + _(song.content.band.name).must_equal '18' end end - describe "::unnest" do + describe '::unnest' do class Unnesting < Disposable::Twin feature Sync include Property::Hash @@ -185,23 +186,23 @@ class Unnesting < Disposable::Twin # end end - it "exposes reader and writer" do - model = Model.new(1, {title: "Bedroom Eyes"}) + it 'exposes reader and writer' do + model = Model.new(1, { title: 'Bedroom Eyes' }) song = Unnesting.new(model) # singular scalar accessors - expect(song.content.title).must_equal "Bedroom Eyes" - expect(song.title).must_equal "Bedroom Eyes" + _(song.content.title).must_equal 'Bedroom Eyes' + _(song.title).must_equal 'Bedroom Eyes' - song.title = "Notorious" - expect(song.title).must_equal "Notorious" - expect(song.content.title).must_equal "Notorious" + song.title = 'Notorious' + _(song.title).must_equal 'Notorious' + _(song.content.title).must_equal 'Notorious' # singular nested accessors - expect(song.band.name).must_be_nil - expect(song.content.band.name).must_be_nil - song.band.name = "Duran Duran" - expect(song.band.name).must_equal "Duran Duran" + _(song.band.name).must_be_nil + _(song.content.band.name).must_be_nil + song.band.name = 'Duran Duran' + _(song.band.name).must_equal 'Duran Duran' end end @@ -228,31 +229,31 @@ class Album < Disposable::Twin end end - it "exposes reader and writer" do + it 'exposes reader and writer' do model = AlbumModel.new(1, [ - { title: "Sherry", band: { name: 'The Four Seasons', label: { location: 'US' } }, featured_artists: [{ name: 'Frankie Valli' }, { name: 'The Variatones' }] }, - { title: "Walk Like a Man", band: { name: 'The Four Seasons', label: { location: 'US' } }, featured_artists: [{ name: 'Frankie Valli' }] } - ]) + { title: 'Sherry', band: { name: 'The Four Seasons', label: { location: 'US' } }, featured_artists: [{ name: 'Frankie Valli' }, { name: 'The Variatones' }] }, + { title: 'Walk Like a Man', band: { name: 'The Four Seasons', label: { location: 'US' } }, featured_artists: [{ name: 'Frankie Valli' }] } + ]) contract = Album.new(model) song1 = contract.songs[0] - expect(song1.title).must_equal "Sherry" - expect(song1.band.name).must_equal 'The Four Seasons' - expect(song1.band.label.location).must_equal 'US' - expect(song1.featured_artists[0].name).must_equal 'Frankie Valli' - expect(song1.featured_artists[1].name).must_equal 'The Variatones' + _(song1.title).must_equal 'Sherry' + _(song1.band.name).must_equal 'The Four Seasons' + _(song1.band.label.location).must_equal 'US' + _(song1.featured_artists[0].name).must_equal 'Frankie Valli' + _(song1.featured_artists[1].name).must_equal 'The Variatones' song2 = contract.songs[1] - expect(song2.title).must_equal "Walk Like a Man" - expect(song2.band.name).must_equal 'The Four Seasons' - expect(song2.band.label.location).must_equal 'US' - expect(song2.featured_artists[0].name).must_equal 'Frankie Valli' + _(song2.title).must_equal 'Walk Like a Man' + _(song2.band.name).must_equal 'The Four Seasons' + _(song2.band.label.location).must_equal 'US' + _(song2.featured_artists[0].name).must_equal 'Frankie Valli' end end end -# fixme: make sure default hash is different for every invocation, and not created at compile time. +# FIXME: make sure default hash is different for every invocation, and not created at compile time. # TODO: test that config is same and nested. diff --git a/test/twin/inherit_test.rb b/test/twin/inherit_test.rb index 0788acd..222bd78 100644 --- a/test/twin/inherit_test.rb +++ b/test/twin/inherit_test.rb @@ -1,4 +1,6 @@ -require "test_helper" +# frozen_string_literal: true + +require 'test_helper' class InheritTest < MiniTest::Spec module Model @@ -33,29 +35,27 @@ class Compilation < Album property :name, writeable: false, inherit: true property :artist, inherit: true do - end end end # definitions are not shared. it do - expect(Twin::Album.definitions.get(:name).extend(Declarative::Inspect).inspect).must_equal "#:_name, :private_name=>:name, :name=>\"name\"}>" - expect(Twin::Compilation.definitions.get(:name).extend(Declarative::Inspect).inspect).must_equal "#:_name, :private_name=>:name, :name=>\"name\", :writeable=>false}>" # FIXME: where did :inherit go? + _(Twin::Album.definitions.get(:name).extend(Declarative::Inspect).inspect).must_equal '#:_name, :private_name=>:name, :name=>"name"}>' + _(Twin::Compilation.definitions.get(:name).extend(Declarative::Inspect).inspect).must_equal '#:_name, :private_name=>:name, :name=>"name", :writeable=>false}>' # FIXME: where did :inherit go? end + let(:album) { Model::Album.new('In The Meantime And Inbetween Time', [], Model::Artist.new) } - let (:album) { Model::Album.new("In The Meantime And Inbetween Time", [], Model::Artist.new) } - - it { expect(Twin::Album.new(album).artist.artist_id).must_equal 1 } + it { _(Twin::Album.new(album).artist.artist_id).must_equal 1 } # inherit inline twins when not overriding. - it { expect(Twin::EmptyCompilation.new(album).artist.artist_id).must_equal 1 } + it { _(Twin::EmptyCompilation.new(album).artist.artist_id).must_equal 1 } # inherit inline twins when overriding. - it { expect(Twin::Compilation.new(album).artist.artist_id).must_equal 1 } + it { _(Twin::Compilation.new(album).artist.artist_id).must_equal 1 } - describe "custom accessors get inherited" do + describe 'custom accessors get inherited' do class Singer < Disposable::Twin property :name @@ -71,15 +71,15 @@ def name=(val) class Star < Singer end - let (:model) { Model::Artist.new("Helloween") } + let(:model) { Model::Artist.new('Helloween') } it do artist = Star.new(model) - expect(artist.name).must_equal("neewolleh") + _(artist.name).must_equal('neewolleh') - artist.name = "HELLOWEEN" + artist.name = 'HELLOWEEN' # artist.with_custom_setter = "this gets ignored" - expect(artist.name).must_equal("neewolleh") + _(artist.name).must_equal('neewolleh') end end end diff --git a/test/twin/inheritance_test.rb b/test/twin/inheritance_test.rb index 24186fe..777621b 100644 --- a/test/twin/inheritance_test.rb +++ b/test/twin/inheritance_test.rb @@ -1,7 +1,9 @@ -require "test_helper" +# frozen_string_literal: true + +require 'test_helper' class InheritanceTest < Minitest::Spec - let (:song) { OpenStruct.new(id: 0) } + let(:song) { OpenStruct.new(id: 0) } module Id def id @@ -9,7 +11,7 @@ def id end def id=(v) - super(v+1) + super(v + 1) end end @@ -20,7 +22,7 @@ class Twin < Disposable::Twin it do twin = Twin.new(song) - expect(twin.id).must_equal 0 + _(twin.id).must_equal 0 end class TwinComposition < Disposable::Twin @@ -32,12 +34,11 @@ class TwinComposition < Disposable::Twin it do twin = TwinComposition.new(song: song) - expect(twin.id).must_equal 0 - twin.id= 3 - expect(twin.id).must_equal 3 + _(twin.id).must_equal 0 + twin.id = 3 + _(twin.id).must_equal 3 end - class TwinCompositionDefineMethod < Disposable::Twin include Composition @@ -50,12 +51,11 @@ class TwinCompositionDefineMethod < Disposable::Twin it do twin = TwinCompositionDefineMethod.new(song: song) - expect(twin.id).must_equal 9 + _(twin.id).must_equal 9 end - - describe ":from" do - let (:song) { Struct.new(:ident).new(1) } + describe ':from' do + let(:song) { Struct.new(:ident).new(1) } class TwinWithFrom < Disposable::Twin include Expose @@ -66,8 +66,8 @@ class InheritingFrom < TwinWithFrom end it do - expect(TwinWithFrom.new(song).id).must_equal 1 - expect(InheritingFrom.new(song).id).must_equal 1 + _(TwinWithFrom.new(song).id).must_equal 1 + _(InheritingFrom.new(song).id).must_equal 1 end end end diff --git a/test/twin/option_test.rb b/test/twin/option_test.rb index e033166..12f42be 100644 --- a/test/twin/option_test.rb +++ b/test/twin/option_test.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # require "test_helper" # class TwinOptionTest < Minitest::Spec @@ -20,7 +21,6 @@ # let (:song) { Model::Song.new(1, "Broken") } # let (:twin) { Song.new(song, :preview? => false) } - # # properties are read from model. # it { twin.id.must_equal 1 } # it { twin.title.must_equal "Broken" } diff --git a/test/twin/parent_test.rb b/test/twin/parent_test.rb index 66f5cba..3c90db7 100644 --- a/test/twin/parent_test.rb +++ b/test/twin/parent_test.rb @@ -1,11 +1,13 @@ -require "test_helper" -require "disposable/twin/parent.rb" +# frozen_string_literal: true + +require 'test_helper' +require 'disposable/twin/parent.rb' class TwinParentTest < MiniTest::Spec module Model Album = Struct.new(:id, :artist, :songs) Artist = Struct.new(:name) - Song = Struct.new(:title, :composer) + Song = Struct.new(:title, :composer) end class Album < Disposable::Twin @@ -25,17 +27,17 @@ class Album < Disposable::Twin end end - let (:album) { Album.new(Model::Album.new(1, Model::Artist.new("Helloween"), [Model::Song.new("I'm Alive", Model::Artist.new("Kai Hansen"))])) } + let(:album) { Album.new(Model::Album.new(1, Model::Artist.new('Helloween'), [Model::Song.new("I'm Alive", Model::Artist.new('Kai Hansen'))])) } - it { expect(album.parent).must_be_nil } - it { expect(album.artist.parent).must_equal album } - it { expect(album.songs[0].parent).must_equal album } - it { expect(album.songs[0].composer.parent).must_equal album.songs[0] } + it { _(album.parent).must_be_nil } + it { _(album.artist.parent).must_equal album } + it { _(album.songs[0].parent).must_equal album } + it { _(album.songs[0].composer.parent).must_equal album.songs[0] } - describe "Collection#append" do + describe 'Collection#append' do it do album.songs.append(Model::Song.new) - expect(album.songs[1].parent).must_equal album + _(album.songs[1].parent).must_equal album end end end diff --git a/test/twin/process_inline_test.rb b/test/twin/process_inline_test.rb index f9c01fd..bae0b37 100644 --- a/test/twin/process_inline_test.rb +++ b/test/twin/process_inline_test.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # require "test_helper" # class ProcessInlineTest < MiniTest::Spec @@ -32,4 +33,4 @@ # assert (twin.artist.class < InlineTwin) # assert ! (twin.composer.class < InlineTwin) # end -# end \ No newline at end of file +# end diff --git a/test/twin/property_processor_test.rb b/test/twin/property_processor_test.rb index 98f93fb..39cb2c7 100644 --- a/test/twin/property_processor_test.rb +++ b/test/twin/property_processor_test.rb @@ -1,9 +1,11 @@ -require "test_helper" +# frozen_string_literal: true + +require 'test_helper' class PropertyProcessorTest < Minitest::Spec - Album = Struct.new(:title, :artist, :songs) - Artist = Struct.new(:name) - Song = Struct.new(:id) + Album = Struct.new(:title, :artist, :songs) + Artist = Struct.new(:name) + Song = Struct.new(:id) class AlbumTwin < Disposable::Twin property :title @@ -13,33 +15,33 @@ class AlbumTwin < Disposable::Twin end collection :songs do - property :id + property :id end end - describe "collection" do - let(:twin) { AlbumTwin.new(Album.new("Live!", Artist.new, [Song.new(1), Song.new(2)])) } - it "yields twin, index" do - called = [] - Disposable::Twin::PropertyProcessor.new(twin.class.definitions.get(:songs), twin).() { |v, i| called << [v.model, i] } + describe 'collection' do + let(:twin) { AlbumTwin.new(Album.new('Live!', Artist.new, [Song.new(1), Song.new(2)])) } + it 'yields twin, index' do + called = [] + Disposable::Twin::PropertyProcessor.new(twin.class.definitions.get(:songs), twin).call { |v, i| called << [v.model, i] } - expect(called.inspect).must_equal %{[[#, 0], [#, 1]]} - end + _(called.inspect).must_equal %([[#, 0], [#, 1]]) + end - it "yields twin" do - called = [] - Disposable::Twin::PropertyProcessor.new(twin.class.definitions.get(:songs), twin).() { |v| called << [v.model] } + it 'yields twin' do + called = [] + Disposable::Twin::PropertyProcessor.new(twin.class.definitions.get(:songs), twin).call { |v| called << [v.model] } - expect(called.inspect).must_equal %{[[#], [#]]} - end + _(called.inspect).must_equal %([[#], [#]]) + end - it "allows nil collection" do - twin = AlbumTwin.new(Album.new("Live!", Artist.new, nil)) + it 'allows nil collection' do + twin = AlbumTwin.new(Album.new('Live!', Artist.new, nil)) - called = [] - Disposable::Twin::PropertyProcessor.new(twin.class.definitions.get(:songs), twin).() { |v, i| called << [v.model, i] } + called = [] + Disposable::Twin::PropertyProcessor.new(twin.class.definitions.get(:songs), twin).call { |v, i| called << [v.model, i] } - expect(called.inspect).must_equal %{[]} - end + _(called.inspect).must_equal %([]) + end end end diff --git a/test/twin/readable_test.rb b/test/twin/readable_test.rb index 54acde8..aedfd54 100644 --- a/test/twin/readable_test.rb +++ b/test/twin/readable_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class ReadableTest < MiniTest::Spec @@ -25,26 +27,26 @@ class PasswordForm < Disposable::Twin end end - let (:cred) { Credentials.new("secret", CreditCard.new("Jonny", "0987654321")) } + let(:cred) { Credentials.new('secret', CreditCard.new('Jonny', '0987654321')) } - let (:twin) { PasswordForm.new(cred) } + let(:twin) { PasswordForm.new(cred) } it { - expect(twin.password).must_be_nil # not readable. - expect(twin.credit_card.name).must_equal "Jonny" - expect(twin.credit_card.number).must_be_nil # not readable. + _(twin.password).must_be_nil # not readable. + _(twin.credit_card.name).must_equal 'Jonny' + _(twin.credit_card.number).must_be_nil # not readable. # manual setting on the twin works. - twin.password = "123" - expect(twin.password).must_equal "123" + twin.password = '123' + _(twin.password).must_equal '123' - twin.credit_card.number = "456" - expect(twin.credit_card.number).must_equal "456" + twin.credit_card.number = '456' + _(twin.credit_card.number).must_equal '456' twin.sync # it writes, but does not read. - expect(cred.inspect).must_equal '#>' + _(cred.inspect).must_equal '#>' # test sync{}. hash = {} @@ -52,12 +54,12 @@ class PasswordForm < Disposable::Twin hash = nested end - expect(hash).must_equal("password"=> "123", "credit_card"=>{"name"=>"Jonny", "number"=>"456"}) + _(hash).must_equal('password' => '123', 'credit_card' => { 'name' => 'Jonny', 'number' => '456' }) } # allow passing non-readable value as option. it do - twin = PasswordForm.new(cred, password: "open sesame!") - expect(twin.password).must_equal "open sesame!" + twin = PasswordForm.new(cred, password: 'open sesame!') + _(twin.password).must_equal 'open sesame!' end end diff --git a/test/twin/save_test.rb b/test/twin/save_test.rb index 6b4b1d0..768c666 100644 --- a/test/twin/save_test.rb +++ b/test/twin/save_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class SaveTest < MiniTest::Spec @@ -7,7 +9,6 @@ module Model Artist = Struct.new(:name) end - module Twin class Album < Disposable::Twin feature Setup @@ -30,16 +31,14 @@ class Album < Disposable::Twin end end + let(:song) { Model::Song.new.extend(Disposable::Saveable) } + let(:composer) { Model::Artist.new(nil).extend(Disposable::Saveable) } + let(:song_with_composer) { Model::Song.new(nil, composer).extend(Disposable::Saveable) } + let(:artist) { Model::Artist.new(nil).extend(Disposable::Saveable) } - let (:song) { Model::Song.new().extend(Disposable::Saveable) } - let (:composer) { Model::Artist.new(nil).extend(Disposable::Saveable) } - let (:song_with_composer) { Model::Song.new(nil, composer).extend(Disposable::Saveable) } - let (:artist) { Model::Artist.new(nil).extend(Disposable::Saveable) } - - - let (:album) { Model::Album.new(nil, [song, song_with_composer], artist).extend(Disposable::Saveable) } + let(:album) { Model::Album.new(nil, [song, song_with_composer], artist).extend(Disposable::Saveable) } - let (:twin) { Twin::Album.new(album) } + let(:twin) { Twin::Album.new(album) } # with populated model. it do @@ -48,29 +47,33 @@ class Album < Disposable::Twin twin.save # sync happened. - expect(album.name).must_equal "Live And Dangerous" - expect(album.songs[0]).must_be_instance_of Model::Song - expect(album.songs[1]).must_be_instance_of Model::Song - expect(album.songs[0].title).must_equal "Southbound" - expect(album.songs[1].title).must_equal "The Boys Are Back In Town" - expect(album.songs[1].composer).must_be_instance_of Model::Artist - expect(album.songs[1].composer.name).must_equal "Lynott" - expect(album.artist).must_be_instance_of Model::Artist - expect(album.artist.name).must_equal "Thin Lizzy" + _(album.name).must_equal 'Live And Dangerous' + _(album.songs[0]).must_be_instance_of Model::Song + _(album.songs[1]).must_be_instance_of Model::Song + _(album.songs[0].title).must_equal 'Southbound' + _(album.songs[1].title).must_equal 'The Boys Are Back In Town' + _(album.songs[1].composer).must_be_instance_of Model::Artist + _(album.songs[1].composer.name).must_equal 'Lynott' + _(album.artist).must_be_instance_of Model::Artist + _(album.artist.name).must_equal 'Thin Lizzy' # saved? - expect(album.saved?).must_equal true - expect(album.songs[0].saved?).must_equal true - expect(album.songs[1].saved?).must_equal true - expect(album.songs[1].composer.saved?).must_equal true - expect(album.artist.saved?).must_equal true + _(album.saved?).must_equal true + _(album.songs[0].saved?).must_equal true + _(album.songs[1].saved?).must_equal true + _(album.songs[1].composer.saved?).must_equal true + _(album.artist.saved?).must_equal true end - #save returns result. - it { expect(twin.save).must_equal true } + # save returns result. + it { _(twin.save).must_equal true } it do - album.instance_eval { def save; false; end } - expect(twin.save).must_equal false + album.instance_eval do + def save + false + end + end + _(twin.save).must_equal false end # with save{}. @@ -85,25 +88,24 @@ class Album < Disposable::Twin nested_hash = hash end - expect(nested_hash).must_equal({"name"=>"Live And Dangerous", "songs"=>[{"title"=>"Southbound", "composer"=>nil}, {"title"=>"The Boys Are Back In Town", "composer"=>{"name"=>"Lynott"}}], "artist"=>{"name"=>"Thin Lizzy"}}) + _(nested_hash).must_equal({ 'name' => 'Live And Dangerous', 'songs' => [{ 'title' => 'Southbound', 'composer' => nil }, { 'title' => 'The Boys Are Back In Town', 'composer' => { 'name' => 'Lynott' } }], 'artist' => { 'name' => 'Thin Lizzy' } }) # nothing written to model. - expect(album.name).must_be_nil - expect(album.songs[0].title).must_be_nil - expect(album.songs[1].title).must_be_nil - expect(album.songs[1].composer.name).must_be_nil - expect(album.artist.name).must_be_nil + _(album.name).must_be_nil + _(album.songs[0].title).must_be_nil + _(album.songs[1].title).must_be_nil + _(album.songs[1].composer.name).must_be_nil + _(album.artist.name).must_be_nil # nothing saved. # saved? - expect(album.saved?).must_be_nil - expect(album.songs[0].saved?).must_be_nil - expect(album.songs[1].saved?).must_be_nil - expect(album.songs[1].composer.saved?).must_be_nil - expect(album.artist.saved?).must_be_nil + _(album.saved?).must_be_nil + _(album.songs[0].saved?).must_be_nil + _(album.songs[1].saved?).must_be_nil + _(album.songs[1].composer.saved?).must_be_nil + _(album.artist.saved?).must_be_nil end - # save: false module Twin class AlbumWithSaveFalse < Disposable::Twin @@ -136,34 +138,33 @@ class AlbumWithSaveFalse < Disposable::Twin twin.save # sync happened. - expect(album.name).must_equal "Live And Dangerous" - expect(album.songs[0]).must_be_instance_of Model::Song - expect(album.songs[1]).must_be_instance_of Model::Song - expect(album.songs[0].title).must_equal "Southbound" - expect(album.songs[1].title).must_equal "The Boys Are Back In Town" - expect(album.songs[1].composer).must_be_instance_of Model::Artist - expect(album.songs[1].composer.name).must_equal "Lynott" - expect(album.artist).must_be_instance_of Model::Artist - expect(album.artist.name).must_equal "Thin Lizzy" + _(album.name).must_equal 'Live And Dangerous' + _(album.songs[0]).must_be_instance_of Model::Song + _(album.songs[1]).must_be_instance_of Model::Song + _(album.songs[0].title).must_equal 'Southbound' + _(album.songs[1].title).must_equal 'The Boys Are Back In Town' + _(album.songs[1].composer).must_be_instance_of Model::Artist + _(album.songs[1].composer.name).must_equal 'Lynott' + _(album.artist).must_be_instance_of Model::Artist + _(album.artist.name).must_equal 'Thin Lizzy' # saved? - expect(album.saved?).must_equal true - expect(album.songs[0].saved?).must_be_nil - expect(album.songs[1].saved?).must_be_nil - expect(album.songs[1].composer.saved?).must_be_nil # doesn't get saved. - expect(album.artist.saved?).must_equal true + _(album.saved?).must_equal true + _(album.songs[0].saved?).must_be_nil + _(album.songs[1].saved?).must_be_nil + _(album.songs[1].composer.saved?).must_be_nil # doesn't get saved. + _(album.artist.saved?).must_equal true end def fill_out!(twin) - twin.name = "Live And Dangerous" - twin.songs[0].title = "Southbound" - twin.songs[1].title = "The Boys Are Back In Town" - twin.songs[1].composer.name = "Lynott" - twin.artist.name = "Thin Lizzy" + twin.name = 'Live And Dangerous' + twin.songs[0].title = 'Southbound' + twin.songs[1].title = 'The Boys Are Back In Town' + twin.songs[1].composer.name = 'Lynott' + twin.artist.name = 'Thin Lizzy' end end - # TODO: with block # class SaveWithDynamicOptionsTest < MiniTest::Spec @@ -185,8 +186,8 @@ def fill_out!(twin) # length_seconds = 120 # form.save(length: lambda { |value, options| form.model.id = "#{value}: #{length_seconds}" }) -# song.title).must_equal "A Poor Man's Memory" -# song.length).must_be_nil -# song.id).must_equal "10: 120" +# song.title.must_equal "A Poor Man's Memory" +# song.length.must_be_nil +# song.id.must_equal "10: 120" # end # end diff --git a/test/twin/setup_test.rb b/test/twin/setup_test.rb index 240c595..aad18d5 100644 --- a/test/twin/setup_test.rb +++ b/test/twin/setup_test.rb @@ -1,4 +1,6 @@ -require "test_helper" +# frozen_string_literal: true + +require 'test_helper' class TwinSetupTest < MiniTest::Spec module Model @@ -7,7 +9,6 @@ module Model Artist = Struct.new(:id) end - module Twin class Artist < Disposable::Twin property :id @@ -32,39 +33,38 @@ class Album < Disposable::Twin end end + let(:song) { Model::Song.new(1, 'Broken', nil) } + let(:composer) { Model::Artist.new(2) } + let(:song_with_composer) { Model::Song.new(1, 'Broken', nil, composer) } + let(:artist) { Model::Artist.new(9) } - let (:song) { Model::Song.new(1, "Broken", nil) } - let (:composer) { Model::Artist.new(2) } - let (:song_with_composer) { Model::Song.new(1, "Broken", nil, composer) } - let (:artist) { Model::Artist.new(9) } - - describe "with songs: [song, song{composer}]" do - let (:album) { Model::Album.new(1, "The Rest Is Silence", [song, song_with_composer], artist) } + describe 'with songs: [song, song{composer}]' do + let(:album) { Model::Album.new(1, 'The Rest Is Silence', [song, song_with_composer], artist) } it do twin = Twin::Album.new(album) - expect(twin.songs.size).must_equal 2 - expect(twin.songs).must_be_instance_of Disposable::Twin::Collection + _(twin.songs.size).must_equal 2 + _(twin.songs).must_be_instance_of Disposable::Twin::Collection - expect(twin.songs[0]).must_be_instance_of Twin::Song - expect(twin.songs[0].id).must_equal 1 + _(twin.songs[0]).must_be_instance_of Twin::Song + _(twin.songs[0].id).must_equal 1 - expect(twin.songs[1]).must_be_instance_of Twin::Song - expect(twin.songs[1].id).must_equal 1 - expect(twin.songs[1].composer).must_be_instance_of Twin::Artist - expect(twin.songs[1].composer.id).must_equal 2 + _(twin.songs[1]).must_be_instance_of Twin::Song + _(twin.songs[1].id).must_equal 1 + _(twin.songs[1].composer).must_be_instance_of Twin::Artist + _(twin.songs[1].composer.id).must_equal 2 end end - describe "with songs: [] and artist: nil" do - let (:album) { Model::Album.new(1, "The Rest Is Silence", [], nil) } + describe 'with songs: [] and artist: nil' do + let(:album) { Model::Album.new(1, 'The Rest Is Silence', [], nil) } it do twin = Twin::Album.new(album) - expect(twin.songs.size).must_equal 0 - expect(twin.songs).must_be_instance_of Disposable::Twin::Collection + _(twin.songs.size).must_equal 0 + _(twin.songs).must_be_instance_of Disposable::Twin::Collection end end @@ -75,7 +75,7 @@ class Album < Disposable::Twin # it do # twin = Twin::Album.new(album) - # twin.songs.size).must_equal 0 + # twin.songs.size.must_equal 0 # twin.songs.must_be_instance_of Disposable::Twin::Collection # end # end @@ -108,33 +108,33 @@ class AlbumForm < Disposable::Twin end end - let (:song) { Model::Song.new(1) } - let (:composer) { Model::Artist.new(2) } - let (:song_with_composer) { Model::Song.new(3, composer) } - let (:artist) { Model::Artist.new(9) } - let (:album) { Model::Album.new(0, "Toto Live", [song, song_with_composer], artist) } + let(:song) { Model::Song.new(1) } + let(:composer) { Model::Artist.new(2) } + let(:song_with_composer) { Model::Song.new(3, composer) } + let(:artist) { Model::Artist.new(9) } + let(:album) { Model::Album.new(0, 'Toto Live', [song, song_with_composer], artist) } it do twin = AlbumForm.new(album) # pp twin - expect(twin.id).must_equal 0 - expect(twin.name).must_equal "Toto Live" + _(twin.id).must_equal 0 + _(twin.name).must_equal 'Toto Live' - expect(twin.artist).must_be_kind_of Disposable::Twin - expect(twin.artist.id).must_equal 9 + _(twin.artist).must_be_kind_of Disposable::Twin + _(twin.artist.id).must_equal 9 - expect(twin.songs).must_be_instance_of Disposable::Twin::Collection + _(twin.songs).must_be_instance_of Disposable::Twin::Collection # nil nested objects work (no composer) - expect(twin.songs[0]).must_be_kind_of Disposable::Twin - expect(twin.songs[0].id).must_equal 1 + _(twin.songs[0]).must_be_kind_of Disposable::Twin + _(twin.songs[0].id).must_equal 1 - expect(twin.songs[1]).must_be_kind_of Disposable::Twin - expect(twin.songs[1].id).must_equal 3 + _(twin.songs[1]).must_be_kind_of Disposable::Twin + _(twin.songs[1].id).must_equal 3 - expect(twin.songs[1].composer).must_be_kind_of Disposable::Twin - expect(twin.songs[1].composer.id).must_equal 2 + _(twin.songs[1].composer).must_be_kind_of Disposable::Twin + _(twin.songs[1].composer.id).must_equal 2 end end @@ -149,7 +149,7 @@ class AlbumTwin < Disposable::Twin it do twin = AlbumTwin.new(Song.new(1), is_online: true) - expect(twin.id).must_equal 1 - expect(twin.is_online).must_equal true + _(twin.id).must_equal 1 + _(twin.is_online).must_equal true end end diff --git a/test/twin/skip_unchanged_test.rb b/test/twin/skip_unchanged_test.rb index c14f947..a416c1e 100644 --- a/test/twin/skip_unchanged_test.rb +++ b/test/twin/skip_unchanged_test.rb @@ -1,4 +1,6 @@ -require "test_helper" +# frozen_string_literal: true + +require 'test_helper' class SkipUnchangedTest < MiniTest::Spec module Model @@ -7,7 +9,6 @@ module Model Artist = Struct.new(:name) end - module Twin class Album < Disposable::Twin feature Setup @@ -30,35 +31,45 @@ class Album < Disposable::Twin end end + let(:song) { Model::Song.new } + let(:composer) { Model::Artist.new(nil) } + let(:song_with_composer) { Model::Song.new('American Jesus', composer) } + let(:artist) { Model::Artist.new('Bad Religion') } - let (:song) { Model::Song.new() } - let (:composer) { Model::Artist.new(nil) } - let (:song_with_composer) { Model::Song.new("American Jesus", composer) } - let (:artist) { Model::Artist.new("Bad Religion") } - - - let (:album) { Model::Album.new("30 Years Live", [song, song_with_composer], artist) } + let(:album) { Model::Album.new('30 Years Live', [song, song_with_composer], artist) } it do twin = Twin::Album.new(album) - twin.songs[1].composer.name = "Greg Graffin" - twin.songs[0].title = "Resist Stance" + twin.songs[1].composer.name = 'Greg Graffin' + twin.songs[0].title = 'Resist Stance' # raises exceptions when setters are called. - album.instance_eval { def name=; raise; end } - artist.instance_eval { def name=; raise; end } - song_with_composer.instance_eval { def title=; raise; end } + album.instance_eval do + def name= + raise + end + end + artist.instance_eval do + def name= + raise + end + end + song_with_composer.instance_eval do + def title= + raise + end + end twin.sync # unchanged, and no exception raised. - expect(album.name).must_equal "30 Years Live" - expect(song_with_composer.title).must_equal "American Jesus" - expect(artist.name).must_equal "Bad Religion" + _(album.name).must_equal '30 Years Live' + _(song_with_composer.title).must_equal 'American Jesus' + _(artist.name).must_equal 'Bad Religion' # this actually got synced. - expect(song_with_composer.composer.name).must_equal "Greg Graffin" # was nil. - expect(song.title).must_equal "Resist Stance" # was nil. + _(song_with_composer.composer.name).must_equal 'Greg Graffin' # was nil. + _(song.title).must_equal 'Resist Stance' # was nil. end end diff --git a/test/twin/struct/coercion_test.rb b/test/twin/struct/coercion_test.rb index 9c436f2..c61691b 100644 --- a/test/twin/struct/coercion_test.rb +++ b/test/twin/struct/coercion_test.rb @@ -1,6 +1,8 @@ -require "test_helper" -require "disposable/twin/coercion" -require "disposable/twin/property/struct" +# frozen_string_literal: true + +require 'test_helper' +require 'disposable/twin/coercion' +require 'disposable/twin/property/struct' class StructCoercionTest < Minitest::Spec ExpenseModel = Struct.new(:content) @@ -10,27 +12,26 @@ class Expense < Disposable::Twin feature Coercion property :content do - property :amount, type: DRY_TYPES_CONSTANT::Float | DRY_TYPES_CONSTANT::Nil + property :amount, type: Types::Params::Float | Types::Params::Nil end unnest :amount, from: :content end - it do - twin = Expense.new( ExpenseModel.new({}) ) + twin = Expense.new(ExpenseModel.new({})) #- direct access, without unnest - expect(twin.content.amount).must_be_nil - twin.content.amount = "1.8" - expect(twin.content.amount).must_equal 1.8 + _(twin.content.amount).must_be_nil + twin.content.amount = '1.8' + _(twin.content.amount).must_equal 1.8 end - it "via unnest" do - twin = Expense.new( ExpenseModel.new({}) ) + it 'via unnest' do + twin = Expense.new(ExpenseModel.new({})) - expect(twin.amount).must_be_nil - twin.amount = "1.8" - expect(twin.amount).must_equal 1.8 + _(twin.amount).must_be_nil + twin.amount = '1.8' + _(twin.amount).must_equal 1.8 end end diff --git a/test/twin/struct_test.rb b/test/twin/struct_test.rb index 5c1fade..6e8588d 100644 --- a/test/twin/struct_test.rb +++ b/test/twin/struct_test.rb @@ -1,43 +1,41 @@ +# frozen_string_literal: true + require 'test_helper' # require "representable/debug" -require 'disposable/twin/struct' +require "disposable/twin/property/struct" class TwinStructTest < MiniTest::Spec class Song < Disposable::Twin include Property::Struct - property :number#, default: 1 # FIXME: this should be :default_if_nil so it becomes clear with a model. + property :number # , default: 1 # FIXME: this should be :default_if_nil so it becomes clear with a model. property :cool? end # empty hash - # it { Song.new({}).number).must_equal 1 } - it { expect(Song.new({}).number).must_be_nil } # TODO: implement default. + # it { Song.new({}).number.must_equal 1 } + it { _(Song.new({}).number).must_be_nil } # TODO: implement default. # model hash - it { expect(Song.new(number: 2).number).must_equal 2 } + it { _(Song.new(number: 2).number).must_equal 2 } # with hash and options as one hash. - it { expect(Song.new(number: 3, cool?: true).cool?).must_equal true } - it { expect(Song.new(number: 3, cool?: true).number).must_equal 3 } + it { _(Song.new(number: 3, cool?: true).cool?).must_equal true } + it { _(Song.new(number: 3, cool?: true).number).must_equal 3 } # with model hash and options hash separated. - it { expect(Song.new({number: 3}, {cool?: true}).cool?).must_equal true } - it { expect(Song.new({number: 3}, {cool?: true}).number).must_equal 3 } - - # with string key and false value - it { Song.new('number' => 3, 'cool?' => false).cool?.must_equal false } - + it { _(Song.new({ number: 3 }, { cool?: true }).cool?).must_equal true } + it { _(Song.new({ number: 3 }, { cool?: true }).number).must_equal 3 } - describe "writing" do - let (:song) { Song.new(model, {cool?: true}) } - let (:model) { {number: 3} } + describe 'writing' do + let(:song) { Song.new(model, { cool?: true }) } + let(:model) { { number: 3 } } # writer it do song.number = 9 - expect(song.number).must_equal 9 - expect(model[:number]).must_equal 3 + _(song.number).must_equal 9 + _(model[:number]).must_equal 3 end # writer with sync @@ -45,15 +43,14 @@ class Song < Disposable::Twin song.number = 9 model = song.sync - expect(song.number).must_equal 9 - expect(model["number"]).must_equal 9 + _(song.number).must_equal 9 + _(model['number']).must_equal 9 - # song.send(:model).object_id).must_equal model.object_id + # song.send(:model).object_id.must_equal model.object_id end end end - class TwinWithNestedStructTest < MiniTest::Spec class Song < Disposable::Twin property :title @@ -78,66 +75,67 @@ class Song < Disposable::Twin end # FIXME: test with missing hash properties, e.g. without released and with released:false. - let (:model) { OpenStruct.new(title: "Seed of Fear and Anger", options: {recorded: true, released: 1, - preferences: {show_image: true, play_teaser: 2}, roles: [{name: "user"}]}) } + let(:model) do + OpenStruct.new(title: 'Seed of Fear and Anger', options: { recorded: true, released: 1, + preferences: { show_image: true, play_teaser: 2 }, roles: [{ name: 'user' }] }) + end # public "hash" reader - it { expect(Song.new(model).options.recorded).must_equal true } + it { _(Song.new(model).options.recorded).must_equal true } # public "hash" writer it { song = Song.new(model) - song.options.recorded = "yo" - expect(song.options.recorded).must_equal "yo" + song.options.recorded = 'yo' + _(song.options.recorded).must_equal 'yo' - expect(song.options.preferences.show_image).must_equal true - expect(song.options.preferences.play_teaser).must_equal 2 - - song.options.preferences.show_image= 9 + _(song.options.preferences.show_image).must_equal true + _(song.options.preferences.play_teaser).must_equal 2 + song.options.preferences.show_image = 9 song.sync # this is only called on the top model, e.g. in Reform#save. - expect(model.title).must_equal "Seed of Fear and Anger" - expect(model.options["recorded"]).must_equal "yo" - expect(model.options["preferences"]).must_equal({"show_image" => 9, "play_teaser"=>2}) + _(model.title).must_equal 'Seed of Fear and Anger' + _(model.options['recorded']).must_equal 'yo' + _(model.options['preferences']).must_equal({ 'show_image' => 9, 'play_teaser' => 2 }) } - describe "nested writes" do - let (:song) { Song.new(model) } + describe 'nested writes' do + let(:song) { Song.new(model) } # adding to collection. it do # note that Struct-twin's public API wants a hash! # it kinda sucks that the user has to know there's a hash model in place. is that what we want? role = song.options.roles.append({}) # add empty "model" to hash collection. - role.name = "admin" + role.name = 'admin' - expect(song.options.roles.size).must_equal 2 - expect(song.options.roles[0].name).must_equal "user" - expect(song.options.roles[1].name).must_equal "admin" - expect(model.options[:roles]).must_equal([{:name=>"user"}]) # model hasn't changed, of course. + _(song.options.roles.size).must_equal 2 + _(song.options.roles[0].name).must_equal 'user' + _(song.options.roles[1].name).must_equal 'admin' + _(model.options[:roles]).must_equal([{ name: 'user' }]) # model hasn't changed, of course. song.sync - expect(model.options).must_equal({"recorded"=>true, "released"=>1, "preferences"=>{"show_image"=>true, "play_teaser"=>2}, "roles"=>[{"name"=>"user"}, {"name"=>"admin"}]}) + _(model.options).must_equal({ 'recorded' => true, 'released' => 1, 'preferences' => { 'show_image' => true, 'play_teaser' => 2 }, 'roles' => [{ 'name' => 'user' }, { 'name' => 'admin' }] }) end # overwriting nested property via #preferences=. it do - song.options.preferences = {play_teaser: :maybe} + song.options.preferences = { play_teaser: :maybe } song.sync - expect(model.options).must_equal({"recorded"=>true, "released"=>1, "preferences"=>{"play_teaser"=>:maybe}, "roles"=>[{"name"=>"user"}]}) + _(model.options).must_equal({ 'recorded' => true, 'released' => 1, 'preferences' => { 'play_teaser' => :maybe }, 'roles' => [{ 'name' => 'user' }] }) end # overwriting collection via #roles=. it do - song.options.roles = [{name: "wizard"}] + song.options.roles = [{ name: 'wizard' }] song.sync - expect(model.options).must_equal({"recorded"=>true, "released"=>1, "preferences"=>{"show_image"=>true, "play_teaser"=>2}, "roles"=>[{"name"=>"wizard"}]}) + _(model.options).must_equal({ 'recorded' => true, 'released' => 1, 'preferences' => { 'show_image' => true, 'play_teaser' => 2 }, 'roles' => [{ 'name' => 'wizard' }] }) end end @@ -149,16 +147,14 @@ class Song < Disposable::Twin # song.sync - # model[:options][:roles]).must_equal({ }) + # model[:options][:roles].must_equal({ }) # pp song - # song.options.preferences.sync! # song.options.model.must_be_instance_of Hash # song.options.preferences.model.must_be_instance_of Hash - # # this must break! # # song.options.preferences = OpenStruct.new(play_teaser: true) # write property object to hash fragment. # # this must break! @@ -166,8 +162,7 @@ class Song < Disposable::Twin # song.options.sync! # end - - describe "#save" do + describe '#save' do it { Song.new(model).extend(Disposable::Twin::Save).save } end end @@ -179,13 +174,13 @@ class Song < Disposable::Twin property :id, readable: false end - it "ignores readable: false" do + it 'ignores readable: false' do song = Song.new(length: 123, id: 1) - expect(song.length).must_equal 123 - expect(song.id).must_be_nil + _(song.length).must_equal 123 + _(song.id).must_be_nil end - it "ignores writeable: false" do + it 'ignores writeable: false' do skip end end @@ -198,34 +193,34 @@ class Twin < Disposable::Twin feature Default feature Sync - property :settings, default: Hash.new do + property :settings, default: {} do include Property::Struct - property :enabled, default: "yes" - property :roles, default: Hash.new do + property :enabled, default: 'yes' + property :roles, default: {} do include Property::Struct - property :admin, default: "maybe" + property :admin, default: 'maybe' end end end # all given. it do - twin = Twin.new(Song.new({enabled: true, roles: {admin: false}})) - expect(twin.settings.enabled).must_equal true - expect(twin.settings.roles.admin).must_equal false + twin = Twin.new(Song.new({ enabled: true, roles: { admin: false } })) + _(twin.settings.enabled).must_equal true + _(twin.settings.roles.admin).must_equal false end # defaults, please. it do song = Song.new twin = Twin.new(song) - expect(twin.settings.enabled).must_equal "yes" - expect(twin.settings.roles.admin).must_equal "maybe" + _(twin.settings.enabled).must_equal 'yes' + _(twin.settings.roles.admin).must_equal 'maybe' twin.sync - expect(song.settings).must_equal({"enabled"=>"yes", "roles"=>{"admin"=>"maybe"}}) + _(song.settings).must_equal({ 'enabled' => 'yes', 'roles' => { 'admin' => 'maybe' } }) end end @@ -234,7 +229,7 @@ class PersistedSheet < Disposable::Twin feature Sync property :content do - feature Struct + feature Property::Struct property :tags collection :notes do @@ -244,7 +239,7 @@ class PersistedSheet < Disposable::Twin end def tags=(*args) - content.tags=*args + content.tags = *args end def notes @@ -252,29 +247,27 @@ def notes end end - it "use nested twin but delegate" do + it 'use nested twin but delegate' do twin = PersistedSheet.new(model) - twin.tags = "history" + twin.tags = 'history' - twin.notes.append text: "Canberra trip", index: 2 + twin.notes.append text: 'Canberra trip', index: 2 twin.sync - expect(model.content).must_equal({"tags"=>["history"], "notes"=>[{"text"=>"Freedom", "index"=>0}, {"text"=>"Like", "index"=>1}, {"text"=>"Canberra trip", "index"=>2}]}) + _(model.content).must_equal({ 'tags' => ['history'], 'notes' => [{ 'text' => 'Freedom', 'index' => 0 }, { 'text' => 'Like', 'index' => 1 }, { 'text' => 'Canberra trip', 'index' => 2 }] }) end class Sheet < Disposable::Twin include Composition feature Sync - property :tags, on: :content #, twin: PersistedSheet.definitions.get[:content].definitions.get(:tags) + property :tags, on: :content # , twin: PersistedSheet.definitions.get[:content].definitions.get(:tags) collection :notes, on: :content do property :text property :index - end#, twin: PersistedSheet.definitions.get(:content)[:nested].definitions.get(:notes)[:nested] - - + end # , twin: PersistedSheet.definitions.get(:content)[:nested].definitions.get(:notes)[:nested] end class Sheeeeeeet < Disposable::Twin @@ -288,47 +281,40 @@ class Sheeeeeeet < Disposable::Twin end end - let (:model) do + let(:model) do OpenStruct.new( content: { - tags: "#hashtag", + tags: '#hashtag', notes: [ - { text: "Freedom", created_at: nil, index: 0 }, - { text: "Like", created_at: nil, index: 1 }, + { text: 'Freedom', created_at: nil, index: 0 }, + { text: 'Like', created_at: nil, index: 1 } ] } ) end - - let (:persisted_sheet) { PersistedSheet.new(model) } - let (:sheet) { Sheet.new(content: persisted_sheet.content) } + let(:persisted_sheet) { PersistedSheet.new(model) } + let(:sheet) { Sheet.new(content: persisted_sheet.content) } it do skip # this fails because the Sheet wants to write PersistedSheet.options.notes twins to the persisted sheet in #sync, # instead of an array of hashes. + # sheeet= Sheeeeeeet.new(p= PersistedSheet.new(model)) + # p.content = sheeet.content -# sheeet= Sheeeeeeet.new(p= PersistedSheet.new(model)) - -# p.content = sheeet.content - -# raise -# sheeet.sync -# raise + # raise + # sheeet.sync + # raise - - - - expect(sheet.tags).must_equal "#hashtag" - expect(sheet.notes[0].text).must_equal "Freedom" - expect(sheet.notes[0].index).must_equal 0 + _(sheet.tags).must_equal '#hashtag' + _(sheet.notes[0].text).must_equal 'Freedom' + _(sheet.notes[0].index).must_equal 0 sheet.notes[0].index = 2 sheet.sync - end end diff --git a/test/twin/sync_option_test.rb b/test/twin/sync_option_test.rb index 22f117f..ed945db 100644 --- a/test/twin/sync_option_test.rb +++ b/test/twin/sync_option_test.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # require 'test_helper' # require "disposable/twin/changed" @@ -8,7 +9,6 @@ # Artist = Struct.new(:name, :hidden_taste) # end - # module Twin # class Album < Disposable::Twin # feature Setup @@ -29,8 +29,6 @@ # end # end - - # # sync does NOT call setter. # describe ":sync allows you conditionals and is run in twin context" do # let (:album) { Model::Album.new(1, "Corridors Of Power", [song, song_with_composer], artist) } @@ -77,7 +75,6 @@ # end # end - # class SyncWithDynamicOptionsTest < MiniTest::Spec # module Model # Song = Struct.new(:title, :composer) @@ -85,7 +82,6 @@ # Artist = Struct.new(:name, :hidden_taste) # end - # module Twin # class Album < Disposable::Twin # feature Setup @@ -106,7 +102,6 @@ # end # end - # # sync does NOT call setter. # describe ":sync allows you conditionals and is run in twin context" do # let (:album) { Model::Album.new(1, "Corridors Of Power", [song, song_with_composer], artist) } @@ -151,7 +146,6 @@ # end # end - # class SyncWithOptionsAndSkipUnchangedTest < MiniTest::Spec # module Model # Song = Struct.new(:title, :composer) @@ -159,7 +153,6 @@ # Artist = Struct.new(:name) # end - # module Twin # class Album < Disposable::Twin # feature Setup @@ -225,4 +218,3 @@ # # song.band.name.must_equal "Rise Against" # # end # # end - diff --git a/test/twin/sync_test.rb b/test/twin/sync_test.rb index e9248dd..195760d 100644 --- a/test/twin/sync_test.rb +++ b/test/twin/sync_test.rb @@ -1,4 +1,6 @@ -require "test_helper" +# frozen_string_literal: true + +require 'test_helper' class TwinSyncTest < MiniTest::Spec module Model @@ -7,7 +9,6 @@ module Model Artist = Struct.new(:name) end - module Twin class Album < Disposable::Twin feature Setup @@ -29,15 +30,13 @@ class Album < Disposable::Twin end end + let(:song) { Model::Song.new } + let(:composer) { Model::Artist.new(nil) } + let(:song_with_composer) { Model::Song.new(nil, composer) } + let(:artist) { Model::Artist.new(nil) } - let (:song) { Model::Song.new() } - let (:composer) { Model::Artist.new(nil) } - let (:song_with_composer) { Model::Song.new(nil, composer) } - let (:artist) { Model::Artist.new(nil) } - - - describe "#sync" do - let (:album) { Model::Album.new(nil, [song, song_with_composer], artist) } + describe '#sync' do + let(:album) { Model::Album.new(nil, [song, song_with_composer], artist) } # with populated model. it do @@ -47,23 +46,23 @@ class Album < Disposable::Twin fill_out!(twin) # not written to model, yet. - expect(album.name).must_be_nil - expect(album.songs[0].title).must_be_nil - expect(album.songs[1].title).must_be_nil - expect(album.songs[1].composer.name).must_be_nil - expect(album.artist.name).must_be_nil + _(album.name).must_be_nil + _(album.songs[0].title).must_be_nil + _(album.songs[1].title).must_be_nil + _(album.songs[1].composer.name).must_be_nil + _(album.artist.name).must_be_nil twin.sync - expect(album.name).must_equal "Live And Dangerous" - expect(album.songs[0]).must_be_instance_of Model::Song - expect(album.songs[1]).must_be_instance_of Model::Song - expect(album.songs[0].title).must_equal "Southbound" - expect(album.songs[1].title).must_equal "The Boys Are Back In Town" - expect(album.songs[1].composer).must_be_instance_of Model::Artist - expect(album.songs[1].composer.name).must_equal "Lynott" - expect(album.artist).must_be_instance_of Model::Artist - expect(album.artist.name).must_equal "Thin Lizzy" + _(album.name).must_equal 'Live And Dangerous' + _(album.songs[0]).must_be_instance_of Model::Song + _(album.songs[1]).must_be_instance_of Model::Song + _(album.songs[0].title).must_equal 'Southbound' + _(album.songs[1].title).must_equal 'The Boys Are Back In Town' + _(album.songs[1].composer).must_be_instance_of Model::Artist + _(album.songs[1].composer.name).must_equal 'Lynott' + _(album.artist).must_be_instance_of Model::Artist + _(album.artist.name).must_equal 'Thin Lizzy' end # with empty, not populated model. @@ -72,31 +71,31 @@ class Album < Disposable::Twin twin = Twin::Album.new(album) # this usually happens in Contract::Validate or in from_* in a representer - twin.name = "Live And Dangerous" + twin.name = 'Live And Dangerous' twin.songs.insert(0, song) twin.songs.insert(1, song_with_composer) - twin.songs[0].title = "Southbound" - twin.songs[1].title = "The Boys Are Back In Town" - twin.songs[1].composer.name = "Lynott" + twin.songs[0].title = 'Southbound' + twin.songs[1].title = 'The Boys Are Back In Town' + twin.songs[1].composer.name = 'Lynott' # not written to model, yet. - expect(album.name).must_be_nil - expect(album.songs).must_equal [] - expect(album.artist).must_be_nil + _(album.name).must_be_nil + _(album.songs).must_equal [] + _(album.artist).must_be_nil twin.sync # this assigns a new collection via #songs=. - expect(album.name).must_equal "Live And Dangerous" - expect(album.songs[0].title).must_equal "Southbound" - expect(album.songs[1].title).must_equal "The Boys Are Back In Town" - expect(album.songs[1].composer.name).must_equal "Lynott" + _(album.name).must_equal 'Live And Dangerous' + _(album.songs[0].title).must_equal 'Southbound' + _(album.songs[1].title).must_equal 'The Boys Are Back In Town' + _(album.songs[1].composer.name).must_equal 'Lynott' end # save with block. - describe "#to_nested_hash" do - let (:twin) { Twin::Album.new(album) } + describe '#to_nested_hash' do + let(:twin) { Twin::Album.new(album) } it "creates nested_hash and doesn't sync" do # this usually happens in Contract::Validate or in from_* in a representer @@ -107,50 +106,47 @@ class Album < Disposable::Twin nested_hash = hash end - expect(nested_hash).must_equal({"name"=>"Live And Dangerous", "songs"=>[{"title"=>"Southbound", "composer"=>nil}, {"title"=>"The Boys Are Back In Town", "composer"=>{"name"=>"Lynott"}}], "artist"=>{"name"=>"Thin Lizzy"}}) + _(nested_hash).must_equal({ 'name' => 'Live And Dangerous', 'songs' => [{ 'title' => 'Southbound', 'composer' => nil }, { 'title' => 'The Boys Are Back In Town', 'composer' => { 'name' => 'Lynott' } }], 'artist' => { 'name' => 'Thin Lizzy' } }) # nothing written to model. - expect(album.name).must_be_nil - expect(album.songs[0].title).must_be_nil - expect(album.songs[1].title).must_be_nil - expect(album.songs[1].composer.name).must_be_nil - expect(album.artist.name).must_be_nil + _(album.name).must_be_nil + _(album.songs[0].title).must_be_nil + _(album.songs[1].title).must_be_nil + _(album.songs[1].composer.name).must_be_nil + _(album.artist.name).must_be_nil end - describe "nil values" do - it "includes nil values, including nil collections" do + describe 'nil values' do + it 'includes nil values, including nil collections' do twin = Twin::Album.new(Model::Album.new(nil, - nil, # uninitialized nil collection. - nil) - ) + nil, # uninitialized nil collection. + nil)) nested_hash = nil twin.sync { |hash| nested_hash = hash } - expect(nested_hash).must_equal({"name"=>nil, "artist"=>nil}) + _(nested_hash).must_equal({ 'name' => nil, 'artist' => nil }) end - it "includes empty collections" do + it 'includes empty collections' do twin = Twin::Album.new(Model::Album.new(nil, - [], # empty collection. - nil) - ) + [], # empty collection. + nil)) nested_hash = nil twin.sync { |hash| nested_hash = hash } - expect(nested_hash).must_equal({"name"=>nil, "songs"=>[], "artist"=>nil}) + _(nested_hash).must_equal({ 'name' => nil, 'songs' => [], 'artist' => nil }) end end end - def fill_out!(twin) - twin.name = "Live And Dangerous" - twin.songs[0].title = "Southbound" - twin.songs[1].title = "The Boys Are Back In Town" - twin.songs[1].composer.name = "Lynott" - twin.artist.name = "Thin Lizzy" + twin.name = 'Live And Dangerous' + twin.songs[0].title = 'Southbound' + twin.songs[1].title = 'The Boys Are Back In Town' + twin.songs[1].composer.name = 'Lynott' + twin.artist.name = 'Thin Lizzy' end end end diff --git a/test/twin/twin_test.rb b/test/twin/twin_test.rb index 16a52e5..bd979fc 100644 --- a/test/twin/twin_test.rb +++ b/test/twin/twin_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class TwinTest < MiniTest::Spec @@ -28,59 +30,59 @@ class Song < Disposable::Twin end end - let (:song) { Model::Song.new(1, "Broken", nil) } + let(:song) { Model::Song.new(1, 'Broken', nil) } - describe "#initialize" do + describe '#initialize' do it do twin = Twin::Song.new(song) song.id = 2 # :from maps public name - expect(twin.title).must_equal "Broken" # public: #record_name - expect(twin.id).must_equal 1 + _(twin.title).must_equal 'Broken' # public: #record_name + _(twin.id).must_equal 1 end # allows passing options. it do # override twin's value... - expect(Twin::Song.new(song, :title => "Kenny").title).must_equal "Kenny" + _(Twin::Song.new(song, title: 'Kenny').title).must_equal 'Kenny' # .. but do not write to the model! - expect(song.title).must_equal "Broken" + _(song.title).must_equal 'Broken' end end - describe "setter" do - let (:twin) { Twin::Song.new(song) } - let (:album) { Model::Album.new(1, "The Stories Are True") } + describe 'setter' do + let(:twin) { Twin::Song.new(song) } + let(:album) { Model::Album.new(1, 'The Stories Are True') } it do twin.id = 3 - twin.title = "Lucky" + twin.title = 'Lucky' twin.album = album # this is a model, not a twin. # updates twin - expect(twin.id).must_equal 3 - expect(twin.title).must_equal "Lucky" + _(twin.id).must_equal 3 + _(twin.title).must_equal 'Lucky' # setter for nested property will twin value. twin.album.extend(Disposable::Comparable) - assert twin.album == Twin::Album.new(album) # FIXME: why does) must_equal not call #== ? + assert_equal twin.album, Twin::Album.new(album) # FIXME: why does must_equal not call #== ? # setter for nested collection. # DOES NOT update model - expect(song.id).must_equal 1 - expect(song.title).must_equal "Broken" + _(song.id).must_equal 1 + _(song.title).must_equal 'Broken' end - describe "deleting" do - it "allows overwriting nested twin with nil" do - album = Model::Album.new(1, "Uncertain Terms", [], Model::Artist.new("Greg Howe")) + describe 'deleting' do + it 'allows overwriting nested twin with nil' do + album = Model::Album.new(1, 'Uncertain Terms', [], Model::Artist.new('Greg Howe')) twin = Twin::Album.new(album) - expect(twin.artist.id).must_equal "Greg Howe" + _(twin.artist.id).must_equal 'Greg Howe' twin.artist = nil - expect(twin.artist).must_be_nil + _(twin.artist).must_be_nil end end @@ -92,7 +94,6 @@ class Song < Disposable::Twin end end - class OverridingAccessorsTest < TwinTest # overriding accessors in Twin class Song < Disposable::Twin @@ -104,38 +105,35 @@ def title end def id=(v) - super(v+1) + super(v + 1) end end - let (:model) { Model::Song.new(1, "A Tale That Wasn't Right") } - it { expect(Song.new(model).title).must_equal "a tale that wasn't right" } - it { expect(Song.new(model).id).must_equal 2 } + let(:model) { Model::Song.new(1, "A Tale That Wasn't Right") } + it { _(Song.new(model).title).must_equal "a tale that wasn't right" } + it { _(Song.new(model).id).must_equal 2 } end - class TwinAsTest < MiniTest::Spec module Model Song = Struct.new(:title, :album) Album = Struct.new(:name) end - module Twin class Album < Disposable::Twin - property :record_name, :from => :name + property :record_name, from: :name # model Model::Album end class Song < Disposable::Twin - property :name, :from => :title - property :record, twin: Album, :from => :album + property :name, from: :title + property :record, twin: Album, from: :album # model Model::Song end end - end # TODO: test coercion! @@ -147,18 +145,18 @@ class Twin < Disposable::Twin end it do - twin = Twin.new(Song.new("bla")) - expect(twin.format).must_equal "bla" - twin.format = "blubb" + twin = Twin.new(Song.new('bla')) + _(twin.format).must_equal 'bla' + twin.format = 'blubb' end end class InvalidPropertyNameTest < Minitest::Spec it 'raises InvalidPropertyNameError' do - assert_raises(Disposable::Twin::InvalidPropertyNameError) { + assert_raises(Disposable::Twin::InvalidPropertyNameError) do class Twin < Disposable::Twin property :class end - } + end end end diff --git a/test/twin/unnest_test.rb b/test/twin/unnest_test.rb index db43341..2ae2774 100644 --- a/test/twin/unnest_test.rb +++ b/test/twin/unnest_test.rb @@ -1,10 +1,12 @@ -require "test_helper" +# frozen_string_literal: true + +require 'test_helper' class UnnestTest < MiniTest::Spec class Twin < Disposable::Twin property :content do - property :id, nice: "yes" - collection :ids, status: "healthy" + property :id, nice: 'yes' + collection :ids, status: 'healthy' property :email do end @@ -15,23 +17,22 @@ class Twin < Disposable::Twin unnest :email, from: :content end - it "copies property option" do - expect(Twin.definitions.get(:id).extend(Declarative::Inspect).inspect).must_equal %{#\"yes\", :private_name=>:id, :name=>\"id\", :readable=>false, :writeable=>false}>} - expect(Twin.definitions.get(:ids).extend(Declarative::Inspect).inspect).must_equal %{#\"healthy\", :collection=>true, :private_name=>:ids, :name=>\"ids\", :readable=>false, :writeable=>false}>} + it 'copies property option' do + _(Twin.definitions.get(:id).extend(Declarative::Inspect).inspect).must_equal %(#\"yes\", :private_name=>:id, :name=>\"id\", :readable=>false, :writeable=>false}>) + _(Twin.definitions.get(:ids).extend(Declarative::Inspect).inspect).must_equal %(#\"healthy\", :collection=>true, :private_name=>:ids, :name=>\"ids\", :readable=>false, :writeable=>false}>) # also copies :nested. - expect(Twin.definitions.get(:email).extend(Declarative::Inspect).inspect).must_equal %{#:email, :nested=>#, :name=>\"email\", :readable=>false, :writeable=>false}>} + _(Twin.definitions.get(:email).extend(Declarative::Inspect).inspect).must_equal %(#:email, :nested=>#, :name=>\"email\", :readable=>false, :writeable=>false}>) end - it "exposes accessors on top-level twin" do - twin = Twin.new(OpenStruct.new(content: OpenStruct.new())) - - expect(twin.email).must_be_nil - twin.email= 2 - expect(twin.email.model).must_equal 2 + it 'exposes accessors on top-level twin' do + twin = Twin.new(OpenStruct.new(content: OpenStruct.new)) + _(twin.email).must_be_nil + twin.email = 2 + _(twin.email.model).must_equal 2 - expect(twin.id).must_be_nil + _(twin.id).must_be_nil twin.id = 1 - expect(twin.id).must_equal 1 + _(twin.id).must_equal 1 end end diff --git a/test/twin/virtual_test.rb b/test/twin/virtual_test.rb index ea65940..c408fa9 100644 --- a/test/twin/virtual_test.rb +++ b/test/twin/virtual_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'test_helper' class VirtualTest < MiniTest::Spec @@ -6,12 +8,12 @@ class CreditCardTwin < Disposable::Twin property :credit_card_number, virtual: true # no read, no write, it's virtual. end - let (:twin) { CreditCardTwin.new(Object.new) } + let(:twin) { CreditCardTwin.new(Object.new) } it { - twin.credit_card_number = "123" + twin.credit_card_number = '123' - expect(twin.credit_card_number).must_equal "123" # this is still readable in the UI. + _(twin.credit_card_number).must_equal '123' # this is still readable in the UI. twin.sync @@ -20,20 +22,20 @@ class CreditCardTwin < Disposable::Twin hash = nested end - expect(hash).must_equal("credit_card_number"=> "123") + _(hash).must_equal('credit_card_number' => '123') } - describe "setter should never be called with virtual:true" do + describe 'setter should never be called with virtual:true' do class Raising < Disposable::Twin property :id, virtual: true def id=(*) - raise "i should never be called!" + raise 'i should never be called!' end end - it "what" do - expect(Raising.new(Object.new).id).must_be_nil + it 'what' do + _(Raising.new(Object.new).id).must_be_nil end end end diff --git a/test/twin/writeable_test.rb b/test/twin/writeable_test.rb index 0d24761..fc34a18 100644 --- a/test/twin/writeable_test.rb +++ b/test/twin/writeable_test.rb @@ -1,14 +1,16 @@ +# frozen_string_literal: true + require 'test_helper' class WriteableTest < MiniTest::Spec Credentials = Struct.new(:password, :credit_card) do - def password=(v) + def password=(_v) raise "don't call me!" end end CreditCard = Struct.new(:name, :number) do - def number=(v) + def number=(_v) raise "don't call me!" end end @@ -25,25 +27,25 @@ class PasswordForm < Disposable::Twin end end - let (:cred) { Credentials.new("secret", CreditCard.new("Jonny", "0987654321")) } + let(:cred) { Credentials.new('secret', CreditCard.new('Jonny', '0987654321')) } - let (:twin) { PasswordForm.new(cred) } + let(:twin) { PasswordForm.new(cred) } it { - expect(twin.password).must_equal "secret" - expect(twin.credit_card.name).must_equal "Jonny" - expect(twin.credit_card.number).must_equal "0987654321" + _(twin.password).must_equal 'secret' + _(twin.credit_card.name).must_equal 'Jonny' + _(twin.credit_card.number).must_equal '0987654321' # manual setting on the twin works. - twin.password = "123" - expect(twin.password).must_equal "123" + twin.password = '123' + _(twin.password).must_equal '123' - twin.credit_card.number = "456" - expect(twin.credit_card.number).must_equal "456" + twin.credit_card.number = '456' + _(twin.credit_card.number).must_equal '456' twin.sync - expect(cred.inspect).must_equal '#>' + _(cred.inspect).must_equal '#>' # test sync{}. hash = {} @@ -51,6 +53,6 @@ class PasswordForm < Disposable::Twin hash = nested end - expect(hash).must_equal("password"=> "123", "credit_card"=>{"name"=>"Jonny", "number"=>"456"}) + _(hash).must_equal('password' => '123', 'credit_card' => { 'name' => 'Jonny', 'number' => '456' }) } end