[
  {
    "path": ".github/code-scanning.yml",
    "content": "paths-ignore:\n  - test/**\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "content": "name: Test\n\npermissions:\n  contents: read\non:\n  push:\n    branches:\n      - main\n  pull_request:\n  workflow_dispatch:\njobs:\n  test:\n    strategy:\n      fail-fast: false\n      matrix:\n        gemfile:\n          - Gemfile\n          - gemfiles/Gemfile-rails-main\n          - gemfiles/Gemfile-rails-8-0\n          - gemfiles/Gemfile-rails-7-2\n          - gemfiles/Gemfile-rails-7-1\n          - gemfiles/Gemfile-rails-7-0\n        ruby:\n          - '4.0'\n          - '3.4'\n          - '3.3'\n          - '3.2'\n          - '3.1'\n          - '3.0'\n          - '2.7'\n        exclude:\n          - gemfile: Gemfile\n            ruby: '3.1'\n          - gemfile: Gemfile\n            ruby: '3.0'\n          - gemfile: Gemfile\n            ruby: '2.7'\n          - gemfile: gemfiles/Gemfile-rails-main\n            ruby: '3.2'\n          - gemfile: gemfiles/Gemfile-rails-main\n            ruby: '3.1'\n          - gemfile: gemfiles/Gemfile-rails-main\n            ruby: '3.0'\n          - gemfile: gemfiles/Gemfile-rails-main\n            ruby: '2.7'\n          - gemfile: gemfiles/Gemfile-rails-8-0\n            ruby: '3.1'\n          - gemfile: gemfiles/Gemfile-rails-8-0\n            ruby: '3.0'\n          - gemfile: gemfiles/Gemfile-rails-8-0\n            ruby: '2.7'\n          - gemfile: gemfiles/Gemfile-rails-7-2\n            ruby: '3.0'\n          - gemfile: gemfiles/Gemfile-rails-7-2\n            ruby: '2.7'\n    runs-on: ubuntu-latest\n    env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps\n      BUNDLE_GEMFILE: ${{ matrix.gemfile }}\n    steps:\n      - uses: actions/checkout@v4\n      - uses: ruby/setup-ruby@v1\n        with:\n          ruby-version: ${{ matrix.ruby }}\n          bundler-cache: true # runs bundle install and caches installed gems automatically\n      - run: bundle exec rake\n"
  },
  {
    "path": ".gitignore",
    "content": ".bundle/\npkg/\ngemfiles/*.lock\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "## Unreleased\n\n* Ruby 4.0 support (no changes required)\n\n## 0.9.0\n\n* Add support for Ruby 3.3/3.4 and Rails 7.2/8.0/8.1. (no changes required)\n* Drop support for Rails < 7 and Ruby < 2.7.\n\n## 0.8.1\n\n* Add support for Rails 7.0/7.1 and Ruby 3.1/3.2 (no changes required)\n* Remove test files from the gem package.\n\n## 0.8.0\n\n* Respect `nil` value when provided, by skipping model attribute value.\n* Add support for Ruby 3.0, drop support for Ruby < 2.5.\n* Add support for Rails 6.1, drop support for Rails < 5.2.\n* Move CI to GitHub Actions.\n\n## 0.7.0\n\n* Add support for Rails 6.0.\n* Drop support for Rails < 5.0 and Ruby < 2.4.\n\n## 0.6.1\n\n* Add support for Rails 5.2.\n*  Fix issue causing blank class not being applied to field wrapper when the result of a Proc is empty.\n\n## 0.6.0\n\n* Relaxed dependencies to support Rails 5.1.\n\n## 0.5.0\n\n* Relaxed dependencies to support Rails 5.\n* Removed support for Rails `3.2` and `4.0` and Ruby `1.9.3` and `2.0.0`.\n\n### enhancements\n  * Do not generate label/content/wrapper/collection classes when config is set to `nil`.\n\n## 0.4.0\n\n### enhancements\n  * Change default `wrapper_tag` to generate a `div` instead of `p`. The `p` tag generates\n    invalid HTML with collections: `p > ul`, and failed tests on Rails 4.2. If you depend\n    on the `p` tag being generated, change your Show For config to set `wrapper_tag` to `:p`.\n  * Remove deprecated `:method` in favor of `:using`.\n  * Improve support to Rails 4.x associations with more duck typing instead of Array checks.\n  * Support Rails 4.1/4.2 and Ruby 2.1/2.2.\n  * Add `skip_blanks` configuration option to skip generating blank attributes\n    instead of generating them with a default message. (by github.com/moktin)\n  * Add `slim` template for the install generator. (by github.com/voanhduy1512)\n  * Add `separator` option that overrides the global configuration (by github.com/bernardofire)\n\n### bugfix\n  * Do not yield default blank value to the block when using an empty association. (by github.com/aptinio)\n\n## 0.3.0\n\n### bug fix\n  * Fix blank value not being applied when using a block. (by github.com/tfwright)\n\n## 0.3.0.rc\n\n### enhancements\n  * Support Rails 4.\n  * Drop support to Rails < 3.2 and Ruby 1.8.\n\n## 0.2.6\n\n### enhancements\n  * Ruby 2.0 support.\n  * Add Haml template. (by github.com/nashby) Closes #12.\n  * Add `blank_html` tanslation. (by github.com/nashby)\n  * Add `show_for_class` configuration option. (by github.com/nashby)\n\n### bug fix\n  * Make show_for works with namespaced models. (by github.com/fabiokr)\n  * Add `blank_content_class` to the attributes. (by github.com/blakehilscher). Closes #24.\n  * Don't call `association.map` if association method is nil (by github.com/nashby). Closes #40.\n\n## 0.2.5\n\n### enhancements\n  * Add a `:value` option for attribute (by github.com/ml-gt)\n  * Add `label_class`, `content_class`, `wrapper_class` and `collection_class` configuration options (by github.com/wojtekmach)\n\n### bug fix\n  * Fix problem with `label => false` and `html_safe` (label => false) (by github.com/nashby)\n\n## 0.2.4\n\n### enhancements\n  * Do not add separator if label is not present (by github.com/eugenebolshakov)\n  * Add method for output value only (by github.com/jenkek)\n\n### bug fix\n  * Fix empty labels to be `html_safe` (label => false) (by github.com/eugenebolshakov)\n\n## 0.2.3\n\n### enhancements\n  * added :attributes method to generate all attributes given\n  * update generator to use the new syntax show_for:install\n\n### bug fix\n  * fix numeric types\n\n## 0.2.2\n\n### bug fix\n  * allow show_for to work with AR association proxies\n\n### enhancements\n  * improvements on html safe and output buffers\n\n## 0.2.1\n\n### enhancements\n  * added label_proc\n  * compatibility with latest Rails\n\n## 0.2.0\n\n### enhancements\n  * Rails 3 compatibility\n\n## 0.1.4\n\n### bug fix\n  * allow show_for to work with AR association proxies\n\n## 0.1.3\n\n### enhancements\n  * allow builder to be given to show_for\n\n### bug fix\n  * Fix typo in yaml\n\n## 0.1.2\n\n### enhancements\n  * allow `f.attribute :nickname, in: :profile` as association shortcut\n\n### deprecations\n  * `:method` now becomes `:using`\n\n## 0.1.1\n\n### enhancements\n  * HAML compatibility (by github.com/grimen)\n  * blank_content support (by github.com/grimen)\n\n## 0.1\n\n### First release\n"
  },
  {
    "path": "Gemfile",
    "content": "source 'https://rubygems.org'\n\ngemspec\n\ngem 'railties', '~> 8.1.0'\ngem 'activemodel', '~> 8.1.0'\ngem 'actionpack', '~> 8.1.0'\n"
  },
  {
    "path": "MIT-LICENSE",
    "content": "Copyright (c) 2020-CURRENT Rafael França, Carlos Antonio da Silva\nCopyright (c) 2012-2019 Plataformatec\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# ShowFor\n\n[![Gem Version](https://badge.fury.io/rb/show_for.svg)](https://badge.fury.io/rb/show_for)\n\nShowFor allows you to quickly show a model information with I18n features.\n\n```erb\n<%= show_for @user do |u| %>\n  <%= u.attribute :name %>\n  <%= u.attribute :nickname, in: :profile %>\n  <%= u.attribute :confirmed? %>\n  <%= u.attribute :created_at, format: :short %>\n  <%= u.attribute :last_sign_in_at, if_blank: \"User did not access yet\",\n                  wrapper_html: { id: \"sign_in_timestamp\" } %>\n\n  <%= u.attribute :photo do %>\n    <%= image_tag(@user.photo_url) %>\n  <% end %>\n\n  <%= u.association :company %>\n  <%= u.association :tags, to_sentence: true %>\n<% end %>\n```\n\n## Installation\n\nInstall the gem:\n\n    gem install show_for\n\nOr add ShowFor to your Gemfile and bundle it up:\n\n    gem 'show_for'\n\nRun the generator:\n\n    rails generate show_for:install\n\nAnd you are ready to go.\n\nNote: This branch aims Rails 7 and 8 support, so if you want to use it with\nolder versions of Rails, check out the available branches.\n\n## Usage\n\nShowFor allows you to quickly show a model information with I18n features.\n\n```erb\n<%= show_for @admin do |a| %>\n  <%= a.attribute :name %>\n  <%= a.attribute :login, value: :upcase %>\n  <%= a.attribute :confirmed? %>\n  <%= a.attribute :created_at, format: :short %>\n  <%= a.attribute :last_sign_in_at, if_blank: \"Administrator did not access yet\"\n                  wrapper_html: { id: \"sign_in_timestamp\" } %>\n\n  <%= a.attribute :photo do %>\n    <%= image_tag(@admin.photo_url) %>\n  <% end %>\n\n  <% a.value :biography %>\n<% end %>\n```\n\nWill generate something like:\n\n```html\n<div id=\"admin_1\" class=\"show_for admin\">\n  <div class=\"wrapper admin_name\">\n    <strong class=\"label\">Name</strong><br />\n    José Valim\n  </div>\n  <div class=\"wrapper admin_login\">\n    <strong class=\"label\">Login</strong><br />\n    JVALIM\n  </div>\n  <div class=\"wrapper admin_confirmed\">\n    <strong class=\"label\">Confirmed?</strong><br />\n    Yes\n  </div>\n  <div class=\"wrapper admin_created_at\">\n    <strong class=\"label\">Created at</strong><br />\n    13/12/2009 - 19h17\n  </div>\n  <div id=\"sign_in_timestamp\" class=\"wrapper admin_last_sign_in_at\">\n    <strong class=\"label\">Last sign in at</strong><br />\n    Administrator did not access yet\n  </div>\n  <div class=\"wrapper admin_photo\">\n    <strong class=\"label\">Photo</strong><br />\n    <img src=\"path/to/photo\" />\n  </div>\n  <div class=\"wrapper admin_biography\">\n    Etiam porttitor eros ut diam vestibulum et blandit lectus tempor. Donec\n    venenatis fermentum nunc ac dignissim. Pellentesque volutpat eros quis enim\n    mollis bibendum. Ut cursus sem ac sem accumsan nec porttitor felis luctus.\n    Sed purus nunc, auctor vitae consectetur pharetra, tristique non nisi.\n  </div>\n</div>\n```\n\nYou can also show a list of attributes, useful if you don't need to change any configuration:\n\n```erb\n<%= show_for @admin do |a| %>\n  <%= a.attributes :name, :confirmed?, :created_at %>\n<% end %>\n```\n\n## Value lookup\n\nShowFor uses the following sequence to get the attribute value:\n\n* use the output of a block argument if given\n* use the output of the `:value` argument if given\n* check if a `:\"human_#{attribute}\"` method is defined\n* retrieve the attribute directly.\n\n## Options\n\nShowFor handles a series of options. Those are:\n\n* __:format__ - Sent to `I18n.localize` when the attribute is a date/time object.\n\n* __:value__ - Can be used instead of block. If a `Symbol` is called as instance method.\n\n* __:if_blank__ - An object to be used if the value is blank. Not escaped as well.\n\n* __:separator__ - The piece of html that separates label and content, overriding the global configuration.\n\nIn addition, all containers (`:label`, `:content` and `:wrapper`) can have their html\noptions configured through the `:label_html`, `:content_html` and `:wrapper_html`\noptions. Containers can have their tags configured on demand as well through\n`:label_tag,` `:content_tag` and `:wrapper_tag` options.\n\n## Label\n\nShowFor also exposes the label method. In case you want to use the default\n`human_attribute_name` lookup and the default wrapping:\n\n```ruby\na.label :name                  #=> <strong class=\"label\">Name</strong>\na.label \"Name\", id: \"my_name\"  #=> <strong class=\"label\" id=\"my_name\">Name</strong>\n```\n\nOptionally, if you want to wrap the inner part of the label with some text\n(e.g. adding a semicolon), you can do so by specifying a proc for `ShowFor.label_proc`\nthat will be called with any label text. E.g.:\n\n```ruby\n  ShowFor.label_proc = lambda { |l| l + \":\" }\n```\n\nWhen taking this route, you can also skip on a per label basis by passing the\n`:wrap_label` option with a value of false.\n\n## Associations\n\nShowFor also supports associations.\n\n```erb\n<%= show_for @artwork do |a| %>\n  <%= a.association :artist %>\n  <%= a.association :artist, using: :name_with_title %>\n  <%= a.attribute :name_with_title, in: :artist %>\n\n  <%= a.association :tags %>\n  <%= a.association :tags, to_sentence: true %>\n  <%= a.association :tags do\n    @artwork.tags.map(&:name).to_sentence\n  end %>\n\n  <%= a.association :fans, collection_tag: :ol do |fan| %>\n    <li><%= link_to fan.name, fan %></li>\n  <% end %>\n<% end %>\n```\n\nThe first is a `has_one` or `belongs_to` association, which works like an attribute\nto ShowFor, except it will retrieve the artist association and try to find a\nproper method from `ShowFor.association_methods` to be used. You can pass\nthe option :using to tell (and not guess) which method from the association\nto use.\n\n:tags is a `has_and_belongs_to_many` association which will return a collection.\nShowFor can handle collections by default by wrapping them in list (`<ul>` with\neach item wrapped by an `<li>`). However, it also allows you to give `:to_sentence`\nor `:join` it you want to render them inline.\n\nYou can also pass a block which expects an argument to association. In such cases,\na wrapper for the collection is still created and the block just iterates over the\ncollection objects.\n\nHere are some other examples of the many possibilites to custom the output content:\n\n```erb\n<%= u.association :relationships, label: 'test' do  %>\n  <% @user.relationships.each do |relation| %>\n    <%= relation.related_user.name if relation.related_user_role == 'supervisor' %>\n  <% end %>\n<% end %>\n\n<%= u.attribute :gender do  %>\n  <%= content_tag :span, t(\"helpers.enum_select.user.gender.#{@user.gender}\") %>\n<% end %>\n```\n\n## Supported Ruby / Rails versions\n\nWe intend to maintain support for all Ruby / Rails versions that haven't reached end-of-life.\n\nFor more information about specific versions please check [Ruby](https://www.ruby-lang.org/en/downloads/branches/)\nand [Rails](https://guides.rubyonrails.org/maintenance_policy.html) maintenance policies, and our test matrix.\n\n## Bugs and Feedback\n\nIf you discover any bugs or want to drop a line, feel free to create an issue on GitHub.\n\nhttp://github.com/heartcombo/show_for/issues\n\n## License\n\nMIT License.\nCopyright 2020-CURRENT Rafael França, Carlos Antonio da Silva.\nCopyright 2012-2019 Plataformatec.\n"
  },
  {
    "path": "Rakefile",
    "content": "# encoding: UTF-8\n\nrequire 'bundler'\nBundler::GemHelper.install_tasks\n\nrequire 'rake/testtask'\nrequire 'rdoc/task'\n\ndesc 'Default: run unit tests.'\ntask default: :test\n\ndesc 'Test the show_form plugin.'\nRake::TestTask.new(:test) do |t|\n  t.libs << 'lib'\n  t.libs << 'test'\n  t.pattern = 'test/**/*_test.rb'\n  t.verbose = true\nend\n\ndesc 'Generate documentation for the show_for plugin.'\nRake::RDocTask.new(:rdoc) do |rdoc|\n  rdoc.rdoc_dir = 'rdoc'\n  rdoc.title    = 'ShowFor'\n  rdoc.options << '--line-numbers' << '--inline-source'\n  rdoc.rdoc_files.include('README.rdoc')\n  rdoc.rdoc_files.include('lib/**/*.rb')\nend\n"
  },
  {
    "path": "gemfiles/Gemfile-rails-7-0",
    "content": "source 'https://rubygems.org'\n\ngemspec path: '..'\n\ngem 'railties', '~> 7.0.0'\ngem 'activemodel', '~> 7.0.0'\ngem 'actionpack', '~> 7.0.0'\n"
  },
  {
    "path": "gemfiles/Gemfile-rails-7-1",
    "content": "source 'https://rubygems.org'\n\ngemspec path: '..'\n\ngem 'railties', '~> 7.1.0'\ngem 'activemodel', '~> 7.1.0'\ngem 'actionpack', '~> 7.1.0'\n"
  },
  {
    "path": "gemfiles/Gemfile-rails-7-2",
    "content": "source 'https://rubygems.org'\n\ngemspec path: '..'\n\ngem 'railties', '~> 7.2.0'\ngem 'activemodel', '~> 7.2.0'\ngem 'actionpack', '~> 7.2.0'\n"
  },
  {
    "path": "gemfiles/Gemfile-rails-8-0",
    "content": "source 'https://rubygems.org'\n\ngemspec path: '..'\n\ngem 'railties', '~> 8.0.0'\ngem 'activemodel', '~> 8.0.0'\ngem 'actionpack', '~> 8.0.0'\n"
  },
  {
    "path": "gemfiles/Gemfile-rails-main",
    "content": "source 'https://rubygems.org'\n\ngemspec path: '..'\n\ngem 'railties', github: 'rails/rails', branch: 'main'\ngem 'activemodel', github: 'rails/rails', branch: 'main'\ngem 'actionpack', github: 'rails/rails', branch: 'main'\n"
  },
  {
    "path": "lib/generators/show_for/USAGE",
    "content": "To copy a ShowFor initializer to your Rails App, with some configuration values, just do:\n\n    rails generate show_for:install\n"
  },
  {
    "path": "lib/generators/show_for/install_generator.rb",
    "content": "module ShowFor\n  module Generators\n    class InstallGenerator < Rails::Generators::Base\n      desc \"Copy ShowFor installation files\"\n      class_option :template_engine, desc: 'Template engine to be invoked (erb or haml or slim).'\n      source_root File.expand_path('../templates', __FILE__)\n\n      def copy_initializers\n        copy_file 'show_for.rb', 'config/initializers/show_for.rb'\n      end\n\n      def copy_locale_file\n        copy_file 'en.yml', 'config/locales/show_for.en.yml'\n      end\n\n      def copy_generator_template\n        engine = options[:template_engine]\n        copy_file \"show.html.#{engine}\", \"lib/templates/#{engine}/scaffold/show.html.#{engine}\"\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/generators/show_for/templates/en.yml",
    "content": "en:\n  show_for:\n    blank: \"Not specified\"\n    # If you want to use html tags with blank value use blank html translation\n    # blank_html: \"<span>Not specified</span>\"\n    \"yes\": \"Yes\"\n    \"no\": \"No\"\n"
  },
  {
    "path": "lib/generators/show_for/templates/show.html.erb",
    "content": "<%%= show_for @<%= singular_name %> do |s| %>\n<% attributes.each do |attribute| -%>\n  <%%= s.<%= attribute.reference? ? :association : :attribute %> :<%= attribute.name %> %>\n<% end -%>\n<%% end %>\n\n<%%= link_to 'Edit', edit_<%= singular_name %>_path(@<%= singular_name %>) %> |\n<%%= link_to 'Back', <%= plural_name %>_path %>\n"
  },
  {
    "path": "lib/generators/show_for/templates/show.html.haml",
    "content": "= show_for(@<%= singular_name %>) do |s|\n<%- attributes.each do |attribute| -%>\n  = s.<%= attribute.reference? ? :association : :attribute %> :<%= attribute.name %>\n<% end -%>\n\n= link_to 'Edit', edit_<%= singular_name %>_path(@<%= singular_name %>)\n|\n= link_to 'Back', <%= plural_name %>_path\n"
  },
  {
    "path": "lib/generators/show_for/templates/show.html.slim",
    "content": "= show_for(@<%= singular_name %>) do |s|\n<%- attributes.each do |attribute| -%>\n  = s.<%= attribute.reference? ? :association : :attribute %> :<%= attribute.name %>\n<% end -%>\n\n= link_to 'Edit', edit_<%= singular_name %>_path(@<%= singular_name %>)\n|\n= link_to 'Back', <%= plural_name %>_path\n"
  },
  {
    "path": "lib/generators/show_for/templates/show_for.rb",
    "content": "# Use this setup block to configure all options available in ShowFor.\nShowFor.setup do |config|\n  # The tag which wraps show_for calls.\n  # config.show_for_tag = :div\n\n  # The DOM class set for show_for tag. Default is nil\n  # config.show_for_class = :custom\n\n  # The tag which wraps each attribute/association call. Default is :p.\n  # config.wrapper_tag = :dl\n\n  # The DOM class set for the wrapper tag. Default is :wrapper.\n  # config.wrapper_class = :custom\n\n  # The tag used to wrap each label. Default is :strong.\n  # config.label_tag = :dt\n\n  # The DOM class of each label tag. Default is :label.\n  # config.label_class = :custom\n\n  # The tag used to wrap each content (value). Default is nil.\n  # config.content_tag = :dd\n\n  # The DOM class of each content tag. Default is :content.\n  # config.content_class = :custom\n\n  # The DOM class set for blank content tags. Default is \"blank\".\n  # config.blank_content_class = 'no_content'\n\n  # Skip blank attributes instead of generating with a default message. Default is false.\n  # config.skip_blanks = true\n\n  # The separator between label and content. Default is \"<br />\".\n  # config.separator = \"<br />\"\n\n  # The tag used to wrap collections. Default is :ul.\n  # config.collection_tag = :ul\n\n  # The DOM class set for the collection tag. Default is :collection.\n  # config.collection_class = :custom\n\n  # The default iterator to be used when invoking a collection/association.\n  # config.default_collection_proc = lambda { |value| \"<li>#{ERB::Util.h(value)}</li>\".html_safe }\n\n  # The default format to be used in I18n when localizing a Date/Time.\n  # config.i18n_format = :default\n\n  # Whenever a association is given, the first method in association_methods\n  # in which the association responds to is used to retrieve the association labels.\n  # config.association_methods = [ :name, :title, :to_s ]\n\n  # If you want to wrap the text inside a label (e.g. to append a semicolon),\n  # specify label_proc - it will be automatically called, passing in the label text.\n  # config.label_proc = lambda { |l| l + \":\" }\nend\n"
  },
  {
    "path": "lib/show_for/association.rb",
    "content": "module ShowFor\n  module Association\n    def attribute(attribute_name, options = {}, &block)\n      if association_name = options.delete(:in)\n        options[:using] = attribute_name\n        association(association_name, options, &block)\n      else\n        super\n      end\n    end\n\n    def association(association_name, options = {}, &block)\n      apply_default_options!(association_name, options)\n\n      # If a block with an iterator was given, no need to calculate the labels\n      # since we want the collection to be yielded. Otherwise, calculate the values.\n      value = if collection_block?(block)\n        collection_block = block\n        @object.send(association_name)\n      elsif block\n        block\n      else\n        association = @object.send(association_name)\n        values = values_from_association(association, options)\n\n        if options.delete(:to_sentence)\n          values.to_sentence\n        elsif joiner = options.delete(:join)\n          values.join(joiner)\n        else\n          values\n        end\n      end\n\n      wrap_label_and_content(association_name, value, options, &collection_block)\n    end\n\n  protected\n\n    def values_from_association(association, options) #:nodoc:\n      sample = association.respond_to?(:to_ary) ? association.first : association\n      method = options.delete(:using) || ShowFor.association_methods.find { |m| sample.respond_to?(m) }\n\n      if method\n        association.respond_to?(:to_ary) ? association.map(&method) : association.try(method)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/show_for/attribute.rb",
    "content": "module ShowFor\n  module Attribute\n    def attribute(attribute_name, options = {}, &block)\n      apply_default_options!(attribute_name, options)\n      block = block_from_value_option(attribute_name, options) unless block\n      collection_block, block = block, nil if collection_block?(block)\n\n      value = attribute_value(attribute_name, &block)\n\n      wrap_label_and_content(attribute_name, value, options, &collection_block)\n    end\n\n    def value(attribute_name, options = {}, &block)\n      apply_default_options!(attribute_name, options)\n      collection_block, block = block, nil if collection_block?(block)\n\n      value = attribute_value(attribute_name, &block)\n\n      wrap_content(attribute_name, value, options, &collection_block)\n    end\n\n    def attributes(*attribute_names)\n      attribute_names.map do |attribute_name|\n        attribute(attribute_name)\n      end.join.html_safe\n    end\n\n  private\n\n    def attribute_value(attribute_name, &block)\n      if block\n        block\n      elsif @object.respond_to?(:\"human_#{attribute_name}\")\n        @object.send :\"human_#{attribute_name}\"\n      else\n        @object.send(attribute_name)\n      end\n    end\n\n    def block_from_value_option(attribute_name, options)\n      if !options.has_key?(:value)\n        nil\n      elsif options[:value].is_a?(Symbol)\n        block_from_symbol(attribute_name, options)\n      else\n        lambda { options[:value].to_s }\n      end\n    end\n\n    def block_from_symbol(attribute_name, options)\n      attribute = @object.send(attribute_name)\n      case attribute\n      when Array, Hash\n        lambda { |element| element.send(options[:value]) }\n      else\n        lambda { attribute.send(options[:value]) }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/show_for/builder.rb",
    "content": "require 'show_for/attribute'\nrequire 'show_for/association'\nrequire 'show_for/content'\nrequire 'show_for/label'\n\nmodule ShowFor\n  class Builder\n    include ShowFor::Attribute\n    include ShowFor::Association\n    include ShowFor::Content\n    include ShowFor::Label\n\n    attr_reader :object, :template\n\n    def initialize(object, template)\n      @object, @template = object, template\n    end\n\n  protected\n\n    def object_name #:nodoc:\n      @object_name ||= begin\n                         model_name = @object.class.model_name\n\n                         # TODO Remove this check when we drop support to Rails 3.0\n                         if model_name.respond_to?(:param_key)\n                           model_name.param_key\n                         else\n                           model_name.singular\n                         end\n                       end\n    end\n\n    def wrap_label_and_content(name, value, options, &block) #:nodoc:\n      return if skip_blanks?(value)\n      label = label(name, options, false)\n      if label.present? && separator = options.fetch(:separator) { ShowFor.separator }\n        label += separator.html_safe\n      end\n      wrap_with(:wrapper, label + content(value, options, false, &block), apply_wrapper_options!(:wrapper, options, value))\n    end\n\n    def wrap_content(name, value, options, &block) #:nodoc:\n      wrap_with(:wrapper, content(value, options, false, &block), apply_wrapper_options!(:wrapper, options, value))\n    end\n\n    # Set \"#{object_name}_#{attribute_name}\" as in the wrapper tag.\n    def apply_default_options!(name, options) #:nodoc:\n      html_class = \"#{object_name}_#{name}\".gsub(/\\W/, '')\n      wrapper_html = options[:wrapper_html] ||= {}\n      wrapper_html[:class] = \"#{html_class} #{wrapper_html[:class]}\".rstrip\n    end\n\n    def apply_wrapper_options!(type, options, value)\n      options[:\"#{type}_html\"] ||= {}\n      options[:\"#{type}_html\"][:class] = [options[:\"#{type}_html\"][:class], ShowFor.blank_content_class].join(' ') if is_empty?(value)\n      options\n    end\n\n    # Gets the default tag set in ShowFor module and apply (if defined)\n    # around the given content. It also check for html_options in @options\n    # hash related to the current type.\n    def wrap_with(type, content, options) #:nodoc:\n      return if skip_blanks?(content)\n      tag = options.delete(:\"#{type}_tag\") || ShowFor.send(:\"#{type}_tag\")\n\n      if tag\n        type_class = ShowFor.send :\"#{type}_class\"\n        html_options = options.delete(:\"#{type}_html\") || {}\n        html_options[:class] = [type_class, html_options[:class]].compact.presence\n        @template.content_tag(tag, content, html_options)\n      else\n        content\n      end\n    end\n\n    # Returns true if the block is supposed to iterate through a collection,\n    # i.e. it has arity equals to one.\n    def collection_block?(block) #:nodoc:\n      block && block.arity == 1\n    end\n\n    # Verifies whether the value is blank and its configured to skip blank values.\n    def skip_blanks?(value) #:nodoc:\n      ShowFor.skip_blanks && value.blank? && value != false\n    end\n\n    def is_empty?(value) #:nodoc:\n      value = @template.capture(&value) if value.is_a?(Proc)\n      value.blank? && value != false\n    end\n  end\nend\n\n"
  },
  {
    "path": "lib/show_for/content.rb",
    "content": "module ShowFor\n  module Content\n    def content(value, options = {}, apply_options = true, &block)\n      # cache value for apply_wrapper_options!\n      sample_value = value\n\n      # We need to convert value to_a because when dealing with ActiveRecord\n      # Array proxies, the follow statement Array# === value return false\n      value = value.to_a if value.respond_to?(:to_ary)\n\n      content = case value\n        when Date, Time, DateTime\n          I18n.l value, format: options.delete(:format) || ShowFor.i18n_format\n        when TrueClass\n          I18n.t :\"show_for.yes\", default: \"Yes\"\n        when FalseClass\n          I18n.t :\"show_for.no\", default: \"No\"\n        when Array, Hash\n          collection_handler(value, options, &block) unless value.empty?\n        when Proc\n          @template.capture(&value)\n        when Numeric\n          value.to_s\n        else\n          unless value.blank?\n            block ? template.capture(value, &block) : value\n          end\n      end\n\n      if content.blank? && !ShowFor.skip_blanks\n        content = blank_value(options)\n      end\n\n      options[:content_html] = options.except(:content_tag) if apply_options\n      wrap_with(:content, content, apply_wrapper_options!(:content, options, sample_value))\n    end\n\n  protected\n\n    def collection_handler(value, options, &block) #:nodoc:\n      iterator = collection_block?(block) ? block : ShowFor.default_collection_proc\n\n      response = value.map do |item|\n        template.capture(item, &iterator)\n      end.join.html_safe\n\n      wrap_with(:collection, response, options)\n    end\n\n    def translate_blank_html\n      template.t(:'show_for.blank_html', default: translate_blank_text)\n    end\n\n    def translate_blank_text\n      I18n.t(:'show_for.blank', default: \"Not specified\")\n    end\n\n    def blank_value(options)\n      options.delete(:if_blank) || translate_blank_html\n    end\n  end\nend\n"
  },
  {
    "path": "lib/show_for/helper.rb",
    "content": "module ShowFor\n  module Helper\n    # Creates a div around the object and yields a builder.\n    #\n    # Example:\n    #\n    #   show_for @user do |f|\n    #     f.attribute :name\n    #     f.attribute :email\n    #   end\n    #\n    def show_for(object, html_options = {}, &block)\n      html_options = html_options.dup\n\n      tag = html_options.delete(:show_for_tag) || ShowFor.show_for_tag\n\n      html_options[:id]  ||= dom_id(object)\n      html_options[:class] = show_for_html_class(object, html_options)\n\n      builder = html_options.delete(:builder) || ShowFor::Builder\n      content = capture(builder.new(object, self), &block)\n\n      content_tag(tag, content, html_options)\n    end\n\n    private\n\n    def show_for_html_class(object, html_options)\n      \"show_for #{dom_class(object)} #{html_options[:class]} #{ShowFor.show_for_class}\".squeeze(\" \").rstrip\n    end\n  end\nend\n\nActionView::Base.send :include, ShowFor::Helper\n"
  },
  {
    "path": "lib/show_for/label.rb",
    "content": "module ShowFor\n  module Label\n    def label(text_or_attribute, options = {}, apply_options = true)\n      label = if text_or_attribute.is_a?(String)\n        text_or_attribute\n      elsif options.key?(:label)\n        options.delete(:label)\n      else\n        human_attribute_name(text_or_attribute)\n      end\n\n      return ''.html_safe if label == false\n      options[:label_html] = options.dup if apply_options\n\n      label = ShowFor.label_proc.call(label) if options.fetch(:wrap_label, true) && ShowFor.label_proc\n      wrap_with :label, label, options\n    end\n\n  protected\n\n    def human_attribute_name(attribute) #:nodoc:\n      @object.class.human_attribute_name(attribute.to_s)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/show_for/version.rb",
    "content": "module ShowFor\n  VERSION = \"0.9.0\".freeze\nend\n"
  },
  {
    "path": "lib/show_for.rb",
    "content": "require 'action_view'\nrequire 'show_for/helper'\n\nmodule ShowFor\n  autoload :Builder, 'show_for/builder'\n\n  mattr_accessor :show_for_tag\n  @@show_for_tag = :div\n\n  mattr_accessor :show_for_class\n  @@show_for_class = nil\n\n  mattr_accessor :label_tag\n  @@label_tag = :strong\n\n  mattr_accessor :label_class\n  @@label_class = :label\n\n  mattr_accessor :separator\n  @@separator = \"<br />\"\n\n  mattr_accessor :content_tag\n  @@content_tag = nil\n\n  mattr_accessor :content_class\n  @@content_class = :content\n\n  mattr_accessor :blank_content_class\n  @@blank_content_class = \"blank\"\n\n  mattr_accessor :skip_blanks\n  @@skip_blanks = false\n\n  mattr_accessor :wrapper_tag\n  @@wrapper_tag = :div\n\n  mattr_accessor :wrapper_class\n  @@wrapper_class = :wrapper\n\n  mattr_accessor :collection_tag\n  @@collection_tag = :ul\n\n  mattr_accessor :collection_class\n  @@collection_class = :collection\n\n  mattr_accessor :default_collection_proc\n  @@default_collection_proc = lambda { |value| \"<li>#{ERB::Util.html_escape(value)}</li>\".html_safe }\n\n  mattr_accessor :i18n_format\n  @@i18n_format = :default\n\n  mattr_accessor :association_methods\n  @@association_methods = [ :name, :title, :to_s ]\n\n  mattr_accessor :label_proc\n  @@label_proc = nil\n\n  # Yield self for configuration block:\n  #\n  #   ShowFor.setup do |config|\n  #     config.i18n_format = :long\n  #   end\n  #\n  def self.setup\n    yield self\n  end\nend\n"
  },
  {
    "path": "show_for.gemspec",
    "content": "# -*- encoding: utf-8 -*-\n$:.push File.expand_path(\"../lib\", __FILE__)\nrequire \"show_for/version\"\n\nGem::Specification.new do |s|\n  s.name        = \"show_for\"\n  s.version     = ShowFor::VERSION.dup\n  s.platform    = Gem::Platform::RUBY\n  s.summary     = \"Wrap your objects with a helper to easily show them\"\n  s.email       = \"heartcombo.oss@gmail.com\"\n  s.homepage    = \"https://github.com/heartcombo/show_for\"\n  s.description = \"Wrap your objects with a helper to easily show them\"\n  s.authors     = [\"José Valim\"]\n  s.licenses    = [\"MIT\"]\n  s.metadata    = {\n    \"homepage_uri\"    => \"https://github.com/heartcombo/show_for\",\n    \"changelog_uri\"   => \"https://github.com/heartcombo/show_for/blob/main/CHANGELOG.md\",\n    \"source_code_uri\" => \"https://github.com/heartcombo/show_for\",\n    \"bug_tracker_uri\" => \"https://github.com/heartcombo/show_for/issues\",\n  }\n\n  s.files         = Dir[\"CHANGELOG.md\", \"MIT-LICENSE\", \"README.md\", \"lib/**/*\"]\n  s.require_paths = [\"lib\"]\n\n  s.required_ruby_version = '>= 2.7.0'\n\n  s.add_dependency('activemodel', '>= 7.0')\n  s.add_dependency('actionpack', '>= 7.0')\n\n  s.add_development_dependency('rake')\n  s.add_development_dependency('rdoc')\n  s.add_development_dependency('ostruct')\nend\n"
  },
  {
    "path": "test/association_test.rb",
    "content": "require 'test_helper'\n\nclass AssociationTest < ActionView::TestCase\n  test \"show_for works with belongs_to/has_one associations\" do\n    with_association_for @user, :company\n    assert_select \"div.show_for div.wrapper\", /Plataformatec/\n  end\n\n  test \"show_for accepts :using as option to tell how to retrieve association value\" do\n    with_association_for @user, :company, using: :alternate_name\n    assert_select \"div.show_for div.wrapper\", /Alternate Plataformatec/\n  end\n\n  test \"show_for accepts :in to tell to retrieve an attribute from association\" do\n    with_attribute_for @user, :alternate_name, in: :company\n    assert_select \"div.show_for div.wrapper\", /Alternate Plataformatec/\n  end\n\n  test \"show_for forwards all options send with :in to association\" do\n    with_attribute_for @user, :alternate_name, in: :tags, to_sentence: true\n    assert_no_select \"div.show_for div.wrapper ul.collection\"\n    assert_select \"div.show_for div.wrapper\", /Alternate Tag 1, Alternate Tag 2, and Alternate Tag 3/\n  end\n\n  test \"show_for works with has_many/has_and_belongs_to_many associations\" do\n    with_association_for @user, :tags\n    assert_select \"div.show_for div.wrapper ul.collection\"\n    assert_select \"div.show_for div.wrapper ul.collection li\", \"Tag 1\"\n    assert_select \"div.show_for div.wrapper ul.collection li\", \"Tag 2\"\n    assert_select \"div.show_for div.wrapper ul.collection li\", \"Tag 3\"\n  end\n\n  test \"show_for works with has_many/has_and_belongs_to_many blank associations\" do\n    def @user.tags\n      []\n    end\n\n    swap ShowFor, association_methods: [:name] do\n      with_association_for @user, :tags\n      assert_no_select \"div.show_for div.wrapper ul.collection\"\n      assert_no_select \"div.show_for div.wrapper\", /Enumerator/\n    end\n  end\n\n  test \"show_for accepts a block with has_many/has_and_belongs_to_many blank associations\" do\n    def @user.tags\n      []\n    end\n\n    swap ShowFor, association_methods: [:name] do\n      with_association_for @user, :tags do |tag|\n        tag.name\n      end\n      assert_no_select \"div.show_for div.wrapper ul.collection\"\n      assert_no_select \"div.show_for div.wrapper\", /Enumerator/\n    end\n  end\n\n  test \"show_for uses :if_blank when has_many/has_and_belongs_to_many association is blank\" do\n    def @user.tags\n      []\n    end\n\n    with_association_for @user, :tags, if_blank: 'No tags' do |tag|\n      tag.name\n    end\n    assert_select \"div.show_for div.wrapper.blank\", /No tags/\n    assert_no_select \"div.show_for div.wrapper ul.collection\"\n    assert_no_select \"div.show_for div.wrapper\", /Enumerator/\n  end\n\n  test \"show_for uses :if_blank if given a block when has_many/has_and_belongs_to_many association is blank\" do\n    def @user.tags\n      []\n    end\n\n    with_association_for @user, :tags, if_blank: 'No tags'\n    assert_select \"div.show_for div.wrapper.blank\", /No tags/\n    assert_no_select \"div.show_for div.wrapper ul.collection\"\n    assert_no_select \"div.show_for div.wrapper\", /Enumerator/\n  end\n\n  test \"show_for accepts a block with an argument in belongs_to associations\" do\n    with_association_for @user, :company do |company|\n      company.name.upcase\n    end\n\n    assert_select \"div.show_for div.wrapper\", /PLATAFORMATEC/\n  end\n\n  test \"show_for accepts :using as option to tell how to retrieve association values\" do\n    with_association_for @user, :tags, using: :alternate_name\n    assert_select \"div.show_for div.wrapper ul.collection\"\n    assert_select \"div.show_for div.wrapper ul.collection li\", \"Alternate Tag 1\"\n    assert_select \"div.show_for div.wrapper ul.collection li\", \"Alternate Tag 2\"\n    assert_select \"div.show_for div.wrapper ul.collection li\", \"Alternate Tag 3\"\n  end\n\n  test \"show_for accepts :to_sentence as option in collection associations\" do\n    with_association_for @user, :tags, to_sentence: true\n    assert_no_select \"div.show_for div.wrapper ul.collection\"\n    assert_select \"div.show_for div.wrapper\", /Tag 1, Tag 2, and Tag 3/\n  end\n\n  test \"show_for accepts :join as option in collection associations\" do\n    with_association_for @user, :tags, join: \", \"\n    assert_no_select \"div.show_for div.wrapper ul.collection\"\n    assert_select \"div.show_for div.wrapper\", /Tag 1, Tag 2, Tag 3/\n  end\n\n  test \"show_for accepts a block without argument in collection associations\" do\n    with_association_for @user, :tags do\n      @user.tags.map(&:name).to_sentence\n    end\n    assert_no_select \"div.show_for div.wrapper ul.collection\"\n    assert_select \"div.show_for div.wrapper\", /Tag 1, Tag 2, and Tag 3/\n  end\n\n  test \"show_for accepts a block with argument in collection associations\" do\n    with_association_for @user, :tags, collection_tag: :p do |tag|\n      assert_kind_of Tag, tag\n      content_tag(:span, tag.name)\n    end\n    assert_no_select \"div.show_for div.wrapper ul.collection\"\n    assert_select \"div.show_for div.wrapper p.collection\"\n    assert_select \"div.show_for div.wrapper p.collection span\", \"Tag 1\"\n    assert_select \"div.show_for div.wrapper p.collection span\", \"Tag 2\"\n    assert_select \"div.show_for div.wrapper p.collection span\", \"Tag 3\"\n  end\n\n  test \"show_for does not display empty has_many/has_and_belongs_to_many association if skip_blanks option is passed\" do\n    def @user.tags\n      []\n    end\n\n    swap ShowFor, skip_blanks: true do\n      with_association_for @user, :tags\n      assert_no_select \"div.show_for div.wrapper\"\n    end\n  end\n\n  test \"show_for does not display empty belongs_to/has_one association if skip_blanks option is passed\" do\n    def @user.company\n      nil\n    end\n\n    swap ShowFor, skip_blanks: true do\n      with_association_for @user, :company\n      assert_no_select \"div.show_for div.wrapper\"\n    end\n  end\nend\n"
  },
  {
    "path": "test/attribute_test.rb",
    "content": "require 'test_helper'\n\nclass AttributeTest < ActionView::TestCase\n  # COLLECTIONS\n  test \"show_for accepts an attribute as a collection\" do\n    with_attribute_for @user, :scopes\n    assert_select \"div.show_for div.wrapper ul.collection\"\n    assert_select \"div.show_for div.wrapper ul.collection li\", count: 3\n  end\n\n  test \"show_for accepts an attribute as a collection with a block to iterate the collection\" do\n    with_attribute_for @user, :scopes do |scope|\n      content_tag :span, scope\n    end\n    assert_select \"div.show_for div.wrapper ul.collection\"\n    assert_select \"div.show_for div.wrapper ul.collection span\", count: 3\n  end\n\n  test \"show_for treats symbol for :value as method on each element of collection\" do\n    with_attribute_for @user, :scopes, value: :upcase\n    @user.scopes.each do |scope|\n      assert_select \"div.show_for div.wrapper ul.collection\", /#{scope.upcase}/\n    end\n  end\n\n  test \"show_for allows collection tag to be configured globally\" do\n    swap ShowFor, collection_tag: :ol, collection_class: \"my_collection\" do\n      with_attribute_for @user, :scopes\n      assert_select \"div.show_for div.wrapper ol.my_collection\"\n    end\n  end\n\n  test \"show_for allows collection class to be disabled globally\" do\n    swap ShowFor, collection_tag: :ol, collection_class: nil do\n      with_attribute_for @user, :scopes\n      assert_select \"div.show_for div.wrapper ol\"\n      assert_no_select \"ol[class]\"\n    end\n  end\n\n  test \"show_for allows collection tag to be changed by attribute\" do\n    with_attribute_for @user, :scopes, collection_tag: :ol\n    assert_select \"div.show_for div.wrapper ol.collection\"\n  end\n\n  test \"show_for allows collection tag html to be configured by attribute\" do\n    with_attribute_for @user, :scopes, collection_html: { id: \"thecollection\", class: \"special\" }\n    assert_select \"div.show_for div.wrapper ul#thecollection.special.collection\"\n  end\n\n  # CONTENT\n  test \"show_for allows content tag to be configured globally\" do\n    swap ShowFor, content_tag: :span, content_class: :my_content do\n      with_attribute_for @user, :name\n      assert_select \"div.show_for div.wrapper span.my_content\"\n    end\n  end\n\n  test \"show_for allows content class to be disabled globally\" do\n    swap ShowFor, content_tag: :span, content_class: nil do\n      with_attribute_for @user, :name\n      assert_select \"div.show_for div.wrapper span\"\n      assert_no_select \"span[class]\"\n    end\n  end\n\n  test \"show_for allows content tag to be changed by attribute\" do\n    with_attribute_for @user, :name, content_tag: :span\n    assert_select \"div.show_for div.wrapper span.content\"\n  end\n\n  test \"show_for allows content tag html to be configured by attribute\" do\n    with_attribute_for @user, :name, content_tag: :span, content_html: { id: \"thecontent\", class: \"special\" }\n    assert_select \"div.show_for div.wrapper span#thecontent.special.content\"\n  end\n\n  test \"show_for accepts an attribute as string\" do\n    with_attribute_for @user, :name\n    assert_select \"div.show_for div.wrapper\", /ShowFor/\n  end\n\n  test \"show_for accepts an attribute as time\" do\n    with_attribute_for @user, :created_at\n    assert_select \"div.show_for div.wrapper\", /#{Regexp.escape(I18n.l(@user.created_at))}/\n  end\n\n  test \"show_for accepts an attribute as date\" do\n    with_attribute_for @user, :updated_at\n    assert_select \"div.show_for div.wrapper\", /#{Regexp.escape(I18n.l(@user.updated_at))}/\n  end\n\n  test \"show_for accepts an attribute as time with format options\" do\n    with_attribute_for @user, :created_at, format: :long\n    assert_select \"div.show_for div.wrapper\", /#{Regexp.escape(I18n.l(@user.created_at, format: :long))}/\n  end\n\n  test \"show_for accepts an attribute as true\" do\n    with_attribute_for @user, :active\n    assert_select \"div.show_for div.wrapper\", /Yes/\n  end\n\n  test \"show_for accepts an attribute as true which can be localized\" do\n    store_translations(:en, show_for: { yes: \"Hell yeah!\" }) do\n      with_attribute_for @user, :active\n      assert_select \"div.show_for div.wrapper\", /Hell yeah!/\n    end\n  end\n\n  test \"show_for accepts an attribute as false\" do\n    with_attribute_for @user, :invalid\n    assert_select \"div.show_for div.wrapper\", /No/\n  end\n\n  test \"show_for accepts an attribute as false which can be localized\" do\n    store_translations(:en, show_for: { no: \"Hell no!\" }) do\n      with_attribute_for @user, :invalid\n      assert_select \"div.show_for div.wrapper\", /Hell no!/\n    end\n  end\n\n  test \"show_for accepts nil and or blank attributes\" do\n    with_attribute_for @user, :description\n    assert_select \"div.show_for div.wrapper\", /Not specified/\n  end\n\n  test \"show_for accepts not spcified message can be localized\" do\n    store_translations(:en, show_for: { blank: \"OMG! It's blank!\" }) do\n      with_attribute_for @user, :description\n      assert_select \"div.show_for div.wrapper\", /OMG! It's blank!/\n    end\n  end\n\n  test \"show_for accepts not spcified message can be localized with html\" do\n    store_translations(:en, show_for: { blank_html: \"<span>OMG! It's blank!</span>\" }) do\n      with_attribute_for @user, :description\n      assert_select \"div.show_for div.wrapper span\", \"OMG! It's blank!\"\n    end\n  end\n\n  test \"show_for uses :if_blank if attribute is blank\" do\n    with_attribute_for @user, :description, if_blank: \"No description provided\"\n    assert_select \"div.show_for div.wrapper\", /No description provided/\n  end\n\n  test \"show_for accepts a block to supply the content\" do\n    with_attribute_for @user, :description do\n      \"This description is not blank\"\n    end\n    assert_select \"div.show_for div.wrapper\", /This description/\n  end\n\n  test \"show_for uses :if_blank if the block content is blank\" do\n    with_attribute_for @user, :description, if_blank: \"No description provided\" do\n      \"\"\n    end\n    assert_select \"div.show_for div.wrapper\", /No description provided/\n  end\n\n  test \"show_for#content given a block should be wrapped in the result\" do\n    with_attribute_for @user, :name do |name|\n      \"<div class='block'>#{name}</div>\".html_safe\n    end\n    assert_select \"div.wrapper.user_name div.block\", /ShowFor/\n  end\n\n  test \"show_for escapes content by default\" do\n    @user.name = \"<b>hack you!</b>\"\n    with_attribute_for @user, :name\n    assert_no_select \"div.show_for div.wrapper b\"\n    assert_select \"div.show_for div.wrapper\", \"Super User Name!<b>hack you!</b>\"\n  end\n\n  test \"show_for works with html_safe marked strings\" do\n    @user.name = \"<b>hack you!</b>\".html_safe\n    with_attribute_for @user, :name\n    assert_select \"div.show_for div.wrapper b\", \"hack you!\"\n  end\n\n  test \"show_for uses :value if supplied\" do\n    with_attribute_for @user, :name, value: \"Calculated Value\"\n    assert_select \"div.show_for div.wrapper\", /Calculated Value/\n  end\n\n  test \"show_for uses :value and casts to string if supplied\" do\n    with_attribute_for @user, :name, value: 123\n    assert_select \"div.show_for div.wrapper\", /123/\n  end\n\n  test \"show_for ignores attribute if :value supplied but with nil value\" do\n    with_attribute_for @user, :name, value: nil\n    assert_select \"div.show_for div.wrapper\", /Not specified/\n  end\n\n  test \"show_for ignores :value if a block is supplied\" do\n    with_attribute_for @user, :name, value: \"Calculated Value\" do\n      @user.name.upcase\n    end\n    assert_select \"div.show_for div.wrapper\", /#{@user.name.upcase}/\n  end\n\n  test \"show_for treats symbol for :value as method on attribute\" do\n    with_attribute_for @user, :name, value: :upcase\n    assert_select \"div.show_for div.wrapper\", /#{@user.name.upcase}/\n  end\n\n  test \"show_for does not display blank attribute if skip_blanks option is passed\" do\n    swap ShowFor, skip_blanks: true do\n      with_attribute_for @user, :description\n      assert_no_select \"div.show_for div.wrapper\"\n    end\n  end\n\n  test \"show_for display false attribute if skip_blanks option is passed\" do\n    swap ShowFor, skip_blanks: true do\n      with_attribute_for @user, :invalid\n      assert_select \"div.show_for div.wrapper\", /No/\n    end\n  end\n\n  # ATTRIBUTES\n  test \"show_for attributes wraps each attribute with a label and content\" do\n    with_attributes_for @user, :name, :email\n    assert_select \"div.show_for div.user_name.wrapper\", /ShowFor/\n    assert_select \"div.user_name strong.label\", \"Super User Name!\"\n    assert_select \"div.show_for div.user_email.wrapper\", /Not specified/\n    assert_select \"div.user_email strong.label\", \"Email\"\n  end\n\n  test \"show_for should wrap blank attributes with no_attribute\" do\n    swap ShowFor, blank_content_class: 'no_attribute' do\n      with_attributes_for @user, :name, :birthday, :karma\n      assert_select \".wrapper.user_birthday.no_attribute\"\n      assert_select \".wrapper.user_karma.no_attribute\"\n      assert_select \".wrapper.user_name.no_attribute\", false\n    end\n  end\n\nend\n"
  },
  {
    "path": "test/builder_test.rb",
    "content": "require 'test_helper'\n\nclass BuilderTest < ActionView::TestCase\n  # WRAPPER\n  test \"show_for allows wrapper to be configured globally\" do\n    swap ShowFor, wrapper_tag: \"li\", wrapper_class: \"my_wrapper\" do\n      with_attribute_for @user, :name\n      assert_select \"div.show_for li.user_name.my_wrapper\"\n      assert_select \"div.show_for li.my_wrapper strong.label\"\n      assert_select \"div.show_for li.my_wrapper\"\n    end\n  end\n\n  test \"show_for allows wrapper class to be disabled globally\" do\n    swap ShowFor, wrapper_tag: \"li\", wrapper_class: nil do\n      with_attribute_for @user, :name\n      assert_select \"div.show_for li[class='user_name']\"\n    end\n  end\n\n  test \"show_for attribute wraps each attribute with a label and content\" do\n    with_attribute_for @user, :name\n    assert_select \"div.show_for div.user_name.wrapper\"\n    assert_select \"div.show_for div.wrapper strong.label\"\n    assert_select \"div.show_for div.wrapper\"\n  end\n\n  test \"show_for properly deals with namespaced models\" do\n    @user = Namespaced::User.new(id: 1, name: \"ShowFor\")\n\n    with_attribute_for @user, :name\n    assert_select \"div.show_for div.namespaced_user_name.wrapper\"\n    assert_select \"div.show_for div.wrapper strong.label\"\n    assert_select \"div.show_for div.wrapper\"\n  end\n\n  test \"show_for allows wrapper tag to be changed by attribute\" do\n    with_attribute_for @user, :name, wrapper_tag: :span\n    assert_select \"div.show_for span.user_name.wrapper\"\n  end\n\n  test \"show_for allows wrapper html to be configured by attribute\" do\n    with_attribute_for @user, :name, wrapper_html: { id: \"thewrapper\", class: \"special\" }\n    assert_select \"div.show_for div#thewrapper.user_name.wrapper.special\"\n  end\n\n  # SEPARATOR\n  test \"show_for allows separator to be configured globally\" do\n    swap ShowFor, separator: '<span class=\"separator\"></span>' do\n      with_attribute_for @user, :name\n      assert_select \"div.show_for div.user_name span.separator\"\n      assert_select \"div.show_for div.wrapper span.separator\"\n      assert_no_select \"div.show_for br\"\n    end\n  end\n\n  test \"show_for allows separator to be changed by attribute\"do\n    with_attribute_for @user, :name, separator: '<span class=\"separator\"></span>'\n    assert_select \"div.show_for div.wrapper span.separator\"\n    assert_no_select \"div.show_for br\"\n  end\n\n  test \"show_for allows disabling separator by attribute\" do\n    with_attribute_for @user, :name, separator: false\n    assert_no_select \"div.show_for div.wrapper span.separator\"\n    assert_no_select \"div.show_for div.wrapper br\"\n    assert_no_select \"div.show_for div.wrapper\", /false/\n  end\n\n  test \"show_for uses a separator if requested\" do\n    with_attribute_for @user, :name\n    assert_select \"div.show_for div.wrapper br\"\n  end\n\n  test \"show_for does not blow if a separator is not set\" do\n    swap ShowFor, separator: nil do\n      with_attribute_for @user, :name\n      assert_select \"div.show_for div.wrapper\"\n    end\n  end\nend\n"
  },
  {
    "path": "test/content_test.rb",
    "content": "require 'test_helper'\n\nclass ContentTest < ActionView::TestCase\n  test \"show_for#content accepts any object\" do\n    with_content_for @user, \"Special content\"\n    assert_select \"div.show_for\", \"Special content\"\n  end\n\n  test \"show_for#content accepts :if_blank as option\" do\n     with_content_for @user, \"\", if_blank: \"Got blank\"\n     assert_select \"div.show_for\", \"Got blank\"\n   end\n\n  test \"show_for#content accepts html options\" do\n    with_content_for @user, \"Special content\", content_tag: :b, id: \"thecontent\", class: \"special\"\n    assert_select \"div.show_for b#thecontent.special.content\", \"Special content\"\n    assert_no_select \"div.show_for b[content_tag]\"\n  end\n\n  test \"show_for#content with blank value has a 'no value'-class\" do\n    swap ShowFor, blank_content_class: \"nothing\" do\n      with_content_for @user, nil, content_tag: :b\n      assert_select \"div.show_for b.nothing\"\n    end\n  end\n\n  test \"show_for#content with blank value does not display content if skip_blanks option is passed\" do\n    swap ShowFor, skip_blanks: true do\n      with_content_for @user, nil, content_tag: :b\n      assert_no_select \"div.show_for b\"\n    end\n  end\nend\n"
  },
  {
    "path": "test/generators/show_for_generator_test.rb",
    "content": "require 'test_helper'\n\nclass ShowForGeneratorTest < Rails::Generators::TestCase\n  tests ShowFor::Generators::InstallGenerator\n  destination File.expand_path('../../tmp', __FILE__)\n  setup :prepare_destination\n  teardown { rm_rf(destination_root) }\n\n  test 'generates example locale file' do\n    run_generator\n    assert_file 'config/locales/show_for.en.yml'\n  end\n\n  test 'generates the show_for initializer' do\n    run_generator\n    assert_file 'config/initializers/show_for.rb',\n      /config.show_for_tag = :div/\n  end\n\n  %W(erb haml slim).each do |engine|\n    test \"generates the scaffold template when using #{engine}\" do\n      run_generator ['-e', engine]\n      assert_file \"lib/templates/#{engine}/scaffold/show.html.#{engine}\"\n    end\n  end\nend\n"
  },
  {
    "path": "test/helper_test.rb",
    "content": "require \"test_helper\"\n\nclass CustomBuilder < ShowFor::Builder\nend\n\nclass HelperTest < ActionView::TestCase\n  test \"show for yields an instance of ShowFor::Builder\" do\n    show_for(@user) do |f|\n      assert f.instance_of?(ShowFor::Builder)\n    end\n  end\n\n  test \"show for yields an instance of builder class specified by builder option\" do\n    show_for(@user, builder: CustomBuilder) do |f|\n      assert f.instance_of?(CustomBuilder)\n    end\n  end\n\n  test \"show for should add default class to form\" do\n    concat(show_for(@user) do |f| end)\n    assert_select \"div.show_for\"\n  end\n\n  test \"show for should add object class name as css class to form\" do\n    concat(show_for(@user) do |f| end)\n    assert_select \"div.show_for.user\"\n  end\n\n  test \"show for should pass options\" do\n    concat(show_for(@user, id: \"my_div\", class: \"common\") do |f| end)\n    assert_select \"div#my_div.show_for.user.common\"\n  end\n\n  test \"show for tag should be configurable\" do\n    swap ShowFor, show_for_tag: :p do\n      concat(show_for(@user) do |f| end)\n      assert_select \"p.show_for\"\n    end\n  end\n\n  test \"show for class should be configurable\" do\n    swap ShowFor, show_for_class: :awesome do\n      concat(show_for(@user) do |f| end)\n      assert_select \"div.show_for.user.awesome\"\n    end\n  end\n  \n  test \"show for options hash should not be modified\" do\n    html_options = { show_for_tag: :li }\n    concat(show_for(@user, html_options) do |f| end)\n    assert_equal({ show_for_tag: :li }, html_options)\n  end\n  \nend\n"
  },
  {
    "path": "test/label_test.rb",
    "content": "require 'test_helper'\n\nclass LabelTest < ActionView::TestCase\n  test \"show_for shows a label using the humanized attribute name from model\" do\n    with_attribute_for @user, :name\n    assert_select \"div.show_for div.wrapper strong.label\", \"Super User Name!\"\n  end\n\n  test \"show_for skips label if requested\" do\n    with_attribute_for @user, :name, label: false\n    assert_no_select \"div.show_for div.wrapper strong.label\"\n    assert_no_select \"div.show_for div.wrapper br\"\n  end\n\n  test \"show_for uses custom content_tag and skips label if requested\" do\n    with_attribute_for @user, :name, label: false, content_tag: :h2\n    assert_select \"div.show_for div.wrapper h2.content\", \"ShowFor\"\n  end\n\n  test \"show_for allows label to be configured globally\" do\n    swap ShowFor, label_tag: :span, label_class: \"my_label\" do\n      with_attribute_for @user, :name\n      assert_select \"div.show_for div.wrapper span.my_label\"\n    end\n  end\n\n  test \"show_for allows label class to be disabled globally\" do\n    swap ShowFor, label_tag: :span, label_class: nil do\n      with_attribute_for @user, :name\n      assert_select \"div.show_for div.wrapper span\"\n      assert_no_select \"span[class]\"\n    end\n  end\n\n  test \"show_for allows label to be changed by attribute\" do\n    with_attribute_for @user, :name, label_tag: :span\n    assert_select \"div.show_for div.wrapper span.label\"\n  end\n\n  test \"show_for allows label html to be configured by attribute\" do\n    with_attribute_for @user, :name, label_html: { id: \"thelabel\", class: \"special\" }\n    assert_select \"div.show_for div.wrapper strong#thelabel.special.label\"\n  end\n\n  test \"show_for allows label to be set without lookup\" do\n    with_attribute_for @user, :name, label: \"Special Label\"\n    assert_select \"div.show_for div.wrapper strong.label\", \"Special Label\"\n  end\n\n  test \"show_for#label accepts the text\" do\n    with_label_for @user, \"Special Label\"\n    assert_select \"div.show_for strong.label\", \"Special Label\"\n  end\n\n  test \"show_for#label accepts an attribute name\" do\n    with_label_for @user, :name\n    assert_select \"div.show_for strong.label\", \"Super User Name!\"\n  end\n\n  test \"show_for#label accepts html options\" do\n    with_label_for @user, :name, id: \"thelabel\", class: \"special\"\n    assert_select \"div.show_for strong#thelabel.special.label\"\n  end\n\n  test \"should let you override the label wrapper\" do\n    swap ShowFor, label_proc: proc { |l| l + \":\" } do\n      with_label_for @user, \"Special Label\"\n      assert_select \"div.show_for strong.label\", \"Special Label:\"\n    end\n  end\n\n  test \"should you skip wrapping the label on a per item basis\" do\n    swap ShowFor, label_proc: proc { |l| l + \":\" } do\n      with_label_for @user, \"Special Label\", wrap_label: false\n      assert_select \"div.show_for strong.label\", \"Special Label\"\n    end\n  end\nend\n"
  },
  {
    "path": "test/support/misc_helpers.rb",
    "content": "module MiscHelpers\n  def store_translations(locale, translations, &block)\n    begin\n      I18n.backend.store_translations locale, translations\n      yield\n    ensure\n      I18n.reload!\n    end\n  end\n\n  def assert_no_select(selector, value = nil)\n    assert_select(selector, text: value, count: 0)\n  end\n\n  def swap(object, new_values)\n    old_values = {}\n    new_values.each do |key, value|\n      old_values[key] = object.send key\n      object.send :\"#{key}=\", value\n    end\n    yield\n  ensure\n    old_values.each do |key, value|\n      object.send :\"#{key}=\", value\n    end\n  end\n\n  def with_attribute_for(object, attribute, options = {}, &block)\n    concat(show_for(object) do |o|\n      concat o.attribute(attribute, options, &block)\n    end)\n  end\n\n  def with_value_for(object, attribute, options = {}, &block)\n    concat(show_for(object) do |o|\n      concat o.value(attribute, options, &block)\n    end)\n  end\n\n  def with_association_for(object, association, options = {}, &block)\n    concat(show_for(object) do |o|\n      concat o.association(association, options, &block)\n    end)\n  end\n\n  def with_label_for(object, attribute, options = {})\n    concat(show_for(object) do |o|\n      concat o.label(attribute, options)\n    end)\n  end\n\n  def with_content_for(object, value, options = {})\n    concat(show_for(object) do |o|\n      concat o.content(value, options)\n    end)\n  end\n\n  def with_attributes_for(object, *attributes)\n    concat(show_for(object) do |o|\n      concat o.attributes(*attributes)\n    end)\n  end\nend\n"
  },
  {
    "path": "test/support/models.rb",
    "content": "require 'ostruct'\n\nCompany = Struct.new(:id, :name) do\n  extend ActiveModel::Naming\n\n  def alternate_name\n    \"Alternate #{self.name}\"\n  end\nend\n\n\nTag = Struct.new(:id, :name) do\n  extend ActiveModel::Naming\n\n  def self.all(options = {})\n    (1..3).map{ |i| Tag.new(i, \"Tag #{i}\") }\n  end\n\n  def alternate_name\n    \"Alternate #{self.name}\"\n  end\nend\n\nclass User < OpenStruct\n  extend ActiveModel::Naming\n\n  # Get rid of deprecation warnings\n  undef_method :id if respond_to?(:id)\n\n  def tags\n    Tag.all\n  end\n\n  def company\n    Company.new(1, \"Plataformatec\")\n  end\n\n  def self.human_attribute_name(attribute)\n    case attribute\n      when 'name'\n        'Super User Name!'\n      when 'company'\n        'Company Human Name!'\n      else\n        attribute.humanize\n    end\n  end\n\n  def self.human_name\n    \"User\"\n  end\nend\n\nmodule Namespaced\n  class User < ::User\n  end\nend\n"
  },
  {
    "path": "test/test_helper.rb",
    "content": "require 'bundler/setup'\n\nrequire 'minitest/autorun'\n\nrequire 'active_model'\nrequire 'action_controller'\nrequire 'action_view'\nrequire 'action_view/template'\nrequire 'action_view/test_case'\n\nrequire \"rails/generators/test_case\"\nrequire 'generators/show_for/install_generator'\n\n$:.unshift File.expand_path(\"../../lib\", __FILE__)\nrequire 'show_for'\n\nDir[\"#{File.dirname(__FILE__)}/support/*.rb\"].each { |f| require f }\nI18n.enforce_available_locales = true\nI18n.default_locale = :en\n\nActiveSupport::TestCase.test_order = :random if ActiveSupport::TestCase.respond_to?(:test_order=)\n\nclass ActionView::TestCase\n  include MiscHelpers\n  include ShowFor::Helper\n\n  setup :setup_new_user\n\n  def setup_new_user(options = {})\n    @user = User.new({\n      id: 1,\n      name: 'ShowFor',\n      description: '',\n      active: true,\n      invalid: false,\n      scopes: [\"admin\", \"manager\", \"visitor\"],\n      birthday: nil,\n      karma: Proc.new { nil },\n      created_at: Time.now,\n      updated_at: Date.today\n    }.merge(options))\n  end\nend\n"
  },
  {
    "path": "test/value_test.rb",
    "content": "require 'test_helper'\n\nclass ValueTest < ActionView::TestCase\n  test \"show_for allows content tag to be configured globally, without label and separator\" do\n    swap ShowFor, content_tag: :span do\n      with_value_for @user, :name\n      assert_no_select \"div.show_for div.wrapper strong.label\"\n      assert_no_select \"div.show_for div.wrapper br\"\n      assert_select \"div.show_for div.wrapper span.content\"\n    end\n  end\n\n  test \"show_for allows content with tag to be changed by attribute, without label and separator\" do\n    with_value_for @user, :name, content_tag: :span\n    assert_no_select \"div.show_for div.wrapper strong.label\"\n    assert_no_select \"div.show_for div.wrapper br\"\n    assert_select \"div.show_for div.wrapper span.content\"\n  end\n\n  test \"show_for allows content tag html to be configured by attribute, without label and separator\" do\n    with_value_for @user, :name, content_tag: :span, content_html: { id: \"thecontent\", class: \"special\" }\n    assert_no_select \"div.show_for div.wrapper strong.label\"\n    assert_no_select \"div.show_for div.wrapper br\"\n    assert_select \"div.show_for div.wrapper span#thecontent.special.content\"\n  end\n\n  test \"show_for accepts an attribute as string, without label and separator\" do\n    with_value_for @user, :name\n    assert_no_select \"div.show_for div.wrapper strong.label\"\n    assert_no_select \"div.show_for div.wrapper br\"\n    assert_select \"div.show_for div.wrapper\", /ShowFor/\n  end\n\n  test \"show_for accepts an attribute as time, without label and separator\" do\n    with_value_for @user, :created_at\n    assert_no_select \"div.show_for div.wrapper strong.label\"\n    assert_no_select \"div.show_for div.wrapper br\"\n    assert_select \"div.show_for div.wrapper\", /#{Regexp.escape(I18n.l(@user.created_at))}/\n  end\n\n  test \"show_for accepts an attribute as date, without label and separator\" do\n    with_value_for @user, :updated_at\n    assert_no_select \"div.show_for div.wrapper strong.label\"\n    assert_no_select \"div.show_for div.wrapper br\"\n    assert_select \"div.show_for div.wrapper\", /#{Regexp.escape(I18n.l(@user.updated_at))}/\n  end\n\n  test \"show_for accepts an attribute as time with format options, without label and separator\" do\n    with_value_for @user, :created_at, format: :long\n    assert_select \"div.show_for div.wrapper\", /#{Regexp.escape(I18n.l(@user.created_at, format: :long))}/\n  end\n\n  test \"show_for accepts an attribute as nil, without label and separator\" do\n    with_value_for @user, :birthday\n    assert_no_select \"div.show_for div.wrapper strong.label\"\n    assert_no_select \"div.show_for div.wrapper br\"\n    assert_select \"div.show_for div.wrapper\", /Not specified/\n  end\n\n  test \"show_for accepts blank attributes, without label and separator\" do\n    with_value_for @user, :description\n    assert_no_select \"div.show_for div.wrapper strong.label\"\n    assert_no_select \"div.show_for div.wrapper br\"\n    assert_select \"div.show_for div.wrapper\", /Not specified/\n  end\n\n  test \"show_for uses :if_blank if attribute is nil, without label and separator\" do\n    with_value_for @user, :birthday, if_blank: \"No description provided\"\n    assert_no_select \"div.show_for div.wrapper strong.label\"\n    assert_no_select \"div.show_for div.wrapper br\"\n    assert_select \"div.show_for div.wrapper\", /No description provided/\n  end\n\n  test \"show_for uses :if_blank if attribute is blank, without label and separator\" do\n    with_value_for @user, :description, if_blank: \"No description provided\"\n    assert_no_select \"div.show_for div.wrapper strong.label\"\n    assert_no_select \"div.show_for div.wrapper br\"\n    assert_select \"div.show_for div.wrapper\", /No description provided/\n  end\n\n  test \"show_for escapes content by default, without label and separator\" do\n    @user.name = \"<b>hack you!</b>\"\n    with_value_for @user, :name\n    assert_no_select \"div.show_for div.wrapper strong.label\"\n    assert_no_select \"div.show_for div.wrapper br\"\n    assert_no_select \"div.show_for div.wrapper b\"\n    assert_select \"div.show_for div.wrapper\", \"<b>hack you!</b>\"\n  end\nend\n"
  }
]