diff --git a/.gitignore b/.gitignore index a81480d..705debd 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ test/dummy/.sass-cache Gemfile.lock test/tmp *.gem + +*.swp diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..455b277 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,4 @@ +AllCops: + RunRailsCops: true + Exclude: + - spec/dummy/db/schema.rb diff --git a/Gemfile b/Gemfile index faf0969..e5adecb 100644 --- a/Gemfile +++ b/Gemfile @@ -16,6 +16,7 @@ rails = case rails_version end gem "rails", rails +gem "test-unit", "~> 3.0" # 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 diff --git a/README.md b/README.md index 2c2841a..cae3a30 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,56 @@ E.g: `app/components/card/card.yml` :link: "http://google.com" ``` + +If your component depends on a form builder object you can use the following statement: + +```yml +:meta: 'There is a class with form builder object' +:stubs: + - + :form: + !ruby/object:MountainView::Helpers::FormBuilder + model: !ruby/object:Something + attributes: + name: 'something name' +``` + +Also you can stub any ruby class with the following method: + + +```yml +:meta: 'There is a class with an AR object' +:stubs: + - + :some_model: !ruby/object:Something + attributes: + name: 'blabla' +``` + +For any complex logic you can define a custom Compoenent Stub with `init_with(coder)` method which will receive a `#map` with attributes loaded from yaml file: + +```yml +:meta: 'There is a class with a complex logic' +:stubs: + - + :some_model: !ruby/object:ComponentStub + params: + - 'blabla' + - 'nothing' + name: 'Some Name' +``` + +```ruby +class ComponentStub < SomeModel # SomeModel could be AR class + def init_with(coder) + param1 = coder.map["params"].first + somename = coder.map["name"] + # or `@properties = coder.map` + initialize(param1, somename) # call initializer of SomeModel + end +end +``` + 3) Vist `http://localhost:3000/mountain_view/styleguide` #### Example Style Guide diff --git a/lib/mountain_view.rb b/lib/mountain_view.rb index 45cdf28..32ef5a9 100644 --- a/lib/mountain_view.rb +++ b/lib/mountain_view.rb @@ -2,6 +2,8 @@ require "mountain_view/configuration" require "mountain_view/presenter" require "mountain_view/component" +require "mountain_view/helpers/form_builder" +require "mountain_view/helpers/object_wrapper" module MountainView def self.configuration diff --git a/lib/mountain_view/component.rb b/lib/mountain_view/component.rb index ae9f5ed..84434ef 100644 --- a/lib/mountain_view/component.rb +++ b/lib/mountain_view/component.rb @@ -11,6 +11,19 @@ def title end def styleguide_stubs + handle_proc = proc { |type, val| + _tag, _domain, object_type = type.split(":") + case object_type + when "Object" + attrs = val["attributes"] + obj = val["class"].constantize.new(attrs) + MountainView::Helpers::ObjectWrapper.new(obj, attrs) + when "Form" + MountainView::Helpers::FormBuilder.new(val["for"]) + end + } + Psych.add_domain_type("mountain_view", "Object", &handle_proc) + Psych.add_domain_type("mountain_view", "Form", &handle_proc) YAML.load_file(stubs_file) || {} rescue Errno::ENOENT {} diff --git a/lib/mountain_view/helpers/form_builder.rb b/lib/mountain_view/helpers/form_builder.rb new file mode 100644 index 0000000..ea54d15 --- /dev/null +++ b/lib/mountain_view/helpers/form_builder.rb @@ -0,0 +1,25 @@ +module MountainView + module Helpers + class FormBuilder < ActionView::Base.default_form_builder + attr_accessor :model + + def initialize(model) + @model = model + super(@model.class.model_name.param_key, + @model, + ActionView::Base.new, + {}) + rescue + super(@model.class.model_name.param_key, + @model, + ActionView::Base.new, + {}, + nil) + end + + def to_json(_) + "form_for(#{model.to_json(nil)})" + end + end + end +end diff --git a/lib/mountain_view/helpers/object_wrapper.rb b/lib/mountain_view/helpers/object_wrapper.rb new file mode 100644 index 0000000..37f6261 --- /dev/null +++ b/lib/mountain_view/helpers/object_wrapper.rb @@ -0,0 +1,22 @@ +require "delegate" + +module MountainView + module Helpers + class ObjectWrapper < SimpleDelegator + attr_accessor :_attributes + + def initialize(object, attributes) + super(object) + @_attributes = attributes + end + + def class + __getobj__.class + end + + def to_json(_) + "#{self.class.model_name}.new(#{@_attributes.deep_symbolize_keys})" + end + end + end +end diff --git a/test/dummy/app/components/form_custom_button/_form_custom_button.html.erb b/test/dummy/app/components/form_custom_button/_form_custom_button.html.erb new file mode 100644 index 0000000..22babde --- /dev/null +++ b/test/dummy/app/components/form_custom_button/_form_custom_button.html.erb @@ -0,0 +1 @@ +<%= form.button "button text" %> diff --git a/test/dummy/app/components/form_custom_button/form_custom_button.css b/test/dummy/app/components/form_custom_button/form_custom_button.css new file mode 100644 index 0000000..e69de29 diff --git a/test/dummy/app/components/form_custom_button/form_custom_button.js b/test/dummy/app/components/form_custom_button/form_custom_button.js new file mode 100644 index 0000000..e69de29 diff --git a/test/dummy/app/components/form_custom_button/form_custom_button.yml b/test/dummy/app/components/form_custom_button/form_custom_button.yml new file mode 100644 index 0000000..630a640 --- /dev/null +++ b/test/dummy/app/components/form_custom_button/form_custom_button.yml @@ -0,0 +1,18 @@ +:meta: 'There is a class with form builder object' +:stubs: + - + :id: 1 + :some_model: !mountain_view:Object + class: Something + attributes: + name: 'blabla' + :some_another_model: !Object + class: Something + attributes: + name: 'another blabla' + :form: + !Form + for: !Object + class: Something + attributes: + name: 'something name' diff --git a/test/dummy/app/components/form_custom_button/form_custom_button_component.rb b/test/dummy/app/components/form_custom_button/form_custom_button_component.rb new file mode 100644 index 0000000..1002331 --- /dev/null +++ b/test/dummy/app/components/form_custom_button/form_custom_button_component.rb @@ -0,0 +1,4 @@ +class FormCustomButtonComponent < MountainView::Presenter + property :form + property :some_model +end diff --git a/test/dummy/app/models/something.rb b/test/dummy/app/models/something.rb new file mode 100644 index 0000000..fd27c41 --- /dev/null +++ b/test/dummy/app/models/something.rb @@ -0,0 +1,2 @@ +class Something < ActiveRecord::Base +end diff --git a/test/dummy/config/application.rb b/test/dummy/config/application.rb index 2349b30..6feec4a 100644 --- a/test/dummy/config/application.rb +++ b/test/dummy/config/application.rb @@ -1,9 +1,6 @@ require File.expand_path('../boot', __FILE__) -require "active_support" -require "action_controller" -require "action_view" -require "sprockets/railtie" +require "rails/all" Bundler.require(*Rails.groups) require "mountain_view" @@ -36,7 +33,7 @@ class Application < Rails::Application # 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 + config.eager_load = true # Configure static asset server for tests with Cache-Control for performance. config.static_cache_control = 'public, max-age=3600' diff --git a/test/dummy/config/database.yml b/test/dummy/config/database.yml index 1c1a37c..0a51ef2 100644 --- a/test/dummy/config/database.yml +++ b/test/dummy/config/database.yml @@ -18,7 +18,7 @@ development: # Do not set this db to the same as development or production. test: <<: *default - database: db/test.sqlite3 + database: ":memory:" production: <<: *default diff --git a/test/dummy/db/migrate/20160427131303_create_somethings.rb b/test/dummy/db/migrate/20160427131303_create_somethings.rb new file mode 100644 index 0000000..8f2e5c8 --- /dev/null +++ b/test/dummy/db/migrate/20160427131303_create_somethings.rb @@ -0,0 +1,9 @@ +class CreateSomethings < ActiveRecord::Migration + def change + create_table :somethings do |t| + t.string :name + + t.timestamps null: false + end + end +end diff --git a/test/dummy/db/schema.rb b/test/dummy/db/schema.rb new file mode 100644 index 0000000..0cb5f52 --- /dev/null +++ b/test/dummy/db/schema.rb @@ -0,0 +1,22 @@ +# encoding: UTF-8 +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 20160427131303) do + + create_table "somethings", force: :cascade do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + +end diff --git a/test/mountain_view/component_test.rb b/test/mountain_view/component_test.rb index a96ae80..0e5c2e6 100644 --- a/test/mountain_view/component_test.rb +++ b/test/mountain_view/component_test.rb @@ -128,4 +128,16 @@ def test_stubs? assert_equal false, component_without_stub_file.stubs? assert_equal false, component_with_empty_stub_file.stubs? end + + def test_component_stubs_pretty_json + component = MountainView::Component.new("form_custom_button") + component_properties = component.component_stubs.first + json = JSON.pretty_generate component_properties + + model_pattern = /Something.new\({:name=>"blabla"}\)/ + form_pattern = /form_for\(Something.new\({:name=>\"something name\"}\)\)/ + + assert_match(model_pattern, json) + assert_match(form_pattern, json) + end end diff --git a/test/mountain_view/presenter_test.rb b/test/mountain_view/presenter_test.rb index 57d9f18..6c34b24 100644 --- a/test/mountain_view/presenter_test.rb +++ b/test/mountain_view/presenter_test.rb @@ -35,4 +35,13 @@ class MountainView::PresenterTest < ActiveSupport::TestCase presenter = InheritedPresenter.new("inherited", {}) assert_equal [], presenter.data end + + test "loading of custom objects" do + component = MountainView::Component.new("form_custom_button") + stub_data = component.component_stubs.first + presenter = FormCustomButtonComponent.new("form_custom_button", stub_data) + assert_equal MountainView::Helpers::FormBuilder, presenter.form.class + assert_equal Something, presenter.some_model.class + assert_equal "blabla", presenter.some_model.name + end end diff --git a/test/test_helper.rb b/test/test_helper.rb index fd3f6f5..b1fd0ae 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -16,3 +16,5 @@ # for generators require "rails/generators/test_case" require "generators/mountain_view/component_generator" + +load "#{Rails.root}/db/schema.rb"