From c1d01dc40f7c3dd70185898b82bdedfcde5205df Mon Sep 17 00:00:00 2001 From: yasushiito Date: Sat, 19 Oct 2013 16:54:58 +0900 Subject: [PATCH] t#32246:add sheet --- app/assets/javascripts/application.js | 2 + app/assets/javascripts/pettanr_sheeter.js.coffee | 89 +++++++ app/assets/javascripts/sheets.js.coffee | 294 ++--------------------- app/controllers/sheets_controller.rb | 21 +- app/models/sheet.rb | 141 +++++++++++ app/models/sheet_panel.rb | 135 ++++++++++- app/views/sheet_panels/_element.html.erb | 6 + app/views/sheet_panels/_element_face.html.erb | 8 + app/views/sheet_panels/_form.html.erb | 42 ++-- app/views/sheet_panels/_play_header.html.erb | 41 ++-- app/views/sheet_panels/_scenario.html.erb | 3 + app/views/sheet_panels/edit.html.erb | 2 +- app/views/sheet_panels/new.html.erb | 2 +- app/views/sheets/_body.html.erb | 10 +- app/views/sheets/_element_tab.html.erb | 8 + app/views/sheets/_form.html.erb | 110 +++++++-- app/views/sheets/_standard.html.erb | 6 +- app/views/sheets/edit.html.erb | 14 +- app/views/sheets/new.html.erb | 14 +- app/views/sheets/play.html.erb | 6 +- app/views/sheets/show.html.erb | 39 +-- config/locales/pettanr.ja.yml | 2 + spec/controllers/sheets_controller_spec.rb | 95 ++++---- spec/models/sheet_panel_spec.rb | 42 ---- spec/models/sheet_spec.rb | 187 ++++++++++++++ 25 files changed, 829 insertions(+), 490 deletions(-) create mode 100644 app/assets/javascripts/pettanr_sheeter.js.coffee create mode 100644 app/views/sheet_panels/_element.html.erb create mode 100644 app/views/sheet_panels/_element_face.html.erb create mode 100644 app/views/sheet_panels/_scenario.html.erb create mode 100644 app/views/sheets/_element_tab.html.erb diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 26e94c06..ce8c00b4 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -9,8 +9,10 @@ //= require jquery.ui.all //= require textchange //= require pettanr_editor +//= require pettanr_sheeter //= require writing_formats //= require_directory ./helpers //= require speech_balloon_templates //= require panels +//= require sheets // require_tree . diff --git a/app/assets/javascripts/pettanr_sheeter.js.coffee b/app/assets/javascripts/pettanr_sheeter.js.coffee new file mode 100644 index 00000000..51afc3d0 --- /dev/null +++ b/app/assets/javascripts/pettanr_sheeter.js.coffee @@ -0,0 +1,89 @@ +class PettanrSheeter + @pettanr_current_sheet_id = 0 + + @new_element_index = {} + @new_element_index[PettanrSheeter.pettanr_current_sheet_id] = 0 + + @current_sheet = () -> + $('#sheet' + PettanrSheeter.pettanr_current_sheet_id.toString()) + + @set_tree_value = (keys, last_attr, value) -> + key = keys.shift() + if keys.length <= 0 + last_attr[key] = value + else + last_attr[key] = last_attr[key] || {} + PettanrSheeter.set_tree_value(keys, last_attr[key], value) + + @is_editting = () -> + trace = '#sheet' + PettanrSheeter.pettanr_current_sheet_id.toString() + 'wrapper' + if $(trace) and $(trace).attr('editable') + return true + else + return false + @is_editable = (p) -> + if p.parent().attr('editable') + return true + else + return false + @is_var = (o) -> + if parseInt(o.attr('no_attr')) > 0 + return false + else + if o.attr('column') + if o.attr('column') == '_destroy' and o.val().length < 1 + return false + else + return true + else + return false + @is_element = (o) -> + if o.attr('element_type') + return true + else + return false + @is_element_part = (o) -> + if o.attr('element_part_type') + return true + else + return false + @element_is = (element_type, o) -> + if PettanrSheeter.is_element(o) and o.attr('element_type') == element_type + return true + else + return false + @element_types = {'sheet_panel': 'sheet_panels'} + @element_type_to_table = (element_type) -> + PettanrSheeter.element_types[element_type] + + @make_tree = (attr, o) -> + if PettanrSheeter.is_var(o) + tree = 'sheets-' + o.attr('sheet_id') + '-' + if PettanrSheeter.is_element(o) + tree = tree + PettanrSheeter.element_type_to_table(o.attr('element_type')) + '_attributes-' + o.attr('element_id') + '-' + if PettanrSheeter.is_element_part(o) + tree = tree + o.attr('element_part_type') + '_attributes-' + tree = tree + o.attr('column') + keys = tree.split('-') + PettanrSheeter.set_tree_value(keys, attr, o.val()) + + @sheet_tag_id = (element) -> + '#sheet' + element.attr('sheet_id') + + @element_tag_id = (element) -> + '#sheet' + element.attr('sheet_id') + element.attr('element_type') + element.attr('element_id') + + @element_part_tag_id = (element_part) -> + '#sheet' + element_part.attr('sheet_id') + element_part.attr('element_type') + element_part.attr('element_id') + element_part.attr('element_part_type') + element_part.attr('element_part_id') + + @refresh_attribute = (field) -> + attr = {} + $('input').map -> + PettanrSheeter.make_tree(attr, $(@)) + $('textarea').map -> + PettanrSheeter.make_tree(attr, $(@)) + $('select').map -> + PettanrSheeter.make_tree(attr, $(@)) + field.val(JSON.stringify(attr['sheets'][PettanrSheeter.pettanr_current_sheet_id.toString() ])) + +@PettanrSheeter = PettanrSheeter diff --git a/app/assets/javascripts/sheets.js.coffee b/app/assets/javascripts/sheets.js.coffee index 634a64ff..c9ebf21b 100644 --- a/app/assets/javascripts/sheets.js.coffee +++ b/app/assets/javascripts/sheets.js.coffee @@ -1,11 +1,11 @@ $ -> confirm_confirm_confirm = () -> confirm( ) - editor = window.PettanrEditor + editor = window.PettanrSheeter - $('.panel-editor').map -> + $('.sheet-editor').map -> if $(@).attr('current') and parseInt($(@).attr('current')) > 0 - editor.pettanr_current_panel_id = parseInt($(@).attr('panel_id')) + editor.pettanr_current_sheet_id = parseInt($(@).attr('sheet_id')) if editor.is_editting() $('#tabs').tabs() $('#elements-tabs').tabs() @@ -17,12 +17,9 @@ $ -> $("#elements-tabs li").map -> $(@).mouseover -> switch $(@).attr('element_type') - when 'speech_balloon' + when 'sheet_panel' trace = editor.element_tag_id($(@)) - t = $('img', $(trace)) - when 'panel_picture' - trace = editor.element_tag_id($(@)) + 'img' - t = $(trace) + t = $('.pettanr-comic-panel', $(trace)) else t = null if t @@ -30,12 +27,9 @@ $ -> $(@).css('display', 'block') $(@).mouseout -> switch $(@).attr('element_type') - when 'speech_balloon' + when 'sheet_panel' trace = editor.element_tag_id($(@)) - t = $('img', $(trace)) - when 'panel_picture' - trace = editor.element_tag_id($(@)) + 'img' - t = $(trace) + t = $('.pettanr-comic-panel', $(trace)) else t = null if t @@ -55,9 +49,9 @@ $ -> if confirm('destroy ?') trace = editor.element_tag_id($(@)) $(trace + '_destroy').val('true') - panel_trace = editor.panel_tag_id($(@)) - update_t(panel_trace + 'tsort') - update_z(panel_trace + 'zsort') + sheet_trace = editor.panel_tag_id($(@)) + update_t(sheet_trace + 'tsort') + update_z(sheet_trace + 'zsort') # sync $(trace + 'element_tab').css('display', 'none') $(trace + 'tab_panel').css('display', 'none') @@ -69,25 +63,19 @@ $ -> $(trace).css('display', 'none') - $('#pettanr-panel-submit').focusin -> - editor.refresh_attribute($('#pettanr-panel-json')) + $('#pettanr-sheet-submit').focusin -> + editor.refresh_attribute($('#pettanr-sheet-json')) - # panel - $('.pettanr-comic-panel').map -> + # sheet + $('.sheet').map -> if editor.is_editable($(@)) $(@).resizable { stop: ( event, ui ) -> - trace = editor.panel_tag_id($(@)) + trace = editor.sheet_tag_id($(@)) w = parseInt($(@).width()) h = parseInt($(@).height()) $(trace + 'width').val(w) $(trace + 'height').val(h) - $('.pettanr-comic-ground-picture').map -> - $(@).width(w) - $(@).height(h) - $('.pettanr-comic-ground-color').map -> - $(@).width(w) - $(@).height(h) , autoHide: true } @@ -95,168 +83,30 @@ $ -> $('input').map -> if $(@).attr('element_type') else - if $(@).attr('panel_id') + if $(@).attr('sheet_id') $(@).focusout -> switch $(@).attr('column') when 'width' - trace = editor.panel_tag_id($(@)) + trace = editor.sheet_tag_id($(@)) $(trace).width(parseInt( $(@).val())) when 'height' - trace = editor.panel_tag_id($(@)) + trace = editor.sheet_tag_id($(@)) $(trace).height(parseInt( $(@).val())) - when 'border' - trace = editor.panel_tag_id($(@)) - $(trace).css('border-width', parseInt($(@).val()).toString() + 'px') - # panel picture - PictureSizeHelper.add_helper() - - $('.pettanr-panel-picture-wrapper').map -> + $('.sheet_panel').map -> $(@).draggable { stop: ( event, ui ) -> trace = editor.element_tag_id($(@)) - img = $(trace + 'img') - left = img.parent().position().left + $(@).position().left - top = img.parent().position().top + $(@).position().top - $(trace + 'x').val(parseInt(left)) - $(trace + 'y').val(parseInt(top)) - } - - $('.panel-picture').map -> - $(@).resizable { - stop: ( event, ui ) -> - resize_div = $(@) - panel_picture_div = resize_div.parent() - trace = editor.element_tag_id(panel_picture_div) - - resize_div.css('top', '0px') - resize_div.css('left', '0px') - if ui.originalPosition.top != ui.position.top - t = panel_picture_div.position().top + ui.position.top - $(trace + 'y').val(Math.floor(t)) - panel_picture_div.css('top', t.toString() + 'px') - if ui.originalPosition.left != ui.position.left - l = panel_picture_div.position().left + ui.position.left - $(trace + 'x').val(Math.floor(l)) - panel_picture_div.css('left', l.toString() + 'px') - w = if $(trace + 'width').val() < 0 - -ui.size.width - else - ui.size.width - h = if $(trace + 'height').val() < 0 - -ui.size.height - else - ui.size.height - $(trace + 'width').val(w) - $(trace + 'height').val(h) - resize: ( event, ui ) -> - resize_div = $(@) - panel_picture_div = resize_div.parent() - trace = editor.element_tag_id(panel_picture_div) - handles: 'all', - autoHide: true - } - - # sync view - $('input').map -> - if editor.element_is('panel_picture', $(@)) - $(@).focusout -> - switch $(@).attr('column') - when 'x' - trace = editor.element_tag_id($(@)) + 'div' - v = parseInt($(@).val()).toString() + 'px' - $(trace).css('left', v) - when 'y' - trace = editor.element_tag_id($(@)) + 'div' - v = parseInt($(@).val()).toString() + 'px' - $(trace).css('top', v) - when 'width' - trace = editor.element_tag_id($(@)) + 'img' - w = parseInt($(@).val()) - $(trace).width(Math.abs(w)) - $(trace).parent().width(Math.abs(w)) - h = parseInt($(editor.element_tag_id($(@)) + 'height').val()) - when 'height' - trace = editor.element_tag_id($(@)) + 'img' - h = parseInt($(@).val()) - $(trace).height(Math.abs(h)) - $(trace).parent().height(Math.abs(h)) - w = parseInt($(editor.element_tag_id($(@)) + 'width').val()) - else - PictureSizeHelper.refresh_picture($(trace), w, h) - else - - # speech_balloons - ColorHelper.add_helper($('.speech-fore_color-wrap'), 'fore_color') - - $('.pettanr-comic-balloon' ).map -> - $(@).draggable { - stop: ( event, ui ) -> - balloon = $('.pettanr-balloon', $(@)) - trace = editor.element_part_tag_id(balloon) left = $(@).position().left top = $(@).position().top $(trace + 'x').val(parseInt(left)) $(trace + 'y').val(parseInt(top)) + , cursor: "crosshair" } - $('.pettanr-balloon' ).map -> - $(@).resizable { - stop: ( event, ui ) -> - resize_div = $(@) - speech_balloon_div = resize_div.parent() - balloon = $('.pettanr-balloon', $(@)) - trace = editor.element_tag_id(speech_balloon_div) - trace_balloon = editor.element_part_tag_id(balloon) - - resize_div.css('top', '0px') - resize_div.css('left', '0px') - w = ui.size.width - h = ui.size.height - if ui.originalPosition.top != ui.position.top - t = speech_balloon_div.position().top + ui.position.top - $(trace_balloon + 'y').val(Math.floor(t)) - speech_balloon_div.css('top', t.toString() + 'px') - speech_balloon_div.css('height', h + 'px') - if ui.originalPosition.left != ui.position.left - l = speech_balloon_div.position().left + ui.position.left - $(trace_balloon + 'x').val(Math.floor(l)) - speech_balloon_div.css('left', l.toString() + 'px') - speech_balloon_div.css('width', w + 'px') - $(trace_balloon + 'width').val(w) - $(trace_balloon + 'height').val(h) - speech_balloon_div.css('width', w.toString() + 'px') - speech_balloon_div.css('height', h.toString() + 'px') - resize: ( event, ui ) -> - resize_div = $(@) - speech_balloon_div = resize_div.parent() - balloon = $('.pettanr-balloon', $(@)) - trace = editor.element_tag_id(speech_balloon_div) - trace_balloon = editor.element_part_tag_id(balloon) - handles: 'all', - autoHide: true - } - - $('.pettanr-comic-speech-inner' ).map -> - $(@).mouseover -> - outer = $(@).parent() - sb = outer.parent() - trace = editor.element_tag_id(sb) - img = $('.pettanr-balloon', $(trace)) - $('.ui-resizable-handle', img.parent()).map -> - $(@).css('display', 'block') - $(@).mouseout -> - outer = $(@).parent() - sb = outer.parent() - trace = editor.element_tag_id(sb) - img = $('.pettanr-balloon', $(trace)) - $('.ui-resizable-handle', img.parent()).map -> - $(@).css('display', 'none') - - # sync view $('input').map -> - if editor.element_is('speech_balloon', $(@)) + if editor.element_is('sheet_panel', $(@)) $(@).focusout -> switch $(@).attr('column') when 'x' @@ -267,92 +117,9 @@ $ -> trace = editor.element_tag_id($(@)) v = parseInt($(@).val()).toString() + 'px' $(trace).css('top', v) - when 'width' - trace = editor.element_tag_id($(@)) - v = parseInt($(@).val()) - $(trace).width(Math.abs(v)) - img = $('.pettanr-balloon', $(trace)) - img.parent().width(v) - img.width(v) - when 'height' - trace = editor.element_tag_id($(@)) - v = parseInt($(@).val()) - $(trace).height(Math.abs(v)) - img = $('.pettanr-balloon', $(trace)) - img.parent().height(v) - img.height(v) else else - $('textarea').map -> - if editor.element_is('speech_balloon', $(@)) - $(@).focusout -> - switch $(@).attr('column') - when 'content' - trace = editor.element_part_tag_id($(@)) - wf_sel = $(trace + 'writing_format_id') - wf_id = parseInt(wf_sel.val()) - v = WritingFormat.render(wf_id, $(@).val()) - $(trace).html(v) - $('textarea').map -> - if editor.element_is('speech_balloon', $(@)) - switch $(@).attr('column') - when 'content' - $(@).bind('textchange', (event, previousText) -> - trace = editor.element_part_tag_id($(@)) - wf_sel = $(trace + 'writing_format_id') - wf_id = parseInt(wf_sel.val()) - v = WritingFormat.render(wf_id, $(@).val()) - $(trace).html(v) - ) - $('select').map -> - if editor.element_is('speech_balloon', $(@)) - $(@).change -> - switch $(@).attr('column') - when 'font_size' - trace = editor.element_part_tag_id($(@)) - $(trace).css('font-size', $(@).val() + 'em') - when 'text_align' - trace = editor.element_part_tag_id($(@)) - v = parseInt($(@).val()) - $(trace).css('text-align', editor.text_align_texts[v]) - else - $('input').map -> - if editor.element_is('speech_balloon', $(@)) - if $(@).attr('column') == 'fore_color' - $(@).hide() - - - # ground-picture - # sync view - $('input').map -> - if editor.element_is('ground_picture', $(@)) - $(@).focusout -> - switch $(@).attr('column') - when 'x', 'y' - trace = editor.element_tag_id($(@)) - x = parseInt($(trace + 'x').val()).toString() + 'px' - y = parseInt($(trace + 'y').val()).toString() + 'px' - $(trace).css('background-position', x + ' ' + y) - $('select').map -> - if editor.element_is('ground_picture', $(@)) - $(@).change -> - switch $(@).attr('column') - when 'repeat' - trace = editor.element_tag_id($(@)) - v = parseInt($(@).val()) - $(trace).css('background-repeat', editor.repeat_texts[v]) - else - - # ground_color - ColorHelper.add_helper($('.ground_color-code-wrap'), 'code') - - # sync view - $('input').map -> - if editor.element_is('ground_color', $(@)) - if $(@).attr('column') == 'code' - $(@).hide() - update_t = (ultrace) -> t = 0 $(ultrace + ' li').map -> @@ -365,7 +132,7 @@ $ -> $('.tsort').map -> $(@).sortable { update: ( event, ui ) -> - trace = editor.panel_tag_id($(@)) + trace = editor.sheet_tag_id($(@)) update_t(trace + 'tsort') } $('.t-sort li').map -> @@ -388,7 +155,7 @@ $ -> $('.zsort').map -> $(@).sortable { update: ( event, ui ) -> - trace = editor.panel_tag_id($(@)) + trace = editor.sheet_tag_id($(@)) update_z(trace + 'zsort') } $('.z-sort li').map -> @@ -396,21 +163,8 @@ $ -> # all # disable form actions - # hide submit buttons - $('.edit_panel_picture' ).map -> - $(@).submit -> - false - $('.edit_speech_balloon' ).map -> - $(@).submit -> - false - $('.edit_ground_picture' ).map -> - $(@).submit -> - false - $('.edit_ground_color' ).map -> - $(@).submit -> - false - $('.edit_panel' ).map -> + $('.edit_sheet' ).map -> if $(@).attr('jqform') else $(@).submit -> diff --git a/app/controllers/sheets_controller.rb b/app/controllers/sheets_controller.rb index 6ab261d5..29857987 100644 --- a/app/controllers/sheets_controller.rb +++ b/app/controllers/sheets_controller.rb @@ -41,14 +41,13 @@ class SheetsController < ApplicationController def play @sheet = Sheet.show(params[:id], [@user, @admin]) - @sheet_panels = SheetPanel.play_list(@sheet, @author) respond_to do |format| format.html { if @author @new_panels = Panel.mylist(@author, 1, 5) end } - format.json {render text: SheetPanel.list_as_json_text(@sheet_panels, @author)} + format.json {render json: @sheet.to_json(Sheet.show_json_opt)} format.jsonp { render :json => "callback(" + @sheet_panels.to_json_list + ");" } @@ -101,11 +100,14 @@ class SheetsController < ApplicationController def create @sheet = Sheet.new @sheet.supply_default - @sheet.attributes = params[:sheet] - @sheet.overwrite @author + jsn = nil + if params[:json] + jsn = JSON.parse_no_except(params[:json]) + end + @prm = params[:sheet] || jsn respond_to do |format| - if @sheet.save + if @sheet.store @prm, @author flash[:notice] = I18n.t('flash.notice.created', :model => Sheet.model_name.human) format.html { redirect_to @sheet } format.json { render json: @sheet.to_json(Sheet.show_json_opt), status: :created, location: @sheet } @@ -119,10 +121,13 @@ class SheetsController < ApplicationController def update @sheet = Sheet.edit(params[:id], @author) - @sheet.attributes = params[:sheet] - @sheet.overwrite @author + jsn = nil + if params[:json] + jsn = JSON.parse(params[:json]) + end + @prm = params[:sheet] || jsn respond_to do |format| - if @sheet.save + if @sheet.store @prm, @author flash[:notice] = I18n.t('flash.notice.updated', :model => Sheet.model_name.human) format.html { redirect_to @sheet } format.json { head :ok } diff --git a/app/models/sheet.rb b/app/models/sheet.rb index eb9cd351..afe4b8d6 100644 --- a/app/models/sheet.rb +++ b/app/models/sheet.rb @@ -7,6 +7,7 @@ class Sheet < ActiveRecord::Base validates :width, :presence => true, :numericality => true, :natural_number => true validates :height, :presence => true, :numericality => true, :natural_number => true validates :visible, :presence => true, :numericality => true, :inclusion => {:in => 0..1} + accepts_nested_attributes_for :sheet_panels, :allow_destroy => true before_validation :valid_encode def valid_encode @@ -16,6 +17,27 @@ class Sheet < ActiveRecord::Base end end + def self.each_element_class_names + {'SheetPanel' => 'sheet_panels'}.each do |k, n| + yield k + end + end + + def self.class_name_to_class k + Object.const_get k + end + + def self.each_element_classes + self.each_element_class_names do |k| + e = self.class_name_to_class k + yield e + end + end + + def elements_by_class_name class_name + self.__send__ class_name.tableize + end + def supply_default self.visible = 0 if self.visible.blank? end @@ -46,6 +68,18 @@ class Sheet < ActiveRecord::Base visible? au end + def tag_id + 'sheet' + self.tag_sheet_id + end + + def tag_sheet_id + self.new_record? ? '0' : self.id.to_s + end + + def field_tag_id f + self.tag_id + f.to_s + end + def self.default_page_size 25 end @@ -143,10 +177,109 @@ class Sheet < ActiveRecord::Base {:include => {:sheet_panels => {:include => {:panel => {}}}, :author => {}}} end + def parts_element + r = [] + self.class.each_element_class_names do |k| + r += (self.elements_by_class_name(k) || []) + end + r + end + + def zorderd_elements + res = [] + self.parts_element.each do |e| + res[e.z-1] = e + end + res + end + + def sheet_elements + res = [] + self.parts_element.each do |e| + res[e.t] = e + end + res + end + + def new_t + self.sheet_elements.size + end + + def new_z + self.sheet_elements.size + 1 + end + def self.visible_count Sheet.count 'visible > 0' end + def self.collect_element_value elements, name + elements.map {|e| + e.map {|o| + if o['_destroy'] or o[:_destroy] + nil + else + o[name] + end + }.compact + }.flatten + end + + def self.validate_serial ary, offset = 0 + i = offset + ary.compact.sort.each do |n| + break false unless n == i + i += 1 + end + ary.compact.size == i - offset + end + + def self.validate_element_serial elements, name, offset = 0 + Sheet.validate_serial(Sheet.collect_element_value(elements, name), offset) + end + + def self.validate_elements_serial c + c.map {|conf| + Sheet.validate_element_serial(conf[:elements], conf[:name], conf[:offset]) ? nil : false + }.compact.empty? + end + + def validate_serial_list + l = [] + self.class.each_element_class_names do |k| + l << self.elements_by_class_name(k) + end +# l = [self.sheet_panels] + [ + {:elements => l, :name => :t, :offset => 0}, + {:elements => l, :name => :z, :offset => 1} + ] + end + + def validate_child +# r1 = Panel.validate_elements_id validate_id_list + Sheet.validate_elements_serial validate_serial_list + end + + def store attr, au + if attr == false + self.errors.add :base, I18n.t('errors.invalid_json') + return false + end + self.attributes = attr + self.overwrite au + res = false + Sheet.transaction do + res = self.save + unless validate_child + res = false + self.errors.add :base, I18n.t('errors.invalid_t') + raise ActiveRecord::Rollback + end + end + res + end + def destroy_with_sheet_panel res = false Sheet.transaction do @@ -171,4 +304,12 @@ class Sheet < ActiveRecord::Base }.join end + def licensed_pictures + r = {} + self.sheet_elements.each do |elm| + r.merge!(elm.licensed_pictures) + end + r + end + end diff --git a/app/models/sheet_panel.rb b/app/models/sheet_panel.rb index 6eb7c72c..2612c562 100644 --- a/app/models/sheet_panel.rb +++ b/app/models/sheet_panel.rb @@ -16,8 +16,13 @@ class SheetPanel < ActiveRecord::Base self.panel_id = nil self.x = 15 self.y = 15 - self.z = 1 - self.t = nil + if self.sheet + self.t = self.sheet.new_t + self.z = self.sheet.new_z + else + self.z = 1 + self.t = nil + end end def overwrite au @@ -182,12 +187,12 @@ class SheetPanel < ActiveRecord::Base '[' + ary.map {|i| i.sheet_panel_as_json(au) }.join(',') + ']' end - def self.licensed_pictures sheet_panels - r = {} - sheet_panels.each do |sheet_panel| - r.merge!(sheet_panel.panel.licensed_pictures) if sheet_panel.panel + def licensed_pictures + if self.panel + self.panel.licensed_pictures + else + [] end - r end def self.new_t sheet_id @@ -296,4 +301,120 @@ class SheetPanel < ActiveRecord::Base res end + # element.rb + def self.colum_structures + @@colum_structures ||= { + } + end + + def self.path_name with_engine = false + self.to_s.tableize + end + + def new_index + @new_index + end + + def new_index= v + @new_index = v + end + + def new_sheet + @new_sheet + end + + def new_sheet= v + @new_sheet = v + end + + def get_sheet + self.sheet || @new_sheet + end + + def tag_id c = nil + 'sheet' + self.tag_sheet_id + self.tag_element_type + self.tag_element_id + c.to_s + end + + def field_tag_id f + self.tag_id + f.to_s + end + + def tag_sheet_id + self.get_sheet.new_record? ? '0' : self.get_sheet.id.to_s + end + + def tag_element_id + self.new_record? ? '0' : self.id.to_s + end + + def tag_element_type + 'sheet_panel' + end + + def tag_new_index + self.new_index.to_s + end + + def path_name with_engine = false + self.class.path_name(with_engine) + end + + def form_template with_engine = false + self.path_name(with_engine) + '/form' + end + + def scenario_template with_engine = false + self.path_name(with_engine) + '/scenario' + end + + def element_face_template with_engine = false + self.path_name(with_engine) + '/element_face' + end + + def form_helper_template(colum_name) + self.class.colum_structures[colum_name][:helper] + end + + def tag_attributes column = nil, opt = {} + { + :id => self.field_tag_id(column), :sheet_id => self.tag_sheet_id, + :element_id => self.tag_element_id, :element_type => self.tag_element_type + }.merge(opt) + end + + def field_tag_attributes column, no_attr, opt = {} + self.tag_attributes(column).merge( + {:column => column, :new_index => self.tag_new_index, :no_attr => no_attr} + ).merge(opt) + end + + #render element by body + def any_tag_attributes name = nil, opt = {} + r = self.tag_attributes(name) + r.merge!( + {:new_index => self.tag_new_index} + ) if self.new_index + r.merge(opt) + end + + def select_tag_attributes(selected, column, no_attr) + [ + :last, :first, + {:html => {:selected => selected}}, + self.field_tag_attributes(column, no_attr) + ] + end + + def tag_attr column = nil, opt = {} + self.tag_attributes(column, opt).to_attr + end + + def field_tag_attr column, no_attr, opt = {} + self.field_tag_attributes(column, no_attr, opt).to_attr + end + + def any_tag_attr name = nil, opt = {} + self.any_tag_attributes(name, opt).to_attr + end + end diff --git a/app/views/sheet_panels/_element.html.erb b/app/views/sheet_panels/_element.html.erb new file mode 100644 index 00000000..56e44e40 --- /dev/null +++ b/app/views/sheet_panels/_element.html.erb @@ -0,0 +1,6 @@ +
class="sheet_panel" style="top:<%= elm.y %>px; left:<%= elm.x %>px; z-index:<%= elm.z %>;"> + <% panel = Panel.show elm.panel, author -%> + <% if panel -%> + <%= render 'panels/body', :panel => panel, :author => author, :spot => nil %> + <% end %> +
diff --git a/app/views/sheet_panels/_element_face.html.erb b/app/views/sheet_panels/_element_face.html.erb new file mode 100644 index 00000000..a1d3a1e8 --- /dev/null +++ b/app/views/sheet_panels/_element_face.html.erb @@ -0,0 +1,8 @@ +
+ <%= panel_icon(:object => elm.panel, :size => 64) %> +
+ + <%= h(truncate(elm.panel.caption, :length => 15)) -%> + +
+
diff --git a/app/views/sheet_panels/_form.html.erb b/app/views/sheet_panels/_form.html.erb index 238fe21e..6f178a8d 100644 --- a/app/views/sheet_panels/_form.html.erb +++ b/app/views/sheet_panels/_form.html.erb @@ -1,32 +1,28 @@ -<%= form_for(@sheet_panel) do |f| %> - <%= render 'system/error_explanation', :obj => @sheet_panel %> +<%= form_for(elm) do |f| %> + <%= render 'system/error_explanation', :obj => elm %>
- <%= f.label :sheet_id %>
- <%= f.number_field :sheet_id %> -
-
- <%= f.label :x %>
- <%= f.number_field :x %> -
-
- <%= f.label :y %>
- <%= f.number_field :y %> -
-
- <%= f.label :z %>
- <%= f.number_field :z %> -
-
- <%= f.label :t %>
- <%= f.number_field :t %> + <%= f.label :x %> + <%= f.number_field :x, elm.field_tag_attributes(:x, no_attr, :size => 5) %> + + <%= f.label :y %> + <%= f.number_field :y, elm.field_tag_attributes(:y, no_attr, :size => 5) %>
- <%= f.label :panel_id %>
- <%= f.number_field :panel_id %> + <%= f.label :z %> + <%= f.number_field :z, elm.field_tag_attributes(:z, no_attr, :size => 5) %> + + <%= f.label :t %> + <%= f.number_field :t, elm.field_tag_attributes(:t, no_attr, :size => 5) %>
+ <%= f.hidden_field :panel_id, elm.field_tag_attributes(:panel_id, no_attr) %> + <%= f.hidden_field :sheet_id, elm.field_tag_attributes(:sheet_id, no_attr) %> + <% unless elm.new_record? %> + <%= f.hidden_field :id, elm.field_tag_attributes(:id, no_attr) %> + <% end %> +
- <%= f.submit %> + <%= f.submit t('sheet_panels.submit'), :class => "submit" %>
<% end %> diff --git a/app/views/sheet_panels/_play_header.html.erb b/app/views/sheet_panels/_play_header.html.erb index 09251ee0..6743faa3 100644 --- a/app/views/sheet_panels/_play_header.html.erb +++ b/app/views/sheet_panels/_play_header.html.erb @@ -1,21 +1,20 @@ -<% if sheet.own? author -%> - <%= form_for(sheet) do |f| %> -
- <%= f.label :caption %>
- <%= f.text_field :caption %> -
-
- <%= f.label :visible %>
- <%= f.collection_select :visible, t_select_items(MagicNumber['sheet_visible_items']), :last, :first, :html => {:selected => @sheet.visible} %> -
-
- <%= f.submit %> -
- <% end %> -<% else %> -<% end %> - -
- <%= link_to author_icon(:object => sheet.author, :size => 25), author_path(sheet.author) %> - <%= link_to h(truncate(sheet.author.name, :length => 12)), author_path(sheet.author) %> -
+

+ <%= link_to sheet_icon(:object => sheet, :size => 25), sheet_path(sheet) %> + <%= link_to h(sheet.caption), play_sheet_path(sheet) %> +

+ + + + + + +
+ + <%= link_to author_icon(:object => sheet.author, :size => 17), author_path(sheet.author) %> + <%= link_to h(truncate(sheet.author.name, :length => 12)), play_sheet_path(sheet.author) %> + + <% if sheet.own? author %> + <%= link_to t('link.edit'), edit_sheet_path(sheet) %> + <%= link_to t('link.destroy'), sheet_path(sheet), :method => :delete %> + <% end %> +
diff --git a/app/views/sheet_panels/_scenario.html.erb b/app/views/sheet_panels/_scenario.html.erb new file mode 100644 index 00000000..e63b7535 --- /dev/null +++ b/app/views/sheet_panels/_scenario.html.erb @@ -0,0 +1,3 @@ +
+ <%= %> +
diff --git a/app/views/sheet_panels/edit.html.erb b/app/views/sheet_panels/edit.html.erb index 1d67f75e..1264b234 100644 --- a/app/views/sheet_panels/edit.html.erb +++ b/app/views/sheet_panels/edit.html.erb @@ -1,4 +1,4 @@

<%= t('.title') %>

<%= notice %>

-<%= render 'form' %> +<%= render @sheet_panel.form_template, :elm => @sheet_panel, :no_attr => 0 %> diff --git a/app/views/sheet_panels/new.html.erb b/app/views/sheet_panels/new.html.erb index f33a2f89..0a817c8b 100644 --- a/app/views/sheet_panels/new.html.erb +++ b/app/views/sheet_panels/new.html.erb @@ -1,3 +1,3 @@

<%= t('.title') %>

-<%= render 'form' %> +<%= render @sheet_panel.form_template, :elm => @sheet_panel, :no_attr => 0 %> diff --git a/app/views/sheets/_body.html.erb b/app/views/sheets/_body.html.erb index d7f2ba92..cdc19f27 100644 --- a/app/views/sheets/_body.html.erb +++ b/app/views/sheets/_body.html.erb @@ -1,11 +1,7 @@ -
+
<% if sheet.visible? author -%> - <% sheet_panels.each do |sheet_panel| %> -
- <% if sheet_panel.panel -%> - <%= render 'panels/body', :panel => sheet_panel.panel, :author => author, :spot => nil %> - <% end %> -
+ <% sheet.sheet_elements.each do |elm| %> + <%= render elm.class.to_s.tableize + '/element', :elm => elm, :author => author %> <% end %> <% else %>

<%= t('sheets.hidden') %>

diff --git a/app/views/sheets/_element_tab.html.erb b/app/views/sheets/_element_tab.html.erb new file mode 100644 index 00000000..e6a8f727 --- /dev/null +++ b/app/views/sheets/_element_tab.html.erb @@ -0,0 +1,8 @@ +
  • + +
    + <%= render elm.element_face_template, :elm => elm %> +
    +
    + +
  • diff --git a/app/views/sheets/_form.html.erb b/app/views/sheets/_form.html.erb index 83c147fb..c061d5eb 100644 --- a/app/views/sheets/_form.html.erb +++ b/app/views/sheets/_form.html.erb @@ -1,27 +1,99 @@ -<%= form_for(@sheet) do |f| %> - <%= render 'system/error_explanation', :obj => @sheet %> +
    + +
    + <%= form_for(@sheet) do |f| %> + <%= render 'system/error_explanation', :obj => @sheet %> + +
    + <%= f.label :caption %> + <%= f.text_field :caption, :id => @sheet.field_tag_id(:caption), :sheet_id => @sheet.tag_sheet_id, :column => :caption -%> +
    +
    + <%= f.label :width %> + <%= f.number_field :width, :size => 5, :id => @sheet.field_tag_id(:width), :sheet_id => @sheet.tag_sheet_id, :column => :width %> + + <%= f.label :height %> + <%= f.number_field :height, :size => 5, :id => @sheet.field_tag_id(:height), :sheet_id => @sheet.tag_sheet_id, :column => :height %> -
    - <%= f.label :caption %>
    - <%= f.text_field :caption %> +
    +
    + <%= f.label :visible %> + <%= f.collection_select :visible, t_select_items(MagicNumber['sheet_visible_items']), :last, :first, {:html => {:selected => @sheet.visible}}, {:id => @sheet.field_tag_id(:visible), :sheet_id => @sheet.tag_sheet_id, :column => :visible} %> +
    + <% unless @sheet.new_record? %> + <%= f.hidden_field :id, :id => @sheet.field_tag_id(:id), :sheet_id => @sheet.tag_sheet_id, :column => :id %> + <% end %> +
    + <%= f.submit 'sheets.submit', :class => "submit" %> +
    + <% end %>
    -
    - <%= f.label :width %>
    - <%= f.number_field :width %> +
    +
    +
      + <% @sheet.sheet_elements.each do |elm| %> + <%= render 'element_tab', :elm => elm %> + <% end %> +
    + <% @sheet.sheet_elements.each do |elm| %> +
    +
    + <%= render elm.form_template, :elm => elm, :no_attr => 0 %> + <%= hidden_field_tag '_destroy', '', :id => elm.field_tag_id(:_destroy), :sheet_id => elm.tag_sheet_id, :element_id => elm.tag_element_id, :element_type => elm.tag_element_type, :column => :_destroy %> +
    +
    + <% end %> +
    -
    - <%= f.label :height %>
    - <%= f.number_field :height %> +
    +
    +
      + <% @sheet.sheet_elements.each do |elm| %> +
    • +
      + <%= render elm.path_name + '/element_face', :elm => elm %> +
      +
    • + <% end %> +
    +
    +
    + <% @sheet.sheet_elements.each do |elm| %> +
    + <%= render elm.scenario_template, :elm => elm, :no_attr => 0 %> +
    + <% end %> +
    +
    +
    -
    - <%= f.label :visible %>
    - <%= f.collection_select :visible, t_select_items(MagicNumber['sheet_visible_items']), :last, :first, :html => {:selected => @sheet.visible} %> +
    +
    +
      + <% @sheet.zorderd_elements.each do |elm| %> +
    • +
      + <%= render elm.class.to_s.tableize + '/element_face', :elm => elm %> +
      +
    • + <% end %> +
    +
    -
    - <%= f.label :author_id %>
    - <%= h @author.name %> +
    -
    - <%= f.submit %> +
    +<%= form_for(@sheet, :html => {:jqform => 'pettanr-sheet-form'}) do |f| %> + <%= render 'system/error_explanation', :obj => @sheet %> + + <%= text_field_tag "json", '', :id => 'pettanr-sheet-json' %> +
    + <%= submit_tag t('sheets.create_from_json'), :id => 'pettanr-sheet-submit' -%>
    <% end %> diff --git a/app/views/sheets/_standard.html.erb b/app/views/sheets/_standard.html.erb index 663de287..ad2f5f4f 100644 --- a/app/views/sheets/_standard.html.erb +++ b/app/views/sheets/_standard.html.erb @@ -1,9 +1,9 @@ -<%= render 'sheets/body', :sheet_panels => sheet_panels, :sheet => sheet, :author => author %> +<%= render 'sheets/body', :sheet => sheet, :author => author %>
    - <% sheet_panels.each do |sheet_panel| %> + <% sheet.sheet_elements.each do |sheet_panel| %> <%= render 'sheet_panels/play_footer', :sheet_panel => sheet_panel, :author => author %> <% end %> - <%= render 'sheet_panels/licensed_pictures', :licensed_pictures => SheetPanel.licensed_pictures(sheet_panels) %> + <%= render 'sheet_panels/licensed_pictures', :licensed_pictures => @sheet.licensed_pictures %>
    diff --git a/app/views/sheets/edit.html.erb b/app/views/sheets/edit.html.erb index 1d67f75e..203d91a4 100644 --- a/app/views/sheets/edit.html.erb +++ b/app/views/sheets/edit.html.erb @@ -1,4 +1,16 @@

    <%= t('.title') %>

    <%= notice %>

    -<%= render 'form' %> +
    + <%= render 'sheets/body', :sheet => @sheet, :author => @author %> +
    + <% @sheet.sheet_elements.each do |sheet_panel| %> + <%= render 'sheet_panels/play_footer', :sheet_panel => sheet_panel, :author => @author %> + <% end %> +
    +
    +
    +
    +<%= render 'form', :sheet => @sheet %> +<%= link_to t('link.destroy'), sheet_path(@sheet), :method => :delete %> +<%= render 'sheet_panels/licensed_pictures', :licensed_pictures => @sheet.licensed_pictures %> diff --git a/app/views/sheets/new.html.erb b/app/views/sheets/new.html.erb index 39ae7bef..3371291f 100644 --- a/app/views/sheets/new.html.erb +++ b/app/views/sheets/new.html.erb @@ -1,5 +1,13 @@

    <%= t('.title') %>

    -<%= render 'form' %> - -<%= link_to t('link.back'), sheets_path %> +
    + <%= render 'sheets/body', :sheet => @sheet, :author => @author %> +
    + <% @sheet.sheet_elements.each do |sheet_panel| %> + <%= render 'sheet_panels/play_footer', :sheet_panel => sheet_panel, :author => @author %> + <% end %> +
    +
    +
    +
    +<%= render 'form', :sheet => @sheet %> diff --git a/app/views/sheets/play.html.erb b/app/views/sheets/play.html.erb index 094ce8eb..1dfe1737 100644 --- a/app/views/sheets/play.html.erb +++ b/app/views/sheets/play.html.erb @@ -2,10 +2,12 @@

    <%= notice %>

    <%= render 'sheet_panels/play_header', :sheet => @sheet, :author => @author %> -<% if @sheet_panels.empty? -%> +<% if @sheet.sheet_elements.empty? -%>

    <%= t('sheet_panels.sheet.empty') %>

    <% else %> - <%= render 'sheets/standard', :sheet_panels => @sheet_panels, :sheet => @sheet, :author => @author %> +
    + <%= render 'sheets/standard', :sheet => @sheet, :author => @author %> +
    <% end %> <% if @sheet.own? @author -%>

    <%= t('sheet_panels.append.new_panels') -%>

    diff --git a/app/views/sheets/show.html.erb b/app/views/sheets/show.html.erb index 92c7477b..f39894dd 100644 --- a/app/views/sheets/show.html.erb +++ b/app/views/sheets/show.html.erb @@ -2,43 +2,12 @@

    <%= t('.title') %>

    <%= notice %>

    -

    - <%= t_m 'Sheet.caption' -%>: - <%= link_to h(@sheet.caption), play_sheet_path(@sheet) %> -

    +<%= render 'standard', :sheet => @sheet, :author => @author %> -

    - <%= t_m 'Sheet.width' -%>: - <%= h(@sheet.width) %> -

    +<% if @sheet.own? @author %> + <%= link_to t('link.edit'), edit_sheet_path(@sheet) %> + <%= link_to t('link.destroy'), sheet_path(@sheet), :method => :delete %> -

    - <%= t_m 'Sheet.height' -%>: - <%= h(@sheet.height) %> -

    - -

    - <%= t_m 'Sheet.visible' -%>: - <%= t_selected_item('sheet_visible_items', @sheet.visible) %> -

    - -

    - <%= t_m 'Sheet.author_id' -%>: - <%= link_to h(@sheet.author.name), author_path(@sheet.author) %> -

    - -

    - <%= t_m 'Sheet.created_at' -%>: - <%= l @sheet.created_at %> -

    - -

    - <%= t_m 'Sheet.updated_at' -%>: - <%= l @sheet.updated_at %> -

    - -<%= link_to t('link.edit'), edit_sheet_path(@sheet) %> -<% if @sheet.own? @author -%>

    <%= t('sheet_panels.append.new_panels') -%>

    <% @new_panels.each do |panel| %> diff --git a/config/locales/pettanr.ja.yml b/config/locales/pettanr.ja.yml index 4217dfce..27affa0c 100644 --- a/config/locales/pettanr.ja.yml +++ b/config/locales/pettanr.ja.yml @@ -670,6 +670,7 @@ ja: browse: title: 用紙 生単票 hidden: 権限がありません + create_from_json: jsonデータからコマ作成する sheet_panels: index: title: 紙コマ一覧 @@ -689,6 +690,7 @@ ja: title: 紙コマ 生一覧 browse: title: 紙コマ 生単票 + submit: 作成する move: 移動 append: panel: このコマを追加する diff --git a/spec/controllers/sheets_controller_spec.rb b/spec/controllers/sheets_controller_spec.rb index 0109ad17..289f3ed5 100644 --- a/spec/controllers/sheets_controller_spec.rb +++ b/spec/controllers/sheets_controller_spec.rb @@ -267,7 +267,7 @@ if MagicNumber['run_mode'] == 1 describe '閲覧に於いて' do before do - @sheet = FactoryGirl.create :sheet, :author_id => @user.author.id + @sheet = FactoryGirl.create :sheet, :author_id => @user.author.id, :caption => 'normal' @panel = FactoryGirl.create :panel, :author_id => @author.id @sheet_panel = FactoryGirl.create :sheet_panel, :t => 0, :sheet_id => @sheet.id, :panel_id => @panel.id, :author_id => @author.id Sheet.stub(:show).with(@sheet.id.to_s, [@user, nil]).and_return(@sheet) @@ -281,16 +281,8 @@ if MagicNumber['run_mode'] == 1 Sheet.should_receive(:show).with(@sheet.id.to_s, [@user, nil]).exactly(1) get :play, :id => @sheet.id end - it '紙コマモデルにプレイリスト取得を問い合わせている' do - SheetPanel.should_receive(:play_list).with(@sheet, @author).exactly(1) - get :play, :id => @sheet.id - end end context 'つつがなく終わるとき' do - it '@sheet_panelsにリストを取得している' do - get :play, :id => @sheet.id - assigns(:sheet_panels).should have_at_least(3).items - end context 'html形式' do it 'ステータスコード200 OKを返す' do get :play, :id => @sheet.id @@ -310,21 +302,15 @@ if MagicNumber['run_mode'] == 1 get :play, :id => @sheet.id, :format => :json lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) end - it '紙コマモデルに紙コマリストのjson出力を問い合わせている' do - SheetPanel.should_receive(:list_as_json_text).exactly(1) - get :play, :id => @sheet.id, :format => :json - end - it 'データがリスト構造になっている' do - get :play, :id => @sheet.id, :format => :json - json = JSON.parse response.body - json.should have_at_least(3).items + it '用紙モデルにjson単体出力オプションを問い合わせている' do + Sheet.should_receive(:show_json_opt).exactly(1) + get :show, :id => @sheet.id, :format => :json end - it 'リストの先頭くらいは紙コマっぽいものであって欲しい' do + it 'データがアレになっている' do get :play, :id => @sheet.id, :format => :json json = JSON.parse response.body - json.first.has_key?("panel_id").should be_true - json.first.has_key?("sheet_id").should be_true - json.first.has_key?("author_id").should be_true + json["caption"].should match(/normal/) + json["visible"].should_not be_nil end end end @@ -512,20 +498,27 @@ if MagicNumber['run_mode'] == 1 @attr = FactoryGirl.attributes_for(:sheet, :author_id => @author.id, :caption => 'normal') end context '事前チェックしておく' do - it '用紙モデルにデフォルト値補充を依頼している' do - Sheet.any_instance.should_receive(:supply_default).exactly(1) + it 'sheetがパラメータにあれば、展開する' do post :create, :sheet => @attr + assigns(:prm)['caption'].should eq 'normal' end - it '用紙モデルにカラム値復元を依頼している' do - Sheet.any_instance.should_receive(:attributes=).exactly(1) - post :create, :sheet => @attr + it 'jsonがパラメータにあれば、展開する' do + post :create, :json => FactoryGirl.attributes_for(:sheet, :caption => 'json prm').to_json + assigns(:prm)['caption'].should eq 'json prm' end - it '用紙モデルに上書き補充を依頼している' do - Sheet.any_instance.should_receive(:overwrite).exactly(1) + it 'sheet・json両パラメータがあれば、sheetを優先して展開する' do + post :create, { + :sheet => FactoryGirl.attributes_for(:sheet, :caption => 'normal'), + :json => FactoryGirl.attributes_for(:sheet, :caption => 'json prm').to_json + } + assigns(:prm)['caption'].should eq 'normal' + end + it '用紙モデルにデフォルト値補充を依頼している' do + Sheet.any_instance.should_receive(:supply_default).exactly(1) post :create, :sheet => @attr end it 'モデルに保存依頼する' do - Sheet.any_instance.should_receive(:save).exactly(1) + Sheet.any_instance.should_receive(:store).exactly(1) post :create, :sheet => @attr end end @@ -537,19 +530,19 @@ if MagicNumber['run_mode'] == 1 end context 'html形式' do it 'ステータスコード302 Foundを返す' do - Sheet.any_instance.stub(:save).and_return(true) + Sheet.any_instance.stub(:store).and_return(true) post :create, :sheet => @attr response.status.should eq 302 end it '作成された用紙の表示ページへ遷移する' do -# Sheet.any_instance.stub(:save).and_return(true) +# Sheet.any_instance.stub(:store).and_return(true) post :create, :sheet => @attr response.should redirect_to(Sheet.last) end end context 'json形式' do it 'ステータスコード200 OKを返す' do -# Sheet.any_instance.stub(:save).and_return(true) +# Sheet.any_instance.stub(:store).and_return(true) post :create, :sheet => @attr, :format => :json response.should be_success end @@ -749,37 +742,45 @@ if MagicNumber['run_mode'] == 1 sign_in @user end context '事前チェックしておく' do - it '用紙モデルに編集取得を問い合わせている' do - Sheet.stub(:edit).with(any_args()).and_return @sheet - Sheet.should_receive(:edit).exactly(1) + it 'sheetがパラメータにあれば、展開する' do put :update, :id => @sheet.id, :sheet => @attr + assigns(:prm)['caption'].should eq 'updated caption' end - it '用紙モデルにカラム値復元を依頼している' do - Sheet.any_instance.should_receive(:attributes=).exactly(1) - put :update, :id => @sheet.id, :sheet => @attr + it 'jsonがパラメータにあれば、展開する' do + put :update, :id => @sheet.id, :json => FactoryGirl.attributes_for(:sheet, :caption => 'json caption').to_json + assigns(:prm)['caption'].should eq 'json caption' + end + it 'sheet・json両パラメータがあれば、sheetを優先して展開する' do + put :update, { + :id => @sheet.id, + :sheet => FactoryGirl.attributes_for(:sheet, :caption => 'updated caption'), + :json => FactoryGirl.attributes_for(:sheet, :caption => 'json caption').to_json + } + assigns(:prm)['caption'].should eq 'updated caption' end - it '用紙モデルに上書き補充を依頼している' do - Sheet.any_instance.should_receive(:overwrite).exactly(1) + end + context 'つつがなく終わるとき' do + it '用紙モデルに編集取得を問い合わせている' do + Sheet.stub(:edit).with(any_args()).and_return @sheet + Sheet.should_receive(:edit).exactly(1) put :update, :id => @sheet.id, :sheet => @attr end it 'モデルに更新を依頼する' do - Sheet.any_instance.stub(:save).with(any_args).and_return true - Sheet.any_instance.should_receive(:save).exactly(1) + Sheet.any_instance.stub(:store).with(any_args).and_return true + Sheet.any_instance.should_receive(:store).exactly(1) put :update, :id => @sheet.id, :sheet => @attr end it '@sheetにアレを取得している' do put :update, :id => @sheet.id, :sheet => @attr assigns(:sheet).id.should eq(@sheet.id) end - end - context 'つつがなく終わるとき' do it '更新される' do put :update, :id => @sheet.id, :sheet => @attr Sheet.find(@sheet.id).visible.should eq 0 end context 'html形式' do it 'ステータスコード302 Foundを返す' do - Sheet.any_instance.stub(:save).with(any_args()).and_return(true) + Sheet.any_instance.stub(:store).with(any_args()).and_return(true) put :update, :id => @sheet.id, :sheet => @attr response.status.should eq 302 end @@ -790,12 +791,12 @@ if MagicNumber['run_mode'] == 1 end context 'json形式' do it 'ステータスコード200 OKを返す' do - Sheet.any_instance.stub(:save).with(any_args()).and_return(true) + Sheet.any_instance.stub(:store).with(any_args()).and_return(true) put :update, :id => @sheet.id, :sheet => @attr, :format => :json response.should be_success end it 'ページ本体は特に返さない' do - Sheet.any_instance.stub(:save).with(any_args()).and_return(true) + Sheet.any_instance.stub(:store).with(any_args()).and_return(true) put :update, :id => @sheet.id, :sheet => @attr, :format => :json response.body.should match /./ end diff --git a/spec/models/sheet_panel_spec.rb b/spec/models/sheet_panel_spec.rb index 5eadaa56..14ab7b8c 100644 --- a/spec/models/sheet_panel_spec.rb +++ b/spec/models/sheet_panel_spec.rb @@ -878,48 +878,6 @@ describe SheetPanel do end end - describe 'ライセンス素材に於いて' do - before do - #コマを作成しておく。 - @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id - @p2 = FactoryGirl.create :picture, :original_picture_id => @op2.id, :license_id => @license.id, :artist_id => @artist.id - @rp2 = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op2.id, :picture_id => @p2.id - @panel = FactoryGirl.create :panel, :author_id => @author.id - @pp = FactoryGirl.create :panel_picture, :panel_id => @panel.id, :t => 0, :width => @p.width, :height => @p.height, :picture_id => @p.id - @panel.reload - @panel2 = FactoryGirl.create :panel, :author_id => @author.id - @pp2= FactoryGirl.create :panel_picture, :panel_id => @panel2.id, :t => 0, :width => @p2.width, :height => @p2.height, :picture_id => @p2.id - @panel2.reload - - @sheet = FactoryGirl.create :sheet, :author_id => @author.id - @sheet_panel = FactoryGirl.create :sheet_panel, :author_id => @author.id, :sheet_id => @sheet.id, :panel_id => @panel.id - @sheet_panel2 = FactoryGirl.create :sheet_panel, :author_id => @author.id, :sheet_id => @sheet.id, :panel_id => @panel2.id - end - context '事前チェック' do - end - context 'つつがなく終わるとき' do - end - it '連想配列(値は実素材、キーは実素材id)を返している' do - r = SheetPanel.licensed_pictures [@sheet_panel, @sheet_panel2] - r.is_a?(Hash).should be_true - r.should have(2).items - r[@pp.picture_id].should eq @p - r[@pp2.picture_id].should eq @p2 - end - context 'コマが削除されているときき' do - before do - @panel2.destroy - end - it '削除されているコマは無視する' do - r = SheetPanel.licensed_pictures [@sheet_panel, @sheet_panel2] - r.is_a?(Hash).should be_true - r.should have(1).items - r[@pp.picture_id].should eq @p - r[@pp2.picture_id].should be_nil - end - end - end - describe 't補充値に於いて' do before do @sheet = FactoryGirl.create :sheet, :author_id => @author.id diff --git a/spec/models/sheet_spec.rb b/spec/models/sheet_spec.rb index 4cec7ed3..202f5cc2 100644 --- a/spec/models/sheet_spec.rb +++ b/spec/models/sheet_spec.rb @@ -664,6 +664,193 @@ describe Sheet do end end + describe '検証値収集に於いて' do + context 'つつがなく終わるとき' do + it '第一パラメータで指定された配列中から第二引数のカラム値を収集している' do + elements = [[{:sheet_id => 1, :a => 'a'}, {:sheet_id => 2, :a => 'a'}], + [{:sheet_id => 3, :a => 'a'}, {:sheet_id => 4, :a => 'a'}]] + r = Sheet.collect_element_value elements, :sheet_id + r.should eq [1, 2, 3, 4] + end + it '第一パラメータで指定された配列中から第二引数のカラム値を収集している' do + elements = [[{:t => 1, :a => 'a'}, {:t => 2, :a => 'a'}], + [{:t => 3, :a => 'a'}, {:t => 0, :a => 'a'}]] + r = Sheet.collect_element_value elements, :t + r.should eq [1, 2, 3, 0] + end + end + end + describe 'シリアライズチェックに於いて' do + context 'つつがなく終わるとき' do + it '0からシリアライズされているならTrueを返す' do + r = Sheet.validate_serial [0, 1, 2] + r.should be_true + end + it '見た目はシリアライズされてなくてもソート結果が無事ならtrueを返す' do + r = Sheet.validate_serial [0, 2, 1] + r.should be_true + end + it '見た目はシリアライズされてなくてもソート結果が無事ならtrueを返す' do + r = Sheet.validate_serial [ 2, 1, 4, 3, 0] + r.should be_true + end + end + context 'オフセットが1のとき' do + it '0からシリアライズされているならFalseを返す' do + r = Sheet.validate_serial [0, 1, 2], 1 + r.should be_false + end + it '1からシリアライズされているならTrueを返す' do + r = Sheet.validate_serial [1, 2, 3], 1 + r.should be_true + end + end + context '異常なとき' do + it '0から始まらないならFalseを返す' do + r = Sheet.validate_serial [1, 2, 3] + r.should be_false + end + it '連続していないならFalseを返す' do + r = Sheet.validate_serial [0, 1, 2, 4] + r.should be_false + end + it '連続していないならFalseを返す' do + r = Sheet.validate_serial [0, 1, 2, 4, 5] + r.should be_false + end + end + end + describe 'シリアライズチェック単体に於いて' do + before do + end + context 'つつがなく終わるとき' do + it '検証値収集を依頼している' do + Sheet.should_receive(:collect_element_value).with(any_args).exactly(1) + Sheet.stub(:collect_element_value).with(any_args).and_return([]) + Sheet.stub(:validate_serial).with(any_args).and_return(true) + r = Sheet.validate_element_serial [], :t + end + it 'シリアライズチェック依頼している' do + Sheet.stub(:collect_element_value).with(any_args).and_return([]) + Sheet.should_receive(:validate_serial).with(any_args).exactly(1) + Sheet.stub(:validate_serial).with(any_args).and_return(true) + r = Sheet.validate_element_serial [], :t + end + end + end + describe '従属データの検証に於いて' do + context 'つつがなく終わるとき' do + it 'trueを返している' do + @sheet = FactoryGirl.create :sheet, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + @sheet.sheet_panels.create( + FactoryGirl.attributes_for(:sheet_panel, :sheet_id => @sheet.id, :panel_id => @panel.id, :t => 0, :z => 0+1) + ) + @sheet.sheet_panels.create( + FactoryGirl.attributes_for(:sheet_panel, :sheet_id => @sheet.id, :panel_id => @panel.id, :t => 1, :z => 1+1) + ) + r = @sheet.validate_child + r.should be_true + end + end + context 'tシリアライズされていないとき' do + it 'falseを返している' do + @sheet = FactoryGirl.create :sheet, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + @sheet.sheet_panels.create( + FactoryGirl.attributes_for(:sheet_panel, :sheet_id => @sheet.id, :panel_id => @panel.id, :t => 2, :z => 0+1) + ) + @sheet.sheet_panels.create( + FactoryGirl.attributes_for(:sheet_panel, :sheet_id => @sheet.id, :panel_id => @panel.id, :t => 1, :z => 1+1) + ) + r = @sheet.validate_child + r.should be_false + end + end + context 'zシリアライズされていないとき' do + it 'falseを返している' do + @sheet = FactoryGirl.create :sheet, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + @sheet.sheet_panels.create( + FactoryGirl.attributes_for(:sheet_panel, :sheet_id => @sheet.id, :panel_id => @panel.id, :t => 0, :z => 0+2) + ) + @sheet.sheet_panels.create( + FactoryGirl.attributes_for(:sheet_panel, :sheet_id => @sheet.id, :panel_id => @panel.id, :t => 1, :z => 1+1) + ) + r = @sheet.validate_child + r.should be_false + end + end + end + describe '保存に於いて' do + before do + @attr = FactoryGirl.attributes_for :sheet + @sheet = Sheet.new + @sheet.supply_default + end + context 'つつがなく終わるとき' do + before do + Sheet.any_instance.stub(:validate_child).with(any_args).and_return(true) + Sheet.any_instance.stub(:save).with(any_args).and_return(true) + end + it 'コマモデルに上書き補充を依頼している' do + Sheet.any_instance.should_receive(:overwrite).exactly(1) + r = @sheet.store @attr, @author + end + it '保存を依頼している' do + Sheet.any_instance.should_receive(:save).with(any_args).exactly(1) + @sheet = FactoryGirl.build :sheet, :author_id => @author.id + r = @sheet.store @attr, @author + end + it '従属データの検証を依頼している' do + Sheet.any_instance.should_receive(:validate_child).with(any_args).exactly(1) + r = @sheet.store @attr, @author + end + end + context 'つつがなく終わるとき' do + before do + Sheet.any_instance.stub(:validate_child).with(any_args).and_return(true) + end + it 'Trueを返す' do + r = @sheet.store @attr, @author + r.should be_true + end + it '行が追加されている' do + Sheet.any_instance.stub(:validate_child).with(any_args).and_return(true) + lambda { + r = @sheet.store @attr, @author + }.should change(Sheet, :count) + end + end + context '不正なjsonデータのとき' do + before do + end + it 'エラーメッセージがセットされている' do + r = @sheet.store false, @author + @sheet.errors[:base].should_not be_blank + end + end + context '従属データの検証に失敗したとき' do + before do + Sheet.any_instance.stub(:save).with(any_args).and_return(true) + Sheet.any_instance.stub(:validate_child).with(any_args).and_return(false) + end + it 'エラーメッセージがセットされている' do + r = @sheet.store @attr, @author + @sheet.errors[:base].should_not be_blank + end + end + context 'カラム値がFalseしたとき' do + before do + Sheet.any_instance.stub(:validate_child).with(any_args).and_return(true) + end + it 'エラーメッセージがセットされている' do + r = @sheet.store false, @author + @sheet.errors.should_not be_empty + end + end + end + describe '削除に於いて' do before do @sheet = FactoryGirl.create :sheet, :author_id => @author.id -- 2.11.0