lib/node_mutation.rb in node_mutation-1.1.0 vs lib/node_mutation.rb in node_mutation-1.2.0

- old
+ new

@@ -20,14 +20,13 @@ autoload :InsertAction, 'node_mutation/action/insert_action' autoload :InsertAfterAction, 'node_mutation/action/insert_after_action' autoload :RemoveAction, 'node_mutation/action/remove_action' autoload :PrependAction, 'node_mutation/action/prepend_action' autoload :ReplaceAction, 'node_mutation/action/replace_action' - autoload :ReplaceErbStmtWithExprAction, 'node_mutation/action/replace_erb_stmt_with_expr_action' autoload :ReplaceWithAction, 'node_mutation/action/replace_with_action' autoload :WrapAction, 'node_mutation/action/wrap_action' - autoload :Engine, 'node_mutation/engine' + autoload :Result, 'node_mutation/result' attr_reader :actions # Configure NodeMutation # @param [Hash] options options to configure @@ -53,13 +52,13 @@ def self.strategy @strategy ||= KEEP_RUNNING end # Initialize a NodeMutation. - # @param file_path [String] file path - def initialize(file_path) - @file_path = file_path + # @param source [String] file source + def initialize(source) + @source = source @actions = [] end # Append code to the ast node. # @param node [Node] ast node @@ -174,25 +173,10 @@ # assert_empty(object) def replace(node, *selectors, with:) @actions << ReplaceAction.new(node, *selectors, with: with).process end - # Replace erb stmt node with expr code. - # @param node [Node] ast node - # @example - # source code of the ast node is - # <% form_for post do |f| %> - # <% end %> - # then we call - # replace_erb_stmt_with_expr(node) - # the source code will be rewritten to - # # <%= form_for post do |f| %> - # # <% end %> - def replace_erb_stmt_with_expr(node) - @actions << ReplaceErbStmtWithExprAction.new(node).process - end - # Replace source code of the ast node with new code. # @param node [Node] ast node # @param code [String] code need to be replaced with. # @example # source code of the ast node is @@ -231,45 +215,31 @@ # it will raise a ConflictActionError if strategy is set to THROW_ERROR, # it will process all non conflicted actions and return `{ conflict: true }` # if strategy is set to KEEP_RUNNING. # @return {{conflict: Boolean}} if actions are conflicted def process - conflict_actions = [] - if @actions.length > 0 - source = +read_source(@file_path) - @actions.sort_by! { |action| [action.start, action.end] } - conflict_actions = get_conflict_actions - if conflict_actions.size > 0 && NodeMutation.strategy == THROW_ERROR - raise ConflictActionError, "mutation actions are conflicted" - end - @actions.reverse_each do |action| - source[action.start...action.end] = action.new_code - end - @actions = [] + if @actions.length == 0 + return NodeMutation::Result.new(affected: false) + end - write_source(@file_path, source) + conflict_actions = [] + source = +@source + @actions.sort_by! { |action| [action.start, action.end] } + conflict_actions = get_conflict_actions + if conflict_actions.size > 0 && NodeMutation.strategy == THROW_ERROR + raise ConflictActionError, "mutation actions are conflicted" end - OpenStruct.new(conflict: !conflict_actions.empty?) + @actions.reverse_each do |action| + source[action.start...action.end] = action.new_code + end + NodeMutation::Result.new( + affected: true, + conflicted: !conflict_actions.empty?, + new_source: source + ) end private - - # Read file source. - # @param file_path [String] file path - # @return [String] file source - def read_source(file_path) - source = File.read(file_path, encoding: 'UTF-8') - source = Engine::Erb.encode(source) if /\.erb$/.match?(file_path) - source - end - - # Write file source to file. - # @param file_path [String] file path - # @param source [String] file source - def write_source(file_path, source) - source = Engine::ERB.decode(source) if /\.erb/.match?(file_path) - File.write(file_path, source.gsub(/ +\n/, "\n")) - end # It changes source code from bottom to top, and it can change source code twice at the same time, # So if there is an overlap between two actions, it removes the conflict actions and operate them in the next loop. def get_conflict_actions i = @actions.length - 1