From b475afee56266ab58f7d144ec3f8c29fc2d08726 Mon Sep 17 00:00:00 2001 From: Paul Dobbins Date: Fri, 13 Apr 2018 19:18:56 -0500 Subject: [PATCH] Refresh gem; Bump version to 0.1.0 Simplify/clarify code, documentation, and README. Remove dependency on Rails. Add Travis CI. Add SimpleCov. --- .gitignore | 21 +-- .travis.yml | 21 +++ CHANGELOG.md | 7 + Gemfile | 16 +- Gemfile.lock | 117 +++++--------- LICENSE.txt | 21 +++ MIT-LICENSE | 20 --- README.md | 130 +++++++++------ Rakefile | 34 +--- bin/console | 14 ++ bin/setup | 8 + lib/object_identifier.rb | 8 +- lib/object_identifier/core_ext/big_decimal.rb | 6 +- lib/object_identifier/core_ext/object.rb | 13 +- lib/object_identifier/core_ext/string.rb | 12 +- lib/object_identifier/core_ext/symbol.rb | 4 +- lib/object_identifier/identifier.rb | 118 +++++++------- lib/object_identifier/version.rb | 2 +- object_identifier.gemspec | 51 ++++-- test/dummy/README.rdoc | 28 ---- test/dummy/Rakefile | 6 - test/dummy/app/assets/images/.keep | 0 .../app/assets/javascripts/application.js | 13 -- .../app/assets/stylesheets/application.css | 13 -- .../app/controllers/application_controller.rb | 5 - test/dummy/app/controllers/concerns/.keep | 0 test/dummy/app/helpers/application_helper.rb | 2 - test/dummy/app/mailers/.keep | 0 test/dummy/app/models/.keep | 0 test/dummy/app/models/concerns/.keep | 0 .../app/views/layouts/application.html.erb | 14 -- test/dummy/bin/bundle | 3 - test/dummy/bin/rails | 4 - test/dummy/bin/rake | 4 - test/dummy/config.ru | 4 - test/dummy/config/application.rb | 23 --- test/dummy/config/boot.rb | 5 - test/dummy/config/database.yml | 25 --- test/dummy/config/environment.rb | 5 - test/dummy/config/environments/development.rb | 29 ---- test/dummy/config/environments/production.rb | 80 ---------- test/dummy/config/environments/test.rb | 36 ----- .../initializers/backtrace_silencers.rb | 7 - .../initializers/filter_parameter_logging.rb | 4 - test/dummy/config/initializers/inflections.rb | 16 -- test/dummy/config/initializers/mime_types.rb | 5 - .../dummy/config/initializers/secret_token.rb | 12 -- .../config/initializers/session_store.rb | 3 - .../config/initializers/wrap_parameters.rb | 14 -- test/dummy/config/locales/en.yml | 23 --- test/dummy/config/routes.rb | 56 ------- test/dummy/lib/assets/.keep | 0 test/dummy/log/.keep | 0 test/dummy/public/404.html | 58 ------- test/dummy/public/422.html | 58 ------- test/dummy/public/500.html | 57 ------- test/dummy/public/favicon.ico | 0 test/object_identifier_test.rb | 148 ++++++++++++------ test/test_helper.rb | 26 +-- 59 files changed, 438 insertions(+), 971 deletions(-) create mode 100644 .travis.yml create mode 100644 LICENSE.txt delete mode 100644 MIT-LICENSE create mode 100755 bin/console create mode 100755 bin/setup delete mode 100644 test/dummy/README.rdoc delete mode 100644 test/dummy/Rakefile delete mode 100644 test/dummy/app/assets/images/.keep delete mode 100644 test/dummy/app/assets/javascripts/application.js delete mode 100644 test/dummy/app/assets/stylesheets/application.css delete mode 100644 test/dummy/app/controllers/application_controller.rb delete mode 100644 test/dummy/app/controllers/concerns/.keep delete mode 100644 test/dummy/app/helpers/application_helper.rb delete mode 100644 test/dummy/app/mailers/.keep delete mode 100644 test/dummy/app/models/.keep delete mode 100644 test/dummy/app/models/concerns/.keep delete mode 100644 test/dummy/app/views/layouts/application.html.erb delete mode 100755 test/dummy/bin/bundle delete mode 100755 test/dummy/bin/rails delete mode 100755 test/dummy/bin/rake delete mode 100644 test/dummy/config.ru delete mode 100644 test/dummy/config/application.rb delete mode 100644 test/dummy/config/boot.rb delete mode 100644 test/dummy/config/database.yml delete mode 100644 test/dummy/config/environment.rb delete mode 100644 test/dummy/config/environments/development.rb delete mode 100644 test/dummy/config/environments/production.rb delete mode 100644 test/dummy/config/environments/test.rb delete mode 100644 test/dummy/config/initializers/backtrace_silencers.rb delete mode 100644 test/dummy/config/initializers/filter_parameter_logging.rb delete mode 100644 test/dummy/config/initializers/inflections.rb delete mode 100644 test/dummy/config/initializers/mime_types.rb delete mode 100644 test/dummy/config/initializers/secret_token.rb delete mode 100644 test/dummy/config/initializers/session_store.rb delete mode 100644 test/dummy/config/initializers/wrap_parameters.rb delete mode 100644 test/dummy/config/locales/en.yml delete mode 100644 test/dummy/config/routes.rb delete mode 100644 test/dummy/lib/assets/.keep delete mode 100644 test/dummy/log/.keep delete mode 100644 test/dummy/public/404.html delete mode 100644 test/dummy/public/422.html delete mode 100644 test/dummy/public/500.html delete mode 100644 test/dummy/public/favicon.ico diff --git a/.gitignore b/.gitignore index 08f1259..23d73bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,11 @@ -.bundle/ -.yardoc/ -doc/ -log/*.log -pkg/ -test/dummy/db/*.sqlite3 -test/dummy/db/*.sqlite3-journal -test/dummy/log/*.log -test/dummy/tmp/ -test/dummy/.sass-cache +/.bundle/ +/.yardoc +/_yardoc/ +/coverage/ +/doc/ +/pkg/ +/spec/reports/ +/tmp/ +.byebug_history +*.gem +.DS_Store diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..9c72fea --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +env: + global: + - CC_TEST_REPORTER_ID=3b57e55dcd3cc40ee073715e7d75fa80ab7b7687cb8a420eac500d27b5cb28db +sudo: false +language: ruby +rvm: + - 2.2.10 + - 2.3.7 + - 2.4.4 + - 2.5.1 + - ruby-head +notifications: + email: false +before_install: gem install bundler -v 1.16.1 +cache: bundler +before_script: + - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter + - chmod +x ./cc-test-reporter + - ./cc-test-reporter before-build +after_script: + - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT diff --git a/CHANGELOG.md b/CHANGELOG.md index ff20675..1d2d4bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +### 0.1.0 - 2018-04-14 + +* Revamp gem +* Update gem dependencies +* Now returns "[no objects]" even if given a :klass option + + ### 0.0.6 - 2016-02-06 * Fix: identify method now supports private & protected methods diff --git a/Gemfile b/Gemfile index 3166a6d..2995b46 100644 --- a/Gemfile +++ b/Gemfile @@ -1,16 +1,6 @@ source "https://rubygems.org" -# Declare your gem's dependencies in object_identifier.gemspec. -# Bundler will treat runtime dependencies like base dependencies, and -# development dependencies will be added by default to the :development group. -gemspec - -# Declare any dependencies that are still in development here instead of in -# your gemspec. These might include edge Rails or gems from your path or -# Git. Remember to move these dependencies to your gemspec before releasing -# your gem to rubygems.org. +git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } -# gem "byebug" -# gem "pry" -# gem "pry-byebug" -# gem "pry-stack_explorer" +# Specify your gem's dependencies in object_identifier.gemspec +gemspec diff --git a/Gemfile.lock b/Gemfile.lock index 8a7d29b..a4bfa53 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,96 +1,51 @@ PATH remote: . specs: - object_identifier (0.0.5) - rails (>= 3.0.0) + object_identifier (0.1.0) GEM remote: https://rubygems.org/ specs: - actionmailer (4.1.5) - actionpack (= 4.1.5) - actionview (= 4.1.5) - mail (~> 2.5.4) - actionpack (4.1.5) - actionview (= 4.1.5) - activesupport (= 4.1.5) - rack (~> 1.5.2) - rack-test (~> 0.6.2) - actionview (4.1.5) - activesupport (= 4.1.5) - builder (~> 3.1) - erubis (~> 2.7.0) - activemodel (4.1.5) - activesupport (= 4.1.5) - builder (~> 3.1) - activerecord (4.1.5) - activemodel (= 4.1.5) - activesupport (= 4.1.5) - arel (~> 5.0.0) - activesupport (4.1.5) - i18n (~> 0.6, >= 0.6.9) - json (~> 1.7, >= 1.7.7) - minitest (~> 5.1) - thread_safe (~> 0.1) - tzinfo (~> 1.1) - arel (5.0.1.20140414130214) - builder (3.2.2) - erubis (2.7.0) - hike (1.2.3) - i18n (0.6.11) - json (1.8.1) - mail (2.5.4) - mime-types (~> 1.16) - treetop (~> 1.4.8) - mime-types (1.25.1) + ansi (1.5.0) + builder (3.2.3) + byebug (10.0.2) + coderay (1.1.2) + docile (1.3.0) + json (2.1.0) + method_source (0.9.0) minitest (5.4.1) - minitest-rails (2.1.0) - minitest (~> 5.4) - railties (~> 4.1) - multi_json (1.10.1) - polyglot (0.3.5) - rack (1.5.2) - rack-test (0.6.2) - rack (>= 1.0) - rails (4.1.5) - actionmailer (= 4.1.5) - actionpack (= 4.1.5) - actionview (= 4.1.5) - activemodel (= 4.1.5) - activerecord (= 4.1.5) - activesupport (= 4.1.5) - bundler (>= 1.3.0, < 2.0) - railties (= 4.1.5) - sprockets-rails (~> 2.0) - railties (4.1.5) - actionpack (= 4.1.5) - activesupport (= 4.1.5) - rake (>= 0.8.7) - thor (>= 0.18.1, < 2.0) + minitest-reporters (1.2.0) + ansi + builder + minitest (>= 5.0) + ruby-progressbar + pry (0.11.3) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + pry-byebug (3.6.0) + byebug (~> 10.0) + pry (~> 0.10) rake (10.3.2) - sprockets (2.12.1) - hike (~> 1.2) - multi_json (~> 1.0) - rack (~> 1.0) - tilt (~> 1.1, != 1.3.0) - sprockets-rails (2.1.3) - actionpack (>= 3.0) - activesupport (>= 3.0) - sprockets (~> 2.8) - sqlite3 (1.3.9) - thor (0.19.1) - thread_safe (0.3.4) - tilt (1.4.1) - treetop (1.4.15) - polyglot - polyglot (>= 0.3.1) - tzinfo (1.2.2) - thread_safe (~> 0.1) + ruby-progressbar (1.9.0) + simplecov (0.16.1) + docile (~> 1.1) + json (>= 1.8, < 3) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.2) PLATFORMS ruby DEPENDENCIES - minitest-rails + bundler (~> 1.16) + byebug (~> 10.0) + minitest (~> 5.0) + minitest-reporters (~> 1.2) object_identifier! - sqlite3 + pry (~> 0.11) + pry-byebug (~> 3.6) + rake (~> 10.0) + simplecov (~> 0.16) + +BUNDLED WITH + 1.16.1 diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..f522831 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Paul Dobbins + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/MIT-LICENSE b/MIT-LICENSE deleted file mode 100644 index a23c616..0000000 --- a/MIT-LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright 2013 Paul Dobbins - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index bc0e7cc..acbb273 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,11 @@ # Object Identifier [![Gem Version](https://badge.fury.io/rb/object_identifier.png)](http://badge.fury.io/rb/object_identifier) +[![Build Status](https://travis-ci.org/pdobb/object_identifier.svg?branch=master)](https://travis-ci.org/pdobb/object_identifier) +[![Test Coverage](https://api.codeclimate.com/v1/badges/0b737a72d16ec755c1ff/test_coverage)](https://codeclimate.com/github/pdobb/object_identifier/test_coverage) +[![Maintainability](https://api.codeclimate.com/v1/badges/0b737a72d16ec755c1ff/maintainability)](https://codeclimate.com/github/pdobb/object_identifier/maintainability) -Object Identifier allows quick, easy, and uniform identification of an object by inspecting its class name and outputting any desirable attributes/methods. This is great for quickly logging, sending more descriptive notifications, or any other purpose. +Object Identifier allows quick, easy, and uniform identification of an object by inspecting its class name and outputting any desirable attributes/methods. It is great for quickly logging, sending descriptive notification messages, etc. For example: @@ -17,117 +20,148 @@ Which is the same as: ``` -## Compatibility - -* Ruby: MRI 1.9.3+ -* Ruby: MRI 2+ -* Rails: 3+ - - ## Installation Add this line to your application's Gemfile: ```ruby -gem 'object_identifier' +gem "object_identifier" ``` And then execute: -```ruby -bundle -``` + $ bundle + +Or install it yourself as: + + $ gem install object_identifier + + +## Compatibility + +Tested MRI Ruby Versions: +* 2.2.10 +* 2.3.7 +* 2.4.4 +* 2.5.1 +* edge ## Usage ### Defaults -Outputs the `id` attribute by default, if possible and if no other attributes -are given: +`identify` outputs the `id` of the receiving object by default, if it exists and no other attributes/methods are specified. ```ruby -some_object.identify # => Movie[id:1] +my_movie.identify # => Movie[id:1] +my_movie.identify(:rating) # => Movie[rating:"7/10"] ``` -Also works with methods: +Private methods can be identified just the same as public methods. ```ruby -some_object.identify(:get_rating) # => Movie[get_rating:"7/10"] +my_movie.identify(:my_private_method) # => Movie[my_private_method:"Shh"] ``` + ### Unknown Attributes/Methods -If the object doesn't respond to a specified attribute/method it is simply -ignored: +If the object doesn't respond to a specified attribute/method it is simply ignored: ```ruby -some_object.identify(:gobble_gobble, :id) # => Movie[id:1] +my_movie.identify(:gobble_gobble, :rating) # => Movie[rating:"7/10"] ``` -### Collections +### Overriding Class Names + +```ruby +my_delayed_job.identify(klass: "Delayed::Job") # => Delayed::Job[id:1] +my_movie.identify(klass: nil) # => [id:1] +``` -Works great with collections: + +### Identifying Nil ```ruby -[some_object, some_other_object].identify(:id, :name) - # => Movie[id:1, name:"Pi"], Contact[id:23, name:"Bob"] +nil.identify(:id, :name) # => [no objects] +nil.identify(:id, :name, klass: "Nope") # => [no objects] ``` -Also allows limiting of results: + +### Collections + +Collections of objects are each identified in turn. ```ruby -[some_object, some_other_object].identify(:id, :name, limit: 1) - # => Movie[id:1, name:"Pi"], ... (1 more) +[my_movie, my_user].identify(:id, :name) +# => Movie[id:1, name:"Pi"], User[id:1, name:"Bob"] ``` -### Overriding the Class Name +The number of results that will be identified from a collection can be truncated by specifying the `limit` option. ```ruby -some_object.identify(klass: "MyMovie") # => MyMovie[id:1] -some_object.identify(klass: nil) # => [id:1] -delayed_job.identify(klass: "Delayed::Job") # => Delayed::Job[id:1] +[my_movie, my_contact].identify(:id, :name, limit: 1) +# => Movie[id:1, name:"Pi"], ... (1 more) ``` -### Nils and Empty Collections + +### Empty Collections ```ruby -nil.identify(:id, :name) # => [no objects] -[].identify # => [no objects] +[].identify # => [no objects] +{}.identify # => [no objects] ``` ## Custom Object Identifiers -Internally, Object Identifier relies on a method named `inspect_lit` to return a "literally-inspected" string representation of all objects being identified. For example: +Internally, Object Identifier calls `inspect_lit` to return a "literally-inspected" string representation of an object. This works because Object, itself, is monkey-patched to define `inspect_lit` which just returns `inspect`. This is sufficient for most objects, but some objects will benefit from defining special output from `inspect_lit`. + +Object Identifier defines `inspect_lit` on three other core objects: String, Symbol, and BigDecimal. ```ruby -:a_symbol.respond_to?(:inspect_lit) # => true -:a_symbol.inspect_lit # => ":\"a_symbol\"" -"a_string".inspect_lit # => "\"a_string\"" -BigDecimal(1.99, 3).inspect_lit # => "" +"a_string".inspect_lit # => "\"a_string\"" +:a_symbol.inspect_lit # => ":\"a_symbol\"" +BigDecimal(1.99, 3).inspect_lit # => "" ``` -Therefore, if you'd like to represent a custom object in a special way for object identification, just define the to-string conversion within the `inspect_lit` method. - +To identify an object in a special way, just define `inspect_lit` to return a custom String. ```ruby -class MyVal +class MyValueObject def initialize(val) @val = val end def inspect_lit - "" + "#{@val} Meters" end end -OpenStruct.new(my_val: MyVal.new(42)).identify(:my_val) -# => "OpenStruct[my_val:]" +my_value_object = MyValueObject.new(42) +OpenStruct.new(my_value: my_value_object).identify(:my_value) +# => "OpenStruct[my_value:42 Meters]" ``` -## Authors +## Supporting Gems + +ObjectIdentifier works great with the [ObjectInspector](https://github.com/pdobb/object_inspector) gem. + + +## Development + +After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. + +To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). + + +## Contributing + +Bug reports and pull requests are welcome on GitHub at https://github.com/pdobb/object_identifier. + + +## License -- Paul Dobbins -- Evan Sherwood +The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). diff --git a/Rakefile b/Rakefile index 5c1ba4a..d433a1e 100644 --- a/Rakefile +++ b/Rakefile @@ -1,32 +1,10 @@ -begin - require 'bundler/setup' -rescue LoadError - puts 'You must `gem install bundler` and `bundle install` to run rake tasks' -end - -require 'rdoc/task' - -RDoc::Task.new(:rdoc) do |rdoc| - rdoc.rdoc_dir = 'rdoc' - rdoc.title = 'ObjectIdentifier' - rdoc.options << '--line-numbers' - rdoc.rdoc_files.include('README.rdoc') - rdoc.rdoc_files.include('lib/**/*.rb') -end - - - - -Bundler::GemHelper.install_tasks - -require 'rake/testtask' +require "bundler/gem_tasks" +require "rake/testtask" Rake::TestTask.new(:test) do |t| - t.libs << 'lib' - t.libs << 'test' - t.pattern = 'test/**/*_test.rb' - t.verbose = false + t.libs << "test" + t.libs << "lib" + t.test_files = FileList["test/**/*_test.rb"] end - -task default: :test +task :default => :test diff --git a/bin/console b/bin/console new file mode 100755 index 0000000..6bc3565 --- /dev/null +++ b/bin/console @@ -0,0 +1,14 @@ +#!/usr/bin/env ruby + +require "bundler/setup" +require "object_identifier" + +# You can add fixtures and/or initialization code here to make experimenting +# with your gem easier. You can also use a different console, if you like. + +# (If you use this, don't forget to add pry to your Gemfile!) +require "pry" +Pry.start + +# require "irb" +# IRB.start(__FILE__) diff --git a/bin/setup b/bin/setup new file mode 100755 index 0000000..dce67d8 --- /dev/null +++ b/bin/setup @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail +IFS=$'\n\t' +set -vx + +bundle install + +# Do any other automated setup that you need to do here diff --git a/lib/object_identifier.rb b/lib/object_identifier.rb index e693862..fe5d2af 100644 --- a/lib/object_identifier.rb +++ b/lib/object_identifier.rb @@ -1,8 +1,8 @@ +module ObjectIdentifier +end + +require "object_identifier/identifier" require "object_identifier/core_ext/object" require "object_identifier/core_ext/string" require "object_identifier/core_ext/symbol" require "object_identifier/core_ext/big_decimal" - -module ObjectIdentifier - autoload :Identifier, "object_identifier/identifier" -end diff --git a/lib/object_identifier/core_ext/big_decimal.rb b/lib/object_identifier/core_ext/big_decimal.rb index 8849228..c936749 100644 --- a/lib/object_identifier/core_ext/big_decimal.rb +++ b/lib/object_identifier/core_ext/big_decimal.rb @@ -1,11 +1,13 @@ +require "bigdecimal" + class BigDecimal # Formats this BigDecimal as an object-type-revealing String. # # @return [String] a String representation of this BigDecimal object # # @example - # BigDecimal.new(1).inspect_lit # => "" - # BigDecimal.new(99.999, 5).inspect_lit # => "" + # BigDecimal.new(1).inspect_lit # => "" + # BigDecimal.new(99.999, 5).inspect_lit # => "" def inspect_lit "" end diff --git a/lib/object_identifier/core_ext/object.rb b/lib/object_identifier/core_ext/object.rb index 8a5ebf3..5e59335 100644 --- a/lib/object_identifier/core_ext/object.rb +++ b/lib/object_identifier/core_ext/object.rb @@ -1,9 +1,8 @@ class Object # Standard #inspect for any object that doesn't override this method. This - # method is meant to make an object's type inherently obvious when used in - # logging methods, etc. + # method is meant to make an object's type inherently obvious inspected. # - # @return [String] a string representation of this object + # @return [String] a String-literal representation of this object def inspect_lit inspect end @@ -20,23 +19,23 @@ def inspect_lit # @param [Hash] options the options for building a customized # self-identifier # @option options [String, nil] :klass object class name override - # @option options [Fixnum] :limit maximum number of objects to display from + # @option options [Integer] :limit maximum number of objects to display from # a collection # - # @return [String] a self-identifying string like `Class[id:1, name:'temp']` + # @return [String] a self-identifying string # # @example # OpenStruct.new(a: 1, b: '2', c: :"3").identify(:a, :b, :c) # # => "OpenStruct[a:1, b:\"2\", c::\"3\"]" # - # 1.identify(:to_s) # => "Fixnum[to_s:\"1\"]" + # 1.identify(:to_s) # => "Integer[to_s:\"1\"]" # nil.identify # => "[no objects]" # # %w(1 2 3).identify(:to_i, :to_f) # # => "String[to_i:1, to_f:1.0], String[to_i:2, to_f:2.0], String[to_i:3, to_f:3.0]" # # (1..10).to_a.identify(:to_f, limit: 2) - # # => "Fixnum[to_f:1.0], Fixnum[to_f:2.0], ... (8 more)" + # # => "Integer[to_f:1.0], Integer[to_f:2.0], ... (8 more)" def identify(*args) ObjectIdentifier::Identifier.identify(self, *args) end diff --git a/lib/object_identifier/core_ext/string.rb b/lib/object_identifier/core_ext/string.rb index c07b3ad..cbe4013 100644 --- a/lib/object_identifier/core_ext/string.rb +++ b/lib/object_identifier/core_ext/string.rb @@ -1,13 +1,13 @@ class String - # Formats this string to look like a string literal so that object type will - # be inherently obvious when used in logging methods, etc. + # Formats self to look like a String literal so that object type will be + # inherently obvious when inspected. # - # @return [String] a string literal representation of this object + # @return [String] a String-literal representation of this object # # @example - # "test".inspect_lit # => "\"test\"" (or '"test"') - # "1".inspect_lit # => "\"1\"" (or '"1"') - # "12.3".inspect_lit # => "\"12.3\"" (or '"12.3"') + # "test".inspect_lit # => "\"test\"" (i.e. '"test"') + # "1".inspect_lit # => "\"1\"" (i.e. '"1"') + # "12.3".inspect_lit # => "\"12.3\"" (i.e. '"12.3"') def inspect_lit %("#{to_s}") end diff --git a/lib/object_identifier/core_ext/symbol.rb b/lib/object_identifier/core_ext/symbol.rb index 04fd1a1..9365661 100644 --- a/lib/object_identifier/core_ext/symbol.rb +++ b/lib/object_identifier/core_ext/symbol.rb @@ -5,8 +5,8 @@ class Symbol # @return [String] a symbol literal representation of this object # # @example - # :test.inspect_lit # => ":\"test\"" (or ':"test"') - # :"ta-da!".inspect_lit # => ":\"ta-da!\"" (or ':"ta-da!"') + # :test.inspect_lit # => ":\"test\"" (or ':"test"') + # :"ta-da!".inspect_lit # => ":\"ta-da!\"" (or ':"ta-da!"') def inspect_lit %(:"#{to_s}") end diff --git a/lib/object_identifier/identifier.rb b/lib/object_identifier/identifier.rb index 71c1fbb..a6d451a 100644 --- a/lib/object_identifier/identifier.rb +++ b/lib/object_identifier/identifier.rb @@ -1,10 +1,6 @@ module ObjectIdentifier class Identifier - def initialize(objects, *args) - @objects = Array.wrap(objects) - @options = args.extract_options! - @attributes = args.empty? ? [:id] : args - end + NO_OBJECTS_INDICATOR = "[no objects]".freeze # Class method for constructing a self-identifying string for any given # object or collection of objects. @@ -20,25 +16,33 @@ def initialize(objects, *args) # @param [Hash] options the options for building a customized # self-identifier # @option options [String, nil] :klass object class name override - # @option options [Fixnum] :limit maximum number of objects to display + # @option options [Integer] :limit maximum number of objects to display # from a collection # # @return [String] a self-identifying string like `Class[id:1, name:'temp']` # # @example - # ObjectIdentifier::Identifier.identify(OpenStruct.new(a: 1, b: '2', c: :"3"), :a, :b, :c) + # ObjectIdentifier::Identifier.identify( + # OpenStruct.new(a: 1, b: '2', c: :"3"), :a, :b, :c) # # => "OpenStruct[a:1, b:\"2\", c::\"3\"]" # - # ObjectIdentifier::Identifier.identify(1, :to_s) # => "Fixnum[to_s:\"1\"]" - # ObjectIdentifier::Identifier.identify(nil) # => "[no objects]" + # ObjectIdentifier::Identifier.identify(1, :to_s) # => "Integer[to_s:\"1\"]" + # ObjectIdentifier::Identifier.identify(nil) # => "[no objects]" # - # ObjectIdentifier::Identifier.identify(%w(1 2 3), :to_i, :to_f) - # # => "String[to_i:1, to_f:1.0], String[to_i:2, to_f:2.0], String[to_i:3, to_f:3.0]" + # ObjectIdentifier::Identifier.identify(%w(1 2), :to_i, :to_f) + # # => "String[to_i:1, to_f:1.0], String[to_i:2, to_f:2.0]" # # ObjectIdentifier::Identifier.identify((1..10).to_a, :to_f, limit: 2) - # # => "Fixnum[to_f:1.0], Fixnum[to_f:2.0], ... (8 more)" - def self.identify(obj, *args) - new(obj, *args).to_s + # # => "Integer[to_f:1.0], Integer[to_f:2.0], ... (8 more)" + def self.identify(object, *args) + new(object, *args).to_s + end + + def initialize(objects, *args, limit: nil, klass: :not_given) + @objects = Array(objects) + @attributes = args.empty? ? [:id] : args + @limit = (limit || @objects.size).to_i + @klass = klass end # Output the self-identifying string for an instance of @@ -48,85 +52,81 @@ def self.identify(obj, *args) # # @return [String] a string representing the object or list of objects def to_s - if multiple_objects_to_identify? + if many? format_multiple_objects else format_single_object end end - private + private def format_multiple_objects - objects = @objects.first(limit).map do |obj| - format_with_attributes(obj) - end.join(", ") + objects = + @objects.first(@limit).map { |obj| format(obj) } - if any_objects_abbreviated? - objects << ", ... (#{number_of_abbreviated_objects} more)" + if truncated? + objects << "... (#{truncated_objects_count} more)" end - objects + objects.join(", ") end def format_single_object - obj = if nil_or_empty_array?(@objects) - @objects - else - @objects.first - end - format_with_attributes(obj) - end + object = @objects.first if @objects.respond_to?(:first) - def multiple_objects_to_identify? - @objects.many? + format(object) end - def limit - @options.fetch(:limit) { @objects.size }.to_i + def format(object) + return NO_OBJECTS_INDICATOR if blank?(object) + + "#{class_name(object)}[#{format_attributes(evaluate_attributes(object))}]" end - def limit_given? - @options.key?(:limit) + def format_attributes(attributes_hash) + return if attributes_hash.empty? + + attributes_hash.map { |(key, value)| + "#{key}:#{value.inspect_lit}" + }.join(", ") end - def any_objects_abbreviated? - limit_given? && number_of_abbreviated_objects > 0 + # @return [Hash] + def evaluate_attributes(object) + @attributes.each_with_object({}) { |key, acc| + if object.respond_to?(key, :include_private) + acc[key] = object.send(key) + end + } end - def number_of_abbreviated_objects - @objects.size - @options[:limit].to_i + def class_name(object) + klass_given? ? @klass : object.class.name end - def format_with_attributes(object) - if nil_or_empty_array?(object) - format_empty(object) - else - attrs = @attributes.each_with_object({}) do |key, memo| - memo[key] = object.send(key) if object.respond_to?(key, :include_all) - end - "#{class_name_of(object)}[#{attribute_formatter(attrs)}]" - end + def truncated_objects_count + objects_count - @limit end - def format_empty(object) - @options.key?(:klass) ? "#{@options[:klass]}[]" : "[no objects]" + def objects_count + @objects_count ||= @objects.size end - def attribute_formatter(hash) - return if hash.empty? + def klass_given? + @klass != :not_given + end - hash.inject([]) do |memo, (key, value)| - memo << "#{key}:#{value.inspect_lit}" - end.join(", ") + def blank?(object) + object.nil? || object == [] || object == {} end - def nil_or_empty_array?(object) - object.nil? || object == [] + def many? + objects_count > 1 end - def class_name_of(object) - @options.fetch(:klass) { object.class.name } + def truncated? + truncated_objects_count > 0 end end end diff --git a/lib/object_identifier/version.rb b/lib/object_identifier/version.rb index 633ad5c..72ec7a4 100644 --- a/lib/object_identifier/version.rb +++ b/lib/object_identifier/version.rb @@ -1,3 +1,3 @@ module ObjectIdentifier - VERSION = "0.0.6" + VERSION = "0.1.0" end diff --git a/object_identifier.gemspec b/object_identifier.gemspec index 0cfdf0a..9c8f312 100644 --- a/object_identifier.gemspec +++ b/object_identifier.gemspec @@ -1,23 +1,40 @@ -$:.push File.expand_path("../lib", __FILE__) - -# Maintain your gem's version: +lib = File.expand_path("../lib", __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require "object_identifier/version" -# Describe your gem and declare its dependencies: -Gem::Specification.new do |s| - s.name = "object_identifier" - s.version = ObjectIdentifier::VERSION - s.authors = ["Paul Dobbins", "Evan Sherwood"] - s.email = ["pdobbins@gmail.com"] - s.homepage = "https://github.com/pdobb/object_identifier" - s.summary = "Identify an object by inspecting its class name and attributes." - s.license = "MIT" +Gem::Specification.new do |spec| + spec.name = "object_identifier" + spec.version = ObjectIdentifier::VERSION + spec.authors = ["Paul Dobbins", "Evan Sherwood"] + spec.email = ["paul.dobbins@icloud.com"] + + spec.summary = %q{ObjectIdentifier identifies an object by its class name and attributes.} + spec.description = %q{Object Identifier allows quick, easy, and uniform identification of an object by inspecting its class name and outputting any desirable attributes/methods. It is great for quickly logging, sending descriptive notification messages, etc.} + spec.homepage = "https://github.com/pdobb/object_identifier" + spec.license = "MIT" - s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"] - s.test_files = Dir["test/**/*"] + # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host' + # to allow pushing to a single host or delete this section to allow pushing to any host. + # if spec.respond_to?(:metadata) + # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'" + # else + # raise "RubyGems 2.0 or newer is required to protect against " \ + # "public gem pushes." + # end - s.add_dependency "rails", ">= 3.0.0" + spec.files = `git ls-files -z`.split("\x0").reject do |f| + f.match(%r{^(test|spec|features)/}) + end + spec.bindir = "exe" + spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } + spec.require_paths = ["lib"] - s.add_development_dependency "sqlite3" - s.add_development_dependency "minitest-rails" + spec.add_development_dependency "bundler", "~> 1.16" + spec.add_development_dependency "rake", "~> 10.0" + spec.add_development_dependency "minitest", "~> 5.0" + spec.add_development_dependency "minitest-reporters", "~> 1.2" + spec.add_development_dependency "simplecov", "~> 0.16" + spec.add_development_dependency "byebug", "~> 10.0" + spec.add_development_dependency "pry", "~> 0.11" + spec.add_development_dependency "pry-byebug", "~> 3.6" end diff --git a/test/dummy/README.rdoc b/test/dummy/README.rdoc deleted file mode 100644 index dd4e97e..0000000 --- a/test/dummy/README.rdoc +++ /dev/null @@ -1,28 +0,0 @@ -== README - -This README would normally document whatever steps are necessary to get the -application up and running. - -Things you may want to cover: - -* Ruby version - -* System dependencies - -* Configuration - -* Database creation - -* Database initialization - -* How to run the test suite - -* Services (job queues, cache servers, search engines, etc.) - -* Deployment instructions - -* ... - - -Please feel free to use a different markup language if you do not plan to run -rake doc:app. diff --git a/test/dummy/Rakefile b/test/dummy/Rakefile deleted file mode 100644 index 4135d7a..0000000 --- a/test/dummy/Rakefile +++ /dev/null @@ -1,6 +0,0 @@ -# Add your own tasks in files placed in lib/tasks ending in .rake, -# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. - -require File.expand_path('../config/application', __FILE__) - -Dummy::Application.load_tasks diff --git a/test/dummy/app/assets/images/.keep b/test/dummy/app/assets/images/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/test/dummy/app/assets/javascripts/application.js b/test/dummy/app/assets/javascripts/application.js deleted file mode 100644 index 5bc2e1c..0000000 --- a/test/dummy/app/assets/javascripts/application.js +++ /dev/null @@ -1,13 +0,0 @@ -// This is a manifest file that'll be compiled into application.js, which will include all the files -// listed below. -// -// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, -// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. -// -// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the -// compiled file. -// -// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details -// about supported directives. -// -//= require_tree . diff --git a/test/dummy/app/assets/stylesheets/application.css b/test/dummy/app/assets/stylesheets/application.css deleted file mode 100644 index 3192ec8..0000000 --- a/test/dummy/app/assets/stylesheets/application.css +++ /dev/null @@ -1,13 +0,0 @@ -/* - * This is a manifest file that'll be compiled into application.css, which will include all the files - * listed below. - * - * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, - * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. - * - * You're free to add application-wide styles to this file and they'll appear at the top of the - * compiled file, but it's generally better to create a new file per style scope. - * - *= require_self - *= require_tree . - */ diff --git a/test/dummy/app/controllers/application_controller.rb b/test/dummy/app/controllers/application_controller.rb deleted file mode 100644 index d83690e..0000000 --- a/test/dummy/app/controllers/application_controller.rb +++ /dev/null @@ -1,5 +0,0 @@ -class ApplicationController < ActionController::Base - # Prevent CSRF attacks by raising an exception. - # For APIs, you may want to use :null_session instead. - protect_from_forgery with: :exception -end diff --git a/test/dummy/app/controllers/concerns/.keep b/test/dummy/app/controllers/concerns/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/test/dummy/app/helpers/application_helper.rb b/test/dummy/app/helpers/application_helper.rb deleted file mode 100644 index de6be79..0000000 --- a/test/dummy/app/helpers/application_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module ApplicationHelper -end diff --git a/test/dummy/app/mailers/.keep b/test/dummy/app/mailers/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/test/dummy/app/models/.keep b/test/dummy/app/models/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/test/dummy/app/models/concerns/.keep b/test/dummy/app/models/concerns/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/test/dummy/app/views/layouts/application.html.erb b/test/dummy/app/views/layouts/application.html.erb deleted file mode 100644 index 670d187..0000000 --- a/test/dummy/app/views/layouts/application.html.erb +++ /dev/null @@ -1,14 +0,0 @@ - - - - Dummy - <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> - <%= javascript_include_tag "application", "data-turbolinks-track" => true %> - <%= csrf_meta_tags %> - - - -<%= yield %> - - - diff --git a/test/dummy/bin/bundle b/test/dummy/bin/bundle deleted file mode 100755 index 66e9889..0000000 --- a/test/dummy/bin/bundle +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env ruby -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) -load Gem.bin_path('bundler', 'bundle') diff --git a/test/dummy/bin/rails b/test/dummy/bin/rails deleted file mode 100755 index 728cd85..0000000 --- a/test/dummy/bin/rails +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env ruby -APP_PATH = File.expand_path('../../config/application', __FILE__) -require_relative '../config/boot' -require 'rails/commands' diff --git a/test/dummy/bin/rake b/test/dummy/bin/rake deleted file mode 100755 index 1724048..0000000 --- a/test/dummy/bin/rake +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env ruby -require_relative '../config/boot' -require 'rake' -Rake.application.run diff --git a/test/dummy/config.ru b/test/dummy/config.ru deleted file mode 100644 index 5bc2a61..0000000 --- a/test/dummy/config.ru +++ /dev/null @@ -1,4 +0,0 @@ -# This file is used by Rack-based servers to start the application. - -require ::File.expand_path('../config/environment', __FILE__) -run Rails.application diff --git a/test/dummy/config/application.rb b/test/dummy/config/application.rb deleted file mode 100644 index 1d6f5fa..0000000 --- a/test/dummy/config/application.rb +++ /dev/null @@ -1,23 +0,0 @@ -require File.expand_path('../boot', __FILE__) - -require 'rails/all' - -Bundler.require(*Rails.groups) -require "object_identifier" - -module Dummy - class Application < Rails::Application - # Settings in config/environments/* take precedence over those specified here. - # Application configuration should go into files in config/initializers - # -- all .rb files in that directory are automatically loaded. - - # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. - # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. - # config.time_zone = 'Central Time (US & Canada)' - - # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. - # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] - # config.i18n.default_locale = :de - end -end - diff --git a/test/dummy/config/boot.rb b/test/dummy/config/boot.rb deleted file mode 100644 index ef36047..0000000 --- a/test/dummy/config/boot.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Set up gems listed in the Gemfile. -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__) - -require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) -$LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__) diff --git a/test/dummy/config/database.yml b/test/dummy/config/database.yml deleted file mode 100644 index 51a4dd4..0000000 --- a/test/dummy/config/database.yml +++ /dev/null @@ -1,25 +0,0 @@ -# SQLite version 3.x -# gem install sqlite3 -# -# Ensure the SQLite 3 gem is defined in your Gemfile -# gem 'sqlite3' -development: - adapter: sqlite3 - database: db/development.sqlite3 - pool: 5 - timeout: 5000 - -# Warning: The database defined as "test" will be erased and -# re-generated from your development database when you run "rake". -# Do not set this db to the same as development or production. -test: - adapter: sqlite3 - database: db/test.sqlite3 - pool: 5 - timeout: 5000 - -production: - adapter: sqlite3 - database: db/production.sqlite3 - pool: 5 - timeout: 5000 diff --git a/test/dummy/config/environment.rb b/test/dummy/config/environment.rb deleted file mode 100644 index 10e0cad..0000000 --- a/test/dummy/config/environment.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Load the Rails application. -require File.expand_path('../application', __FILE__) - -# Initialize the Rails application. -Dummy::Application.initialize! diff --git a/test/dummy/config/environments/development.rb b/test/dummy/config/environments/development.rb deleted file mode 100644 index 9d26e12..0000000 --- a/test/dummy/config/environments/development.rb +++ /dev/null @@ -1,29 +0,0 @@ -Dummy::Application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # In the development environment your application's code is reloaded on - # every request. This slows down response time but is perfect for development - # since you don't have to restart the web server when you make code changes. - config.cache_classes = false - - # Do not eager load code on boot. - config.eager_load = false - - # Show full error reports and disable caching. - config.consider_all_requests_local = true - config.action_controller.perform_caching = false - - # Don't care if the mailer can't send. - config.action_mailer.raise_delivery_errors = false - - # Print deprecation notices to the Rails logger. - config.active_support.deprecation = :log - - # Raise an error on page load if there are pending migrations - config.active_record.migration_error = :page_load - - # Debug mode disables concatenation and preprocessing of assets. - # This option may cause significant delays in view rendering with a large - # number of complex assets. - config.assets.debug = true -end diff --git a/test/dummy/config/environments/production.rb b/test/dummy/config/environments/production.rb deleted file mode 100644 index b690b1c..0000000 --- a/test/dummy/config/environments/production.rb +++ /dev/null @@ -1,80 +0,0 @@ -Dummy::Application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # Code is not reloaded between requests. - config.cache_classes = true - - # Eager load code on boot. This eager loads most of Rails and - # your application in memory, allowing both thread web servers - # and those relying on copy on write to perform better. - # Rake tasks automatically ignore this option for performance. - config.eager_load = true - - # Full error reports are disabled and caching is turned on. - config.consider_all_requests_local = false - config.action_controller.perform_caching = true - - # Enable Rack::Cache to put a simple HTTP cache in front of your application - # Add `rack-cache` to your Gemfile before enabling this. - # For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid. - # config.action_dispatch.rack_cache = true - - # Disable Rails's static asset server (Apache or nginx will already do this). - config.serve_static_assets = false - - # Compress JavaScripts and CSS. - config.assets.js_compressor = :uglifier - # config.assets.css_compressor = :sass - - # Do not fallback to assets pipeline if a precompiled asset is missed. - config.assets.compile = false - - # Generate digests for assets URLs. - config.assets.digest = true - - # Version of your assets, change this if you want to expire all your assets. - config.assets.version = '1.0' - - # Specifies the header that your server uses for sending files. - # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache - # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx - - # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. - # config.force_ssl = true - - # Set to :debug to see everything in the log. - config.log_level = :info - - # Prepend all log lines with the following tags. - # config.log_tags = [ :subdomain, :uuid ] - - # Use a different logger for distributed setups. - # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) - - # Use a different cache store in production. - # config.cache_store = :mem_cache_store - - # Enable serving of images, stylesheets, and JavaScripts from an asset server. - # config.action_controller.asset_host = "http://assets.example.com" - - # Precompile additional assets. - # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. - # config.assets.precompile += %w( search.js ) - - # Ignore bad email addresses and do not raise email delivery errors. - # Set this to true and configure the email server for immediate delivery to raise delivery errors. - # config.action_mailer.raise_delivery_errors = false - - # Enable locale fallbacks for I18n (makes lookups for any locale fall back to - # the I18n.default_locale when a translation can not be found). - config.i18n.fallbacks = true - - # Send deprecation notices to registered listeners. - config.active_support.deprecation = :notify - - # Disable automatic flushing of the log to improve performance. - # config.autoflush_log = false - - # Use default logging formatter so that PID and timestamp are not suppressed. - config.log_formatter = ::Logger::Formatter.new -end diff --git a/test/dummy/config/environments/test.rb b/test/dummy/config/environments/test.rb deleted file mode 100644 index afbc0ae..0000000 --- a/test/dummy/config/environments/test.rb +++ /dev/null @@ -1,36 +0,0 @@ -Dummy::Application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # The test environment is used exclusively to run your application's - # test suite. You never need to work with it otherwise. Remember that - # your test database is "scratch space" for the test suite and is wiped - # and recreated between test runs. Don't rely on the data there! - config.cache_classes = true - - # Do not eager load code on boot. This avoids loading your whole application - # just for the purpose of running a single test. If you are using a tool that - # preloads Rails for running tests, you may have to set it to true. - config.eager_load = false - - # Configure static asset server for tests with Cache-Control for performance. - config.serve_static_assets = true - config.static_cache_control = "public, max-age=3600" - - # Show full error reports and disable caching. - config.consider_all_requests_local = true - config.action_controller.perform_caching = false - - # Raise exceptions instead of rendering exception templates. - config.action_dispatch.show_exceptions = false - - # Disable request forgery protection in test environment. - config.action_controller.allow_forgery_protection = false - - # Tell Action Mailer not to deliver emails to the real world. - # The :test delivery method accumulates sent emails in the - # ActionMailer::Base.deliveries array. - config.action_mailer.delivery_method = :test - - # Print deprecation notices to the stderr. - config.active_support.deprecation = :stderr -end diff --git a/test/dummy/config/initializers/backtrace_silencers.rb b/test/dummy/config/initializers/backtrace_silencers.rb deleted file mode 100644 index 59385cd..0000000 --- a/test/dummy/config/initializers/backtrace_silencers.rb +++ /dev/null @@ -1,7 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. -# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } - -# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. -# Rails.backtrace_cleaner.remove_silencers! diff --git a/test/dummy/config/initializers/filter_parameter_logging.rb b/test/dummy/config/initializers/filter_parameter_logging.rb deleted file mode 100644 index 4a994e1..0000000 --- a/test/dummy/config/initializers/filter_parameter_logging.rb +++ /dev/null @@ -1,4 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Configure sensitive parameters which will be filtered from the log file. -Rails.application.config.filter_parameters += [:password] diff --git a/test/dummy/config/initializers/inflections.rb b/test/dummy/config/initializers/inflections.rb deleted file mode 100644 index ac033bf..0000000 --- a/test/dummy/config/initializers/inflections.rb +++ /dev/null @@ -1,16 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Add new inflection rules using the following format. Inflections -# are locale specific, and you may define rules for as many different -# locales as you wish. All of these examples are active by default: -# ActiveSupport::Inflector.inflections(:en) do |inflect| -# inflect.plural /^(ox)$/i, '\1en' -# inflect.singular /^(ox)en/i, '\1' -# inflect.irregular 'person', 'people' -# inflect.uncountable %w( fish sheep ) -# end - -# These inflection rules are supported but not enabled by default: -# ActiveSupport::Inflector.inflections(:en) do |inflect| -# inflect.acronym 'RESTful' -# end diff --git a/test/dummy/config/initializers/mime_types.rb b/test/dummy/config/initializers/mime_types.rb deleted file mode 100644 index 72aca7e..0000000 --- a/test/dummy/config/initializers/mime_types.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Add new mime types for use in respond_to blocks: -# Mime::Type.register "text/richtext", :rtf -# Mime::Type.register_alias "text/html", :iphone diff --git a/test/dummy/config/initializers/secret_token.rb b/test/dummy/config/initializers/secret_token.rb deleted file mode 100644 index 3b3b1fa..0000000 --- a/test/dummy/config/initializers/secret_token.rb +++ /dev/null @@ -1,12 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Your secret key is used for verifying the integrity of signed cookies. -# If you change this key, all old signed cookies will become invalid! - -# Make sure the secret is at least 30 characters and all random, -# no regular words or you'll be exposed to dictionary attacks. -# You can use `rake secret` to generate a secure secret key. - -# Make sure your secret_key_base is kept private -# if you're sharing your code publicly. -Dummy::Application.config.secret_key_base = '5e0344d05a5e2d3dc180c35474f7098452b324ae921da07878dcfcc221fc7b925948ab879b225db8c9f06a02ca5039c385c4f4ebbdbabaf85eb06345e7a84a2e' diff --git a/test/dummy/config/initializers/session_store.rb b/test/dummy/config/initializers/session_store.rb deleted file mode 100644 index 155f7b0..0000000 --- a/test/dummy/config/initializers/session_store.rb +++ /dev/null @@ -1,3 +0,0 @@ -# Be sure to restart your server when you modify this file. - -Dummy::Application.config.session_store :cookie_store, key: '_dummy_session' diff --git a/test/dummy/config/initializers/wrap_parameters.rb b/test/dummy/config/initializers/wrap_parameters.rb deleted file mode 100644 index 33725e9..0000000 --- a/test/dummy/config/initializers/wrap_parameters.rb +++ /dev/null @@ -1,14 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# This file contains settings for ActionController::ParamsWrapper which -# is enabled by default. - -# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. -ActiveSupport.on_load(:action_controller) do - wrap_parameters format: [:json] if respond_to?(:wrap_parameters) -end - -# To enable root element in JSON for ActiveRecord objects. -# ActiveSupport.on_load(:active_record) do -# self.include_root_in_json = true -# end diff --git a/test/dummy/config/locales/en.yml b/test/dummy/config/locales/en.yml deleted file mode 100644 index 0653957..0000000 --- a/test/dummy/config/locales/en.yml +++ /dev/null @@ -1,23 +0,0 @@ -# Files in the config/locales directory are used for internationalization -# and are automatically loaded by Rails. If you want to use locales other -# than English, add the necessary files in this directory. -# -# To use the locales, use `I18n.t`: -# -# I18n.t 'hello' -# -# In views, this is aliased to just `t`: -# -# <%= t('hello') %> -# -# To use a different locale, set it with `I18n.locale`: -# -# I18n.locale = :es -# -# This would use the information in config/locales/es.yml. -# -# To learn more, please read the Rails Internationalization guide -# available at http://guides.rubyonrails.org/i18n.html. - -en: - hello: "Hello world" diff --git a/test/dummy/config/routes.rb b/test/dummy/config/routes.rb deleted file mode 100644 index 268779b..0000000 --- a/test/dummy/config/routes.rb +++ /dev/null @@ -1,56 +0,0 @@ -Dummy::Application.routes.draw do - # The priority is based upon order of creation: first created -> highest priority. - # See how all your routes lay out with "rake routes". - - # You can have the root of your site routed with "root" - # root 'welcome#index' - - # Example of regular route: - # get 'products/:id' => 'catalog#view' - - # Example of named route that can be invoked with purchase_url(id: product.id) - # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase - - # Example resource route (maps HTTP verbs to controller actions automatically): - # resources :products - - # Example resource route with options: - # resources :products do - # member do - # get 'short' - # post 'toggle' - # end - # - # collection do - # get 'sold' - # end - # end - - # Example resource route with sub-resources: - # resources :products do - # resources :comments, :sales - # resource :seller - # end - - # Example resource route with more complex sub-resources: - # resources :products do - # resources :comments - # resources :sales do - # get 'recent', on: :collection - # end - # end - - # Example resource route with concerns: - # concern :toggleable do - # post 'toggle' - # end - # resources :posts, concerns: :toggleable - # resources :photos, concerns: :toggleable - - # Example resource route within a namespace: - # namespace :admin do - # # Directs /admin/products/* to Admin::ProductsController - # # (app/controllers/admin/products_controller.rb) - # resources :products - # end -end diff --git a/test/dummy/lib/assets/.keep b/test/dummy/lib/assets/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/test/dummy/log/.keep b/test/dummy/log/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/test/dummy/public/404.html b/test/dummy/public/404.html deleted file mode 100644 index a0daa0c..0000000 --- a/test/dummy/public/404.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - The page you were looking for doesn't exist (404) - - - - - -
-

The page you were looking for doesn't exist.

-

You may have mistyped the address or the page may have moved.

-
-

If you are the application owner check the logs for more information.

- - diff --git a/test/dummy/public/422.html b/test/dummy/public/422.html deleted file mode 100644 index fbb4b84..0000000 --- a/test/dummy/public/422.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - The change you wanted was rejected (422) - - - - - -
-

The change you wanted was rejected.

-

Maybe you tried to change something you didn't have access to.

-
-

If you are the application owner check the logs for more information.

- - diff --git a/test/dummy/public/500.html b/test/dummy/public/500.html deleted file mode 100644 index e9052d3..0000000 --- a/test/dummy/public/500.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - We're sorry, but something went wrong (500) - - - - - -
-

We're sorry, but something went wrong.

-
-

If you are the application owner check the logs for more information.

- - diff --git a/test/dummy/public/favicon.ico b/test/dummy/public/favicon.ico deleted file mode 100644 index e69de29..0000000 diff --git a/test/object_identifier_test.rb b/test/object_identifier_test.rb index 1953c4f..27436c0 100644 --- a/test/object_identifier_test.rb +++ b/test/object_identifier_test.rb @@ -1,69 +1,115 @@ require "test_helper" -describe ObjectIdentifier::Identifier do - describe "#identify" do - it "yields 'Class[id:1]', GIVEN id and no attributes" do - OpenStruct.new(id: 1).identify.must_equal "OpenStruct[id:1]" - end +class ObjectIdentifier::IdentifierTest < Minitest::Spec + describe ObjectIdentifier::Identifier do + describe "#identify" do + context "GIVEN a single object" do + it "returns attribute values" do + subject = OpenStruct.new(name: "Pepper", beak_size: 4) + subject.identify(:beak_size).must_equal "OpenStruct[beak_size:4]" + end - it "lists each entry in collection" do - collection = [OpenStruct.new(id: 1), OpenStruct.new(id: 2)] - collection.identify.must_equal "OpenStruct[id:1], OpenStruct[id:2]" - end + it "quotes strings in attributes" do + subject = OpenStruct.new(name: "Pepper") + subject.identify(:name).must_equal %(OpenStruct[name:"Pepper"]) + end - describe "no attributes, no id, empty array, nil" do - it "yields 'Class[]', GIVEN no id or attributes" do - Object.new.identify.must_equal "Object[]" - end + it "quotes symbols in attributes" do + subject = OpenStruct.new(name: "Pepper", color: :grey) + subject.identify(:color).must_equal %(OpenStruct[color::"grey"]) + end - it "yields '[no objects]', GIVEN an empty array" do - [].identify.must_equal "[no objects]" - end + it "ignores attributes that don't exist" do + subject = OpenStruct.new(name: "Pepper", color: :grey, beak_size: 4) + subject.identify(:volume, :beak_size). + must_equal "OpenStruct[beak_size:4]" + end - it "yields '[no objects]', GIVEN nil" do - nil.identify.must_equal "[no objects]" - end - end + it "returns '[no objects]', GIVEN nil" do + subject = nil + subject.identify.must_equal "[no objects]" + end - describe "with attributes" do - it "yields attribute values" do - obj = OpenStruct.new(name: "Pepper", beak_size: 4) - obj.identify(:beak_size).must_equal "OpenStruct[beak_size:4]" - end + context "GIVEN object responds to :id" do + subject { OpenStruct.new(id: 1) } - it "quotes strings" do - obj = OpenStruct.new(name: "Pepper") - obj.identify(:name).must_equal %(OpenStruct[name:"Pepper"]) - end + it "returns 'Class[id:1]', GIVEN no other attributes" do + subject.identify.must_equal "OpenStruct[id:1]" + end + end - it "quotes symbols" do - obj = OpenStruct.new(name: "Pepper", color: :grey) - obj.identify(:color).must_equal %(OpenStruct[color::"grey"]) - end + context "GIVEN object does not respond to :id" do + subject { Object.new } - it "ignores attributes that don't exist" do - obj = OpenStruct.new(name: "Pepper", color: :grey, beak_size: 4) - obj.identify(:volume, :beak_size).must_equal "OpenStruct[beak_size:4]" - end - end + it "returns '[]', GIVEN no attributes" do + subject.identify.must_equal "Object[]" + end + end - describe "options" do - it "overrides object class name with :klass" do - OpenStruct.new(id: 1).identify(klass: "Monkey").must_equal "Monkey[id:1]" - end + context "GIVEN a :klass" do + subject { OpenStruct.new(id: 1) } - it "yields no class, GIVEN class is empty string" do - OpenStruct.new(id: 1).identify(klass: "").must_equal "[id:1]" - OpenStruct.new(id: 1).identify(klass: nil).must_equal "[id:1]" - end + it "overrides object class name" do + subject.identify(klass: "Bird").must_equal "Bird[id:1]" + end + + it "returns no class, GIVEN :klass is nil" do + subject.identify(klass: nil).must_equal "[id:1]" + end + + it "returns no class, GIVEN :klass is empty string" do + subject.identify(klass: "").must_equal "[id:1]" + end + end - it "overrides object class name with :klass with no attributes" do - [].identify(klass: "Monkey").must_equal "Monkey[]" + context "GIVEN a :limit" do + subject { OpenStruct.new(id: 1) } + + it "ignores :limit" do + subject.identify(:id, limit: 3).must_equal "OpenStruct[id:1]" + end + end end - it "yields first n (:limit) objects in collection" do - (1..7).to_a.identify(:to_i, limit: 3).must_equal( - "Fixnum[to_i:1], Fixnum[to_i:2], Fixnum[to_i:3], ... (4 more)") + context "GIVEN a collection of objects" do + it "identifies each object in turn" do + subject = [OpenStruct.new(id: 1), OpenStruct.new(id: 2)] + subject.identify.must_equal "OpenStruct[id:1], OpenStruct[id:2]" + end + + it "returns '[no objects]', GIVEN an empty Array" do + subject = [] + subject.identify.must_equal "[no objects]" + end + + it "returns '[no objects]', GIVEN an empty Hash" do + subject = {} + subject.identify.must_equal "[no objects]" + end + + context "GIVEN a :klass" do + subject { [OpenStruct.new(id: 1), Object.new] } + + it "overrides object class name for all objects" do + subject.identify(klass: "Bird").must_equal "Bird[id:1], Bird[]" + end + + it "returns no class, GIVEN :klass is nil" do + subject.identify(klass: nil).must_equal "[id:1], []" + end + + it "returns no class, GIVEN :klass is empty string" do + subject.identify(klass: "").must_equal "[id:1], []" + end + end + + context "GIVEN a :limit" do + it "returns truncated list, GIVEN :limit" do + subject = "abcdefg".chars + subject.identify(:upcase, limit: 3).must_equal( + "String[upcase:\"A\"], String[upcase:\"B\"], String[upcase:\"C\"], ... (4 more)") + end + end end end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 9fa4988..472bf53 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,15 +1,21 @@ -ENV["RAILS_ENV"] = "test" +require "simplecov" +SimpleCov.start do + add_filter "/bin/" + add_filter "/test/" +end +puts "SimpleCov enabled." -require File.expand_path("../dummy/config/environment.rb", __FILE__) -require "rails/test_help" -require "minitest/rails" +$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__) +require "object_identifier" -Rails.backtrace_cleaner.remove_silencers! +require "minitest/autorun" +require "minitest/reporters" +require "pry" -# Load support files -Dir[Rails.root.join("test/support/**/*.rb")].each { |f| require f } +Minitest::Test.make_my_diffs_pretty! +reporter_options = { color: true } +Minitest::Reporters.use! Minitest::Reporters::DefaultReporter.new(reporter_options) -# Load fixtures from the engine -if ActiveSupport::TestCase.method_defined?(:fixture_path=) - ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__) +def context(*args, &block) + describe(*args, &block) end