diff --git a/Gemfile b/Gemfile index d4b290e..3dde574 100644 --- a/Gemfile +++ b/Gemfile @@ -8,8 +8,12 @@ gem 'sprockets-rails', require: 'sprockets/railtie' gem 'rspec-rails' , require: "rspec-rails" gem 'haml-rails' , require: "haml-rails" gem "tailwindcss-rails" +gem "importmap-rails" +gem "sprockets-rails" group :development, :test do + gem "capybara" + gem 'guard-rspec', require: false end # Start debugger with binding.b [https://github.com/ruby/debug] diff --git a/Gemfile.lock b/Gemfile.lock index e2a710d..45a5648 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -77,15 +77,41 @@ GEM addressable (2.8.1) public_suffix (>= 2.0.2, < 6.0) builder (3.2.4) + capybara (3.38.0) + addressable + matrix + mini_mime (>= 0.1.3) + nokogiri (~> 1.8) + rack (>= 1.6.0) + rack-test (>= 0.6.3) + regexp_parser (>= 1.5, < 3.0) + xpath (~> 3.2) + coderay (1.1.3) concurrent-ruby (1.1.10) crass (1.0.6) diff-lcs (1.5.0) erubi (1.11.0) + ffi (1.15.5) + formatador (1.1.0) git (1.12.0) addressable (~> 2.8) rchardet (~> 1.8) globalid (1.0.0) activesupport (>= 5.0) + guard (2.18.0) + formatador (>= 0.2.4) + listen (>= 2.7, < 4.0) + lumberjack (>= 1.0.12, < 2.0) + nenv (~> 0.1) + notiffany (~> 0.0) + pry (>= 0.13.0) + shellany (~> 0.0) + thor (>= 0.18.1) + guard-compat (1.2.1) + guard-rspec (4.7.3) + guard (~> 2.1) + guard-compat (~> 1.1) + rspec (>= 2.99.0, < 4.0) haml (6.0.12) temple (>= 0.8.2) thor @@ -97,15 +123,24 @@ GEM railties (>= 5.1) i18n (1.12.0) concurrent-ruby (~> 1.0) + importmap-rails (1.1.5) + actionpack (>= 6.0.0) + railties (>= 6.0.0) + listen (3.7.1) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) loofah (2.19.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) + lumberjack (1.2.8) mail (2.7.1) mini_mime (>= 0.1.1) marcel (1.0.2) + matrix (0.4.2) method_source (1.0.0) mini_mime (1.1.2) minitest (5.16.3) + nenv (0.3.0) net-imap (0.3.1) net-protocol net-pop (0.1.2) @@ -117,6 +152,12 @@ GEM nio4r (2.5.8) nokogiri (1.13.9-x86_64-linux) racc (~> 1.4) + notiffany (0.1.3) + nenv (~> 0.1) + shellany (~> 0.0) + pry (0.14.1) + coderay (~> 1.1) + method_source (~> 1.0) public_suffix (5.0.0) racc (1.6.0) rack (2.2.4) @@ -149,7 +190,15 @@ GEM thor (~> 1.0) zeitwerk (~> 2.5) rake (13.0.6) + rb-fsevent (0.11.2) + rb-inotify (0.10.1) + ffi (~> 1.0) rchardet (1.8.0) + regexp_parser (2.6.1) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) rspec-core (3.12.0) rspec-support (~> 3.12.0) rspec-expectations (3.12.0) @@ -167,6 +216,7 @@ GEM rspec-mocks (~> 3.11) rspec-support (~> 3.11) rspec-support (3.12.0) + shellany (0.0.1) sprockets (4.1.1) concurrent-ruby (~> 1.0) rack (> 1, < 3) @@ -185,13 +235,18 @@ GEM websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) + xpath (3.2.0) + nokogiri (~> 1.8) zeitwerk (2.6.6) PLATFORMS x86_64-linux DEPENDENCIES + capybara + guard-rspec haml-rails + importmap-rails merged! rspec-rails sprockets-rails diff --git a/Guardfile b/Guardfile new file mode 100644 index 0000000..23074cd --- /dev/null +++ b/Guardfile @@ -0,0 +1,70 @@ +# A sample Guardfile +# More info at https://github.com/guard/guard#readme + +## Uncomment and set this to only include directories you want to watch +# directories %w(app lib config test spec features) \ +# .select{|d| Dir.exist?(d) ? d : UI.warning("Directory #{d} does not exist")} + +## Note: if you are using the `directories` clause above and you are not +## watching the project directory ('.'), then you will want to move +## the Guardfile to a watched dir and symlink it back, e.g. +# +# $ mkdir config +# $ mv Guardfile config/ +# $ ln -s config/Guardfile . +# +# and, you'll have to watch "config/Guardfile" instead of "Guardfile" + +# Note: The cmd option is now required due to the increasing number of ways +# rspec may be run, below are examples of the most common uses. +# * bundler: 'bundle exec rspec' +# * bundler binstubs: 'bin/rspec' +# * spring: 'bin/rspec' (This will use spring if running and you have +# installed the spring binstubs per the docs) +# * zeus: 'zeus rspec' (requires the server to be started separately) +# * 'just' rspec: 'rspec' + +guard :rspec, cmd: "bundle exec rspec" do + require "guard/rspec/dsl" + dsl = Guard::RSpec::Dsl.new(self) + + # Feel free to open issues for suggestions and improvements + + # RSpec files + rspec = dsl.rspec + watch(rspec.spec_helper) { rspec.spec_dir } + watch(rspec.spec_support) { rspec.spec_dir } + watch(rspec.spec_files) + + # Ruby files + ruby = dsl.ruby + dsl.watch_spec_files_for(ruby.lib_files) + + # Rails files + rails = dsl.rails(view_extensions: %w(erb haml slim)) + dsl.watch_spec_files_for(rails.app_files) + dsl.watch_spec_files_for(rails.views) + + watch(rails.controllers) do |m| + [ + rspec.spec.call("routing/#{m[1]}_routing"), + rspec.spec.call("controllers/#{m[1]}_controller"), + rspec.spec.call("acceptance/#{m[1]}") + ] + end + + # Rails config changes + watch(rails.spec_helper) { rspec.spec_dir } + watch(rails.routes) { "#{rspec.spec_dir}/routing" } + watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" } + + # Capybara features specs + watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") } + watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") } + + # Turnip features and steps + watch(%r{^spec/acceptance/(.+)\.feature$}) + watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m| + Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance" + end +end diff --git a/app/assets/config/merged_manifest.js b/app/assets/config/merged_manifest.js index c29cd21..e714dc9 100644 --- a/app/assets/config/merged_manifest.js +++ b/app/assets/config/merged_manifest.js @@ -1 +1 @@ -//= link ../stylesheets/merged .css +//= link_directory ../stylesheets/merged .css diff --git a/app/assets/stylesheets/merged/merged.css b/app/assets/stylesheets/merged/merged.css index 17bbc45..274630b 100644 --- a/app/assets/stylesheets/merged/merged.css +++ b/app/assets/stylesheets/merged/merged.css @@ -859,6 +859,18 @@ select { height: 6rem; } +.h-60 { + height: 15rem; +} + +.h-40 { + height: 10rem; +} + +.h-32 { + height: 8rem; +} + .w-6 { width: 1.5rem; } diff --git a/app/controllers/merged/styles_controller.rb b/app/controllers/merged/styles_controller.rb index 0447cdd..248c58f 100644 --- a/app/controllers/merged/styles_controller.rb +++ b/app/controllers/merged/styles_controller.rb @@ -2,8 +2,8 @@ module Merged class StylesController < MergedController def index - @sections = Style.sections - @cards = Style.cards + @sections = SectionStyle.sections + @cards = CardStyle.cards end end diff --git a/app/helpers/merged/merged_helper.rb b/app/helpers/merged/merged_helper.rb index 7a6ec8d..69f91dd 100644 --- a/app/helpers/merged/merged_helper.rb +++ b/app/helpers/merged/merged_helper.rb @@ -20,8 +20,20 @@ module Merged text end end + def button(text , url , color) + link_to(url) do + content_tag(:button , class: color + " " + button_classes ) do + text + end + end + end def button_classes "mr-3 inline-block rounded-lg px-4 py-3 text-md font-medium text-white" end + # section should be hash with at least 'template' key + def find_template(section) + "merged/view/" + section.template + end + end end diff --git a/app/helpers/merged/view_helper.rb b/app/helpers/merged/view_helper.rb index 8296bd7..f10d077 100644 --- a/app/helpers/merged/view_helper.rb +++ b/app/helpers/merged/view_helper.rb @@ -2,10 +2,6 @@ module Merged module ViewHelper include OptionsHelper include MergedHelper - # section should be hash with at least 'template' key - def find_template(section) - "merged/view/" + section.template - end # background image as inline style def bg(section , clazz = "") @@ -27,13 +23,5 @@ module Merged image_tag("#{Image.image_root}/#{element.image}" , class: classes) end - def button(text , url , color) - link_to(url) do - content_tag(:button , class: color + " " + button_classes ) do - text - end - end - end - end end diff --git a/app/models/merged/card.rb b/app/models/merged/card.rb index dd8948a..7426c2b 100644 --- a/app/models/merged/card.rb +++ b/app/models/merged/card.rb @@ -60,7 +60,7 @@ module Merged end def template_style - Style.cards[ section.card_template ] + CardStyle.cards[ section.card_template ] end def allowed_fields template_style.fields @@ -68,7 +68,7 @@ module Merged def self.build_data(card_template) data = { "id" => SecureRandom.hex(10) } - Style.cards[ card_template ].fields.each do |key| + CardStyle.cards[ card_template ].fields.each do |key| data[key] = key.upcase end data diff --git a/app/models/merged/option.rb b/app/models/merged/option.rb index 754ace5..a3d0c8f 100644 --- a/app/models/merged/option.rb +++ b/app/models/merged/option.rb @@ -1,6 +1,8 @@ module Merged class Option + @@options = {} + attr_reader :name , :default , :description def initialize(options) @@ -30,6 +32,10 @@ module Merged @values.split(" ") end + def self.options + @@options + end + def self.load(yaml) yaml.each do |content| option = Option.new(content) diff --git a/app/models/merged/section.rb b/app/models/merged/section.rb index 3972d5c..f09e129 100644 --- a/app/models/merged/section.rb +++ b/app/models/merged/section.rb @@ -49,7 +49,7 @@ module Merged end def template_style - Style.sections[ template ] + SectionStyle.sections[ template ] end def allowed_fields diff --git a/app/views/merged/sections/index.html.haml b/app/views/merged/sections/index.html.haml index 1ef59aa..dafde11 100644 --- a/app/views/merged/sections/index.html.haml +++ b/app/views/merged/sections/index.html.haml @@ -27,9 +27,9 @@ %h3.mt-4.text-lg.font-bold Header %p= section.header %h3.mt-4.text-lg.font-bold Text - %p= section.text[0..100] + " ..." + %p= section.text[0..100] + " ..." if section.text .relative.block.border.border-gray-100.p-4 - - if section.cards? + - if section.has_cards? %h3.mt-4.text-lg.font-bold #{section.content['cards'].length} Cards =link_to section_cards_url(section.id) do =card_preview(section , class: "w-full object-contain") @@ -37,7 +37,7 @@ = link_to(section_select_image_url(section.id)) do %h3.mt-4.text-lg.font-bold Image -if section.image - = image_tag "cms/" + section.image + = image_tag( "cms/" + section.image , class: "h-40") -else %p No image .relative.block.border.border-gray-100.p-4 diff --git a/app/views/merged/sections/show.html.haml b/app/views/merged/sections/show.html.haml index ff984f3..15c5832 100644 --- a/app/views/merged/sections/show.html.haml +++ b/app/views/merged/sections/show.html.haml @@ -40,7 +40,7 @@ = red_button( "Remove image", section_set_image_path( @section.id , image: "")) .grid.grid-cols-3.gap-2.m-8 - - if( @section.cards? ) + - if( @section.has_cards? ) .relative.block.border.border-gray-100 %h3.mt-4.text-lg.font-bold Card Template #{@section.card_template} =card_preview(@section , class: "w-full object-contain") diff --git a/app/views/merged/styles/index.haml b/app/views/merged/styles/index.haml index 60b6fa9..a402380 100644 --- a/app/views/merged/styles/index.haml +++ b/app/views/merged/styles/index.haml @@ -22,7 +22,7 @@ %h3.text-lg.font-medium.text-gray-900 Cards %p.mt-2.text-sm.leading-relaxed.text-gray-500.line-clamp-3 - -if(style.cards?) + -if(style.has_cards?) Section may include cards. See card styles below -else Section may not include cards diff --git a/config/merged/options.yaml b/config/merged/option.yaml similarity index 100% rename from config/merged/options.yaml rename to config/merged/option.yaml diff --git a/spec/features/merged/changes_spec.rb b/spec/features/merged/changes_spec.rb new file mode 100644 index 0000000..0712ff6 --- /dev/null +++ b/spec/features/merged/changes_spec.rb @@ -0,0 +1,11 @@ +require 'rails_helper' + +RSpec.feature "Changes", type: :feature do + describe "GET /changes" do + it "returns http success" do + visit "/merged/changes" + expect(page).to have_title("Merged") + expect(page).to have_text("Pages") + end + end +end diff --git a/spec/features/merged/images_spec.rb b/spec/features/merged/images_spec.rb new file mode 100644 index 0000000..49d47db --- /dev/null +++ b/spec/features/merged/images_spec.rb @@ -0,0 +1,11 @@ +require 'rails_helper' + +RSpec.feature "Images", type: :feature do + describe "GET /images" do + it "returns http success" do + visit "/merged/images" + expect(page).to have_title("Merged") + expect(page).to have_text("Pages") + end + end +end diff --git a/spec/features/merged/page_spec.rb b/spec/features/merged/page_spec.rb new file mode 100644 index 0000000..f571767 --- /dev/null +++ b/spec/features/merged/page_spec.rb @@ -0,0 +1,17 @@ +require 'rails_helper' + +RSpec.feature "Pages", type: :feature do + describe "GET /pages" do + it "returns http success" do + visit "/merged/pages" + expect(page).to have_title("Merged") + expect(page).to have_text("Pages") + end + end + describe "index page" do + it "returns http success" do + visit "/merged/pages" + click_on ("index") + end + end +end diff --git a/spec/features/merged/section_spec.rb b/spec/features/merged/section_spec.rb new file mode 100644 index 0000000..1255524 --- /dev/null +++ b/spec/features/merged/section_spec.rb @@ -0,0 +1,19 @@ +require 'rails_helper' + +RSpec.feature "Sections", type: :feature do + describe "index page" do + it "returns http success" do + visit "/merged/pages" + click_on ("index") + expect(page).to have_text("index") + expect(page).to have_text("Section 1") + end + end + describe "show page" do + it "returns http success" do + visit "/merged/pages" + click_on ("index") + find_link("Edit").click + end + end +end diff --git a/spec/features/merged/style_spec.rb b/spec/features/merged/style_spec.rb new file mode 100644 index 0000000..aeb6166 --- /dev/null +++ b/spec/features/merged/style_spec.rb @@ -0,0 +1,11 @@ +require 'rails_helper' + +RSpec.feature "Styles", type: :feature do + describe "GET /styles" do + it "returns http success" do + visit "/merged/styles/index" + expect(page).to have_title("Merged") + expect(page).to have_text("Pages") + end + end +end diff --git a/spec/models/merged/option_spec.rb b/spec/models/merged/option_spec.rb new file mode 100644 index 0000000..29165ca --- /dev/null +++ b/spec/models/merged/option_spec.rb @@ -0,0 +1,17 @@ +require 'rails_helper' + +module Merged + RSpec.describe Option, type: :model do + let(:first) {Option.options.values.first} + + it "has Option.options" do + expect(Option.options.class).to be Hash + end + it "there are options" do + expect(Option.options.length).to be 12 + end + it "has option objects" do + expect(first.class).to be Option + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a0d4080..386e952 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,4 @@ +require 'capybara/rspec' # This file was generated by the `rails generate rspec:install` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # The generated `.rspec` file contains `--require spec_helper` which will cause