ruby setup_load_paths.rb

setup_load_paths.rb
if ENV['MY_RUBY_HOME'] && ENV['MY_RUBY_HOME'].include?('rvm')
  begin
    rvm_path     = File.dirname(File.dirname(ENV['MY_RUBY_HOME']))
  #  rvm_lib_path = File.join(rvm_path, 'lib')
 #   $LOAD_PATH.unshift rvm_lib_path
    require 'rvm'
    RVM.use_from_path! File.dirname(File.dirname(__FILE__))
  rescue LoadError
    raise "RVM ruby lib is currently unavailable."
  end
end

# This assumes Bundler 1.0+
ENV['BUNDLE_GEMFILE'] = File.expand_path('../Gemfile', File.dirname(__FILE__))
require 'bundler/setup'


 ## OLD VERSION BELOW: 

#if ENV['MY_RUBY_HOME'] && ENV['MY_RUBY_HOME'].include?('rvm')
#  begin
#    gems_path = ENV['MY_RUBY_HOME'].split(/@/)[0].sub(/rubies/,'gems')
#    ENV['GEM_PATH'] = "#{gems_path}:#{gems_path}@global"
#    require 'rvm'
#    RVM.use_from_path! File.dirname(File.dirname(__FILE__))
#  rescue LoadError
#    raise "RVM gem is currently unavailable."
#  end
#end
#
## If you're not using Bundler at all, remove lines bellow
#ENV['BUNDLE_GEMFILE'] = File.expand_path("../Gemfile", File.dirname(__FILE__))
#require 'bundler/setup'

ruby Capybara JS使用angular.js和/或turbolinks怪癖

Capybara JS使用angular.js和/或turbolinks怪癖

angularjs_steps.rb
step %{I save a task without the required fields} do
  within_task_form do
    # NOTE filling with '' won't work as it does not trigger keypress events
    # and thus breaks angular bindings
    fill_in 'task_name', with: ' '
  end
  step %{I save the task}
end
bootstrap_steps.rb
step %{the task should be :task_state} do |task_state|
  within '.tag-list .dropdown.task-state' do
    expect(page).to have_css '.dropdown-toggle',       text: task_state.capitalize
    toggle_dropdown # NOTE needed to get next assertion, else finder returns '' for some reason
    expect(page).to have_css '.dropdown-menu .active', text: task_state.capitalize
  end
end
turblolinks_steps.rb
step %{I go to edit task} do
  expect(page).to have_css %{a[rel='edit-task']}, visible: true
  find(%{a[rel='edit-task']}).click
  # NOTE must wait for selector else turbolinks breaks the next step since it 
  # will execute instantly as it is no longer waiting for the traditional page load
  expect(page).to have_css '.editor-pane'
end

ruby 我用Squarespace的Wordpress XML导入了我的Jekyll

我用Squarespace的Wordpress XML导入了我的Jekyll

rename.rb
#!/usr/bin/env ruby

require 'html2markdown'

POST_REGEX = %r{(?<year>[0-9]+)-(?<month>[0-9]+)-(?<day>[0-9]+)-(?<title>.*).html}

files = Dir.glob('*.html').select{ |f| f.match POST_REGEX }

files.each do |post|
  data = post.match(POST_REGEX)
  p = HTMLPage.new(contents: File.read(post))

  File.open(post, 'w') { |f| f.puts p.markdown }
  File.rename(post, "#{data[:year]}-#{data[:month]}-#{data[:day]}-#{data[:title]}.md")
end
import.rb
# coding: utf-8

require 'rubygems'
require 'hpricot'
require 'fileutils'
require 'safe_yaml'
require 'time'

module JekyllImport
  # This importer takes a wordpress.xml file, which can be exported from your
  # wordpress.com blog (/wp-admin/export.php).
  module WordpressDotCom
    def self.process(filename = {:source => "wordpress.xml"})
      import_count = Hash.new(0)
      doc = Hpricot::XML(File.read(filename[:source]))

      (doc/:channel/:item).each do |item|
        title = item.at(:title).inner_text.strip
        permalink_title = item.at('wp:post_name').inner_text.gsub("/","-")
        # Fallback to "prettified" title if post_name is empty (can happen)
        if permalink_title == ""
          permalink_title = sluggify(title)
        end

        if item.at('wp:post_date')
          begin
            date = Time.parse(item.at('wp:post_date').inner_text)
          rescue
            date = Time.now
          end
        else
          date = Time.now
        end

        status = item.at('wp:status').inner_text

        if status == "publish"
          published = true
        else
          published = false
        end

        type = item.at('wp:post_type').inner_text
        categories = item.search('category[@domain="category"]').map{|c| c.inner_text}.reject{|c| c == 'Uncategorized'}.uniq
        tags = item.search('category[@domain="post_tag"]').map{|t| t.inner_text}.uniq

        metas = Hash.new
        item.search("wp:postmeta").each do |meta|
          key = meta.at('wp:meta_key').inner_text
          value = meta.at('wp:meta_value').inner_text
          metas[key] = value;
        end

        name = "#{date.strftime('%Y-%m-%d')}-#{permalink_title}.html"
        header = {
          'layout' => type,
          'title' => title,
          'categories' => categories,
          'tags' => tags,
          'status' => status,
          'type' => type,
          'published' => published,
          'meta' => metas
        }

        begin
          FileUtils.mkdir_p "_#{type}s"
          File.open("_#{type}s/#{name}", "w") do |f|
            f.puts header.to_yaml
            f.puts '---'
            f.puts item.at('content:encoded').inner_text
          end
        rescue => e
          puts "Couldn't import post!"
          puts "Title: #{title}"
          puts "Name/Slug: #{name}\n"
          puts "Error: #{e.message}"
          next
        end

        import_count[type] += 1
      end

      import_count.each do |key, value|
        puts "Imported #{value} #{key}s"
      end
    end

    def self.sluggify(title)
      title.gsub(/[^[:alnum:]]+/, '-').downcase
    end
  end
end

JekyllImport::WordpressDotCom.process

ruby 用于创建封装JSON序列化逻辑的类的简单模式。只需继承`BaseSerializer`并覆盖h

用于创建封装JSON序列化逻辑的类的简单模式。只需继承`BaseSerializer`并根据需要覆盖hook方法。

comment_serializer.rb
# serialize a comment to json:
# 
#   CommentSerializer.new(c).as_json
#   => {
#	"id"=>1,
#	"html_body"=>"lorem ipsum dolor...",
#	"created_at"=>"2013-07-26T10:38:47-07:00",
#	"user"=>{
#		"id"=>1,
#		"name"=>"Matthew"
#	}
#    }
class CommentSerializer < BaseSerializer

  private

    def serialize(object, options={})
      super(object, options).tap do |json|
        json['link'] = user_path(serialized_object)
      end
    end

    def attributes
      %w(id created_at)
    end

    def includes
      { 'user' => { 'only' => %w(id name) } }
    end

    def methods
      %w(html_body)
    end
end
base_serializer.rb
# An abstract base class used to create simple serializers
# for ActiveRecord objects
class BaseSerializer
  include Rails.application.routes.url_helpers

  attr_reader :serialized_object

  def initialize(serialized_object)
    @serialized_object = serialized_object
  end
	
  def as_json(options={})
    if serialized_object.respond_to?(:to_ary)
      serialized_object.map { |object| serialize(object, options) }
    else
      serialize(serialized_object, options)
    end
  end

  private

    # serialize a single instance
    def serialize(object, options={})
      object.as_json(as_json_options.merge(options))
    end

    # the default options passed to as_json
    def as_json_options
      { :only    => attributes, 
        :methods => methods, 
        :include => includes }
    end

    # hook methods
    def attributes ; end
    def includes   ; end
    def methods    ; end
end

ruby each_with_object.rb

test.rb
require 'minitest/autorun'
require_relative 'dna'

class DNATest < MiniTest::Unit::TestCase

  def test_no_difference_between_empty_strands
    assert_equal 0, DNA.new('').hamming_distance('')
  end

  def test_no_difference_between_identical_strands
    assert_equal 0, DNA.new('GGACTGA').hamming_distance('GGACTGA')
  end

  def test_complete_hamming_distance_in_small_strand
    assert_equal 3, DNA.new('ACT').hamming_distance('GGA')
  end

  def test_hamming_distance_in_off_by_one_strand
    assert_equal 19, DNA.new('GGACGGATTCTGACCTGGACTAATTTTGGGG').hamming_distance('AGGACGGATTCTGACCTGGACTAATTTTGGGG')
  end

  def test_small_hamming_distance_in_middle_somewhere
    assert_equal 1, DNA.new('GGACG').hamming_distance('GGTCG')
  end

  def test_larger_distance
    assert_equal 2, DNA.new('ACCAGGG').hamming_distance('ACTATGG')
  end

  def test_ignores_extra_length_on_other_strand_when_longer
    assert_equal 3, DNA.new('AAACTAGGGG').hamming_distance('AGGCTAGCGGTAGGAC')
  end

  def test_ignores_extra_length_on_original_strand_when_longer
    assert_equal 5, DNA.new('GACTACGGACAGGGTAGGGAAT').hamming_distance('GACATCGCACACC')
  end

  def test_does_not_actually_shorten_original_strand
    assert_equal 1, DNA.new('AGACAACAGCCAGCCGCCGGATT').hamming_distance('AGGCAA')
    assert_equal 4, DNA.new('AGACAACAGCCAGCCGCCGGATT').hamming_distance('AGACATCTTTCAGCCGCCGGATTAGGCAA')
    assert_equal 1, DNA.new('AGACAACAGCCAGCCGCCGGATT').hamming_distance('AGG')
  end

end
inject.rb
class DNA
  attr_reader :strand

  def initialize(strand)
    @strand = strand
  end

  def hamming_distance(homologous_strand)
    nucleic_acid_indexes(homologous_strand).inject(0) do |differences_count, nucleic_acid_index|
      if nucleic_acids_differ?(nucleic_acid_index, homologous_strand)
        differences_count += 1
      end
      differences_count
    end
  end

  private

  def nucleic_acids_differ?(nucleic_acid_index, homologous_strand)
    strand[nucleic_acid_index].to_s != homologous_strand[nucleic_acid_index].to_s
  end

  def nucleic_acid_indexes(homologous_strand)
    0.upto([strand.length, homologous_strand.length].min - 1)
  end
end
each_with_object.rb
class DNA
  attr_reader :strand

  def initialize(strand)
    @strand = strand
  end

  def hamming_distance(homologous_strand)
    nucleic_acid_indexes(homologous_strand).each_with_object(0) do |nucleic_acid_index, differences_count|
      if nucleic_acids_differ?(nucleic_acid_index, homologous_strand)
        differences_count += 1
      end
    end
  end

  private

  def nucleic_acids_differ?(nucleic_acid_index, homologous_strand)
    strand[nucleic_acid_index].to_s != homologous_strand[nucleic_acid_index].to_s
  end

  def nucleic_acid_indexes(homologous_strand)
    0.upto([strand.length, homologous_strand.length].min - 1)
  end
end

ruby 标准的knife.rb文件

标准的knife.rb文件

knife.rb
chef_server = "provision-dev.infra.rds"

log_level                :info
log_location             STDOUT
node_name                "vagrant"
client_key               "#{ENV['HOME']}/.chef/#{chef_server}/vagrant.pem"
validation_client_name   "chef-validator"
validation_key           "#{ENV['HOME']}/.chef/#{chef_server}/chef-validator.pem"
chef_server_url          "https://#{chef_server}"
syntax_check_cache_path  "#{ENV['HOME']}/.chef/#{chef_server}/syntax_check_cache"

cookbook_path            [ "#{ENV['CHEF_DIR_FLA']}/chef_fla/cookbooks" ]

cache_type    "BasicFile"
cache_options( :path => "#{ENV['HOME']}/.chef/#{chef_server}/checsums" )

ruby a.rb

a.rb
# 0. Pasos previos si se clona de VirtualBox

#  0.1. para evitar problemas con eth0, eliminar y reiniciar la maquina:
$ sudo rm /etc/udev/rules.d/70-persistent-net.rules

# 1. Actualizando el sistema
$ sudo apt-get update

# 2. Instalar php y pear para usar en terminal
#    Ver: https://gist.github.com/1074228#file_0_php_cli.sh

# 3. Instalar sun-java-jre y sun-java-jdk
#    Ver: https://gist.github.com/1258127#file_ubuntu_v11.04.sh

# 4. Instalar Jenkins CI
#    Ver: https://gist.github.com/1258167#file_ubuntu_v11.04.sh

# 5. Instalar Behat para symfony
#    http://docs.behat.org/bundle/index.html
$ pear channel-discover pear.symfony.com
$ pear channel-discover pear.behat.org
$ pear install behat/behat

ruby 添加context-block jruby-parser示例后。

添加context-block jruby-parser示例后。

AFTER-static_analysis_spec.rb
require_relative '../helpers'

describe Parser do
  VERSIONS.each do |v|
    if v == 2.0
      it "test 2.0" do
        parse("def foo(a:1); p a; end", v)
      end
    end
    if v != 1.8
      it "parses a simple multiple assignment [#{v}]" do
        parse("a,b,c = 1,2,3", v).find_node(:multipleasgn).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, 2], [:c, 3]])
        end
      end

      context "left-hand side splat multiple assignment [#{v}]" do
        it "parses a splat as the last assignment" do
          parse("a,*b = 1,2,3", v).find_node(:multipleasgn).tap do |masgn|
            masgn.should have_static_assignments([[:a, 1], [:b, [2, 3]]])
          end
          parse("a,b,*c = 1,2,3,4", v).find_node(:multipleasgn).tap do |masgn|
            masgn.should have_static_assignments([[:a, 1], [:b, 2], [:c, [3,4]]])
          end
        end

        it "parses a splat as the first assignment" do
          parse("*a,b = 1,2,3", v).find_node(:multipleasgn).tap do |masgn|
            masgn.should have_static_assignments([[:a, [1, 2]], [:b, 3]])
          end
          parse("*a,b,c = 1,2,3,4", v).find_node(:multipleasgn).tap do |masgn|
            masgn.should have_static_assignments([[:a, [1, 2]], [:b, 3], [:c, 4]])
          end
        end

        it "parses a splat as the middle assignment" do
          parse("a,*b, c = 1,2,3,4", v).find_node(:multipleasgn).tap do |masgn|
            masgn.should have_static_assignments([[:a, 1], [:b, [2, 3]], [:c, 4]])
          end
          parse("a, b, *c, d = 1,2,3,4,5", v).find_node(:multipleasgn).tap do |masgn|
            masgn.should have_static_assignments([[:a, 1], [:b, 2], [:c, [3, 4]], [:d, 5]])
          end
          parse("a, *b, c, d = 1,2,3,4,5", v).find_node(:multipleasgn).tap do |masgn|
            masgn.should have_static_assignments([[:a, 1], [:b, [2, 3]], [:c, 4], [:d, 5]])
          end
        end

        it "parses a splat that should recieve no assignment" do
          parse("a,*b,c,d = 1,2,3,4", v).find_node(:multipleasgn).tap do |masgn|
            masgn.should have_static_assignments([[:a, 1], [:b, []], [:c, 2], [:d, 3]])
          end
        end
      end

      it "parses a simple rhs splat multiple assignment [#{v}]" do
        ast = parse("a,*b = 1,*foo", v)
        foo = ast.find_node(:vcall)
        ast.find_node(:multipleasgn).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, foo]])
        end
      end

      it "parses a simple rhs splat multiple assignment [#{v}]" do
        ast = parse("*a,b = *foo,1", v)
        splatted_foo = ast.find_node(:splat)
        ast.find_node(:multipleasgn).tap do |masgn|
          masgn.should have_static_assignments([[:a, splatted_foo], [:b, 1]])
        end
      end
    end

    it "method: can parse an empty body method with unused param [#{v}]" do
      parse("def foo(a)\nend").find_node(:defn) do |defn|
        defn.args.get_normative_parameter_name_list(true).each do |parameter|
          defn.is_parameter_used(parameter).should == false
        end
      end
    end

    it "method: Can detect simple parameter is used" do
      parse("def foo(a); a; end").find_node(:defn) do |defn|
        defn.args.get_normative_parameter_name_list(true).each do |parameter|
          defn.is_parameter_used(parameter).should == true
        end
      end

      parse("def foo(a,b); a; b; end").find_node(:defn) do |defn|
        defn.args.get_normative_parameter_name_list(true).each do |parameter|
          defn.is_parameter_used(parameter).should == true
        end
      end

      parse("def foo(a,b); a=1; b; end").find_node(:defn) do |defn|
        defn.is_parameter_used("a").should == false
        defn.is_parameter_used("b").should == true
      end
    end

    it "method: Can detect some simple parameters are used" do
      parse("def foo(a,b); b; end").find_node(:defn) do |defn|
        defn.is_parameter_used("a").should == false
        defn.is_parameter_used("b").should == true
      end

      parse("def foo(a,b); b if true; end").find_node(:defn) do |defn|
        defn.is_parameter_used("a").should == false
        defn.is_parameter_used("b").should == true
      end

      parse("def foo(a,b); proc { b if true }; end").find_node(:defn) do |defn|
        defn.is_parameter_used("a").should == false
        defn.is_parameter_used("b").should == true
      end

      parse("def foo a, b, c\nputs a, b, c\nend").find_node(:defn) do |defn|
        defn.is_parameter_used("a").should == true
        defn.is_parameter_used("b").should == true
        defn.is_parameter_used("c").should == true
      end

      parse("def foo(a, b); b.each_answer {|n| data if n == a }; end") do |defn|
        defn.is_parameter_used("a").should == true
        defn.is_parameter_used("b").should == true
      end
    end

    it "method: Can detect some simple optarg params are used" do
      parse("def foo(a,b = {}); b; end").find_node(:defn) do |defn|
        defn.is_parameter_used("a").should == false
        defn.is_parameter_used("b").should == true
      end
    end

    it "method: Can detect zsuper usage" do
      parse("def foo(a,b = {}); super; end").find_node(:defn) do |defn|
        defn.is_parameter_used("a").should == true
        defn.is_parameter_used("b").should == true
      end
    end

    it "block/iter: can parse an empty proc body with unused param [#{v}]" do
      parse("proc do |a|\nend").find_node(:iter) do |iter|
        iter.is_parameter_used("a").should == false
      end
    end

    it "block/iter: Can detect simple parameter is used" do
      parse("proc { |a, b| a; b }").find_node(:iter) do |iter|
        iter.is_parameter_used("a").should == true
        iter.is_parameter_used("b").should == true
      end
    end

    it "block/iter: Can detect simple parameter is used" do
      parse("proc { |a, b| a=1; b }").find_node(:iter) do |iter|
        iter.is_parameter_used("a").should == false
        iter.is_parameter_used("b").should == true
      end
    end

    it "block/iter: Can detect some simple parameters are used" do
      parse("proc {|a,b| b }").find_node(:iter) do |iter|
        iter.is_parameter_used("a").should == false
        iter.is_parameter_used("b").should == true
      end

      parse("proc {|a,b| b if true }").find_node(:iter) do |iter|
        iter.is_parameter_used("a").should == false
        iter.is_parameter_used("b").should == true
      end

      parse("proc {|a,b| proc { b if true } }").find_node(:iter) do |iter|
        iter.is_parameter_used("a").should == false
        iter.is_parameter_used("b").should == true
      end

      parse("proc {|a, b, c| puts a, b, c }").find_node(:iter) do |iter|
        iter.is_parameter_used("a").should == true
        iter.is_parameter_used("b").should == true
        iter.is_parameter_used("c").should == true
      end

      parse("proc {|a, b| b.each_answer {|n| data if n == a } }") do |iter|
        iter.is_parameter_used("a").should == true
        iter.is_parameter_used("b").should == true
      end
    end
  end
end

ruby 在jruby-parser中添加context-blocks示例之前和之后。

在jruby-parser中添加context-blocks示例之前和之后。

results.md
with a faked failure resulting from altering the 'no assignment to the splat' spec to purposefully fail like this:

```ruby
        it "parses a splat that should recieve no assignment" do
          parse("a,*b,c,d = 1,2,3,4", v).find_node(:multipleasgn).tap do |masgn|
            masgn.should have_static_assignments([[:a, 1], [:b, []], [:c, 2], [:d, 3]])
          end
        end
```

```
$ rake spec
...build process output...

.........................................................................................................................................................F...F....................................................................................................................................

Failures:

  1) Java::OrgJrubyparser::Parser left-hand side splat multiple assignment [1.9] parses a splat that should recieve no assignment
     Failure/Error: masgn.should have_static_assignments([[:a, 1], [:b, []], [:c, 2], [:d, 3]])
       names: 
       values: [] != [2] 2 != 3 3 != 4 
     # ./spec/jruby-parser/static_analysis_spec.rb:50:in `(root)'
     # ./spec/jruby-parser/static_analysis_spec.rb:49:in `(root)'

  2) Java::OrgJrubyparser::Parser left-hand side splat multiple assignment [2.0] parses a splat that should recieve no assignment
     Failure/Error: masgn.should have_static_assignments([[:a, 1], [:b, []], [:c, 2], [:d, 3]])
       names: 
       values: [] != [2] 2 != 3 3 != 4 
     # ./spec/jruby-parser/static_analysis_spec.rb:50:in `(root)'
     # ./spec/jruby-parser/static_analysis_spec.rb:49:in `(root)'

Finished in 7.69 seconds
290 examples, 2 failures

Failed examples:

rspec ./spec/jruby-parser/static_analysis_spec.rb:48 # Java::OrgJrubyparser::Parser left-hand side splat multiple assignment [1.9] parses a splat that should recieve no assignment
rspec ./spec/jruby-parser/static_analysis_spec.rb:48 # Java::OrgJrubyparser::Parser left-hand side splat multiple assignment [2.0] parses a splat that should recieve no assignment
/home/eric/.rbenv/versions/jruby-1.7.4/bin/jruby -J-ea -Ilib -S rspec ./spec/ast/node/break_spec.rb ./spec/ast/node/comments_spec.rb ./spec/ast/node/find_scopes_spec.rb ./spec/ast/node/get_declaration_spec.rb ./spec/ast/node/get_defined_scope_spec.rb ./spec/ast/node/get_node_at_spec.rb ./spec/ast/node/get_occurences_spec.rb ./spec/ast/node/is_block_parameter_spec.rb ./spec/ast/node/is_method_parameter_spec.rb ./spec/ast/node/next_spec.rb ./spec/ast/node/return_spec.rb ./spec/jruby-parser/find_spec.rb ./spec/jruby-parser/parse_spec.rb ./spec/jruby-parser/rewriting_spec.rb ./spec/jruby-parser/static_analysis_spec.rb ./spec/parser/alias_spec.rb ./spec/parser/broken_spec.rb ./spec/positions/alias_spec.rb ./spec/positions/arg_spec.rb ./spec/positions/attr_asgn_spec.rb ./spec/positions/call_spec.rb ./spec/positions/conditionals_spec.rb ./spec/positions/hash_spec.rb ./spec/positions/heredoc_spec.rb ./spec/positions/name_spec.rb ./spec/positions/op_asgn_or_spec.rb ./spec/positions/str_spec.rb ./spec/util/node_diff_spec.rb failed
```
BEFORE-static_analysis_spec.rb
require_relative '../helpers'

describe Parser do
  VERSIONS.each do |v|
    if v == 2.0
      it "test 2.0" do
        parse("def foo(a:1); p a; end", v)
      end
    end
    if v != 1.8
      it "parses a simple multiple assignment [#{v}]" do
        parse("a,b,c = 1,2,3", v).find_node(:multipleasgn).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, 2], [:c, 3]])
        end
      end

      it "parses a simple lhs splat multiple assignment [#{v}]" do
        parse("a,*b = 1,2,3", v).find_node(:multipleasgn).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, [2, 3]]])
        end
        parse("a,b,*c = 1,2,3,4", v).find_node(:multipleasgn).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, 2], [:c, [3,4]]])
        end
      end

      it "parses a simple lhs splat multiple assignment [#{v}]" do
        parse("*a,b = 1,2,3", v).find_node(:multipleasgn).tap do |masgn|
          masgn.should have_static_assignments([[:a, [1, 2]], [:b, 3]])
        end
        parse("*a,b,c = 1,2,3,4", v).find_node(:multipleasgn).tap do |masgn|
          masgn.should have_static_assignments([[:a, [1, 2]], [:b, 3], [:c, 4]])
        end
      end

      it "parses a simple lhs splat multiple assignment [#{v}]" do
        parse("a,*b, c = 1,2,3,4", v).find_node(:multipleasgn).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, [2, 3]], [:c, 4]])
        end
        parse("a, b, *c, d = 1,2,3,4,5", v).find_node(:multipleasgn).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, 2], [:c, [3, 4]], [:d, 5]])
        end
        parse("a, *b, c, d = 1,2,3,4,5", v).find_node(:multipleasgn).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, [2, 3]], [:c, 4], [:d, 5]])
        end
      end

      it "parses a simple lhs splat multiple assignment [#{v}]" do
        parse("a,*b,c,d = 1,2,3", v).find_node(:multipleasgn).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, []], [:c, 2], [:d, 3]])
        end
      end
    end
  end
end
AFTER-static_analysis_spec.rb
require_relative '../helpers'

describe Parser do
  VERSIONS.each do |v|
    if v == 2.0
      it "test 2.0" do
        parse("def foo(a:1); p a; end", v)
      end
    end
    if v != 1.8
      it "parses a simple multiple assignment [#{v}]" do
        parse("a,b,c = 1,2,3", v).find_node(:multipleasgn).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, 2], [:c, 3]])
        end
      end

      context "left-hand side splat multiple assignment [#{v}]" do
        it "parses a splat as the last assignment" do
          parse("a,*b = 1,2,3", v).find_node(:multipleasgn).tap do |masgn|
            masgn.should have_static_assignments([[:a, 1], [:b, [2, 3]]])
          end
          parse("a,b,*c = 1,2,3,4", v).find_node(:multipleasgn).tap do |masgn|
            masgn.should have_static_assignments([[:a, 1], [:b, 2], [:c, [3,4]]])
          end
        end

        it "parses a splat as the first assignment" do
          parse("*a,b = 1,2,3", v).find_node(:multipleasgn).tap do |masgn|
            masgn.should have_static_assignments([[:a, [1, 2]], [:b, 3]])
          end
          parse("*a,b,c = 1,2,3,4", v).find_node(:multipleasgn).tap do |masgn|
            masgn.should have_static_assignments([[:a, [1, 2]], [:b, 3], [:c, 4]])
          end
        end

        it "parses a splat as the middle assignment" do
          parse("a,*b, c = 1,2,3,4", v).find_node(:multipleasgn).tap do |masgn|
            masgn.should have_static_assignments([[:a, 1], [:b, [2, 3]], [:c, 4]])
          end
          parse("a, b, *c, d = 1,2,3,4,5", v).find_node(:multipleasgn).tap do |masgn|
            masgn.should have_static_assignments([[:a, 1], [:b, 2], [:c, [3, 4]], [:d, 5]])
          end
          parse("a, *b, c, d = 1,2,3,4,5", v).find_node(:multipleasgn).tap do |masgn|
            masgn.should have_static_assignments([[:a, 1], [:b, [2, 3]], [:c, 4], [:d, 5]])
          end
        end

        it "parses a splat that should recieve no assignment" do
          parse("a,*b,c,d = 1,2,3", v).find_node(:multipleasgn).tap do |masgn|
            masgn.should have_static_assignments([[:a, 1], [:b, []], [:c, 2], [:d, 3]])
          end
        end
      end
    end
  end
end

ruby 在从JRuby-Parser添加context-blocks示例之前。

在从JRuby-Parser添加context-blocks示例之前。

BEFORE-static_analysis_spec.rb
require_relative '../helpers'

describe Parser do
  VERSIONS.each do |v|
    if v == 2.0
      it "test 2.0" do
        parse("def foo(a:1); p a; end", v)
      end
    end
    if v != 1.8
      it "parses a simple multiple assignment [#{v}]" do
        parse("a,b,c = 1,2,3", v).find_node(:multipleasgn19).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, 2], [:c, 3]])
        end
      end

      it "parses a simple lhs splat multiple assignment [#{v}]" do
        parse("a,*b = 1,2,3", v).find_node(:multipleasgn19).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, [2, 3]]])
        end
        parse("a,b,*c = 1,2,3,4", v).find_node(:multipleasgn19).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, 2], [:c, [3,4]]])
        end
      end

      it "parses a simple lhs splat multiple assignment [#{v}]" do
        parse("*a,b = 1,2,3", v).find_node(:multipleasgn19).tap do |masgn|
          masgn.should have_static_assignments([[:a, [1, 2]], [:b, 3]])
        end
        parse("*a,b,c = 1,2,3,4", v).find_node(:multipleasgn19).tap do |masgn|
          masgn.should have_static_assignments([[:a, [1, 2]], [:b, 3], [:c, 4]])
        end
      end

      it "parses a simple lhs splat multiple assignment [#{v}]" do
        parse("a,*b, c = 1,2,3,4", v).find_node(:multipleasgn19).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, [2, 3]], [:c, 4]])
        end
        parse("a, b, *c, d = 1,2,3,4,5", v).find_node(:multipleasgn19).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, 2], [:c, [3, 4]], [:d, 5]])
        end
        parse("a, *b, c, d = 1,2,3,4,5", v).find_node(:multipleasgn19).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, [2, 3]], [:c, 4], [:d, 5]])
        end
      end

      it "parses a simple lhs splat multiple assignment [#{v}]" do
        parse("a,*b,c,d = 1,2,3", v).find_node(:multipleasgn19).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, []], [:c, 2], [:d, 3]])
        end
      end

      it "parses a simple rhs splat multiple assignment [#{v}]" do
        ast = parse("a,*b = 1,*foo", v)
        foo = ast.find_node(:vcall)
        ast.find_node(:multipleasgn19).tap do |masgn|
          masgn.should have_static_assignments([[:a, 1], [:b, foo]])
        end
      end

      it "parses a simple rhs splat multiple assignment [#{v}]" do
        ast = parse("*a,b = *foo,1", v)
        splatted_foo = ast.find_node(:splat)
        ast.find_node(:multipleasgn19).tap do |masgn|
          masgn.should have_static_assignments([[:a, splatted_foo], [:b, 1]])
        end
      end
    end

    it "method: can parse an empty body method with unused param [#{v}]" do
      parse("def foo(a)\nend").find_node(:defn) do |defn|
        defn.args.get_normative_parameter_name_list(true).each do |parameter|
          defn.is_parameter_used(parameter).should == false
        end
      end
    end

    it "method: Can detect simple parameter is used" do
      parse("def foo(a); a; end").find_node(:defn) do |defn|
        defn.args.get_normative_parameter_name_list(true).each do |parameter|
          defn.is_parameter_used(parameter).should == true
        end
      end

      parse("def foo(a,b); a; b; end").find_node(:defn) do |defn|
        defn.args.get_normative_parameter_name_list(true).each do |parameter|
          defn.is_parameter_used(parameter).should == true
        end
      end

      parse("def foo(a,b); a=1; b; end").find_node(:defn) do |defn|
        defn.is_parameter_used("a").should == false
        defn.is_parameter_used("b").should == true
      end
    end

    it "method: Can detect some simple parameters are used" do
      parse("def foo(a,b); b; end").find_node(:defn) do |defn|
        defn.is_parameter_used("a").should == false
        defn.is_parameter_used("b").should == true
      end

      parse("def foo(a,b); b if true; end").find_node(:defn) do |defn|
        defn.is_parameter_used("a").should == false
        defn.is_parameter_used("b").should == true
      end

      parse("def foo(a,b); proc { b if true }; end").find_node(:defn) do |defn|
        defn.is_parameter_used("a").should == false
        defn.is_parameter_used("b").should == true
      end

      parse("def foo a, b, c\nputs a, b, c\nend").find_node(:defn) do |defn|
        defn.is_parameter_used("a").should == true
        defn.is_parameter_used("b").should == true
        defn.is_parameter_used("c").should == true
      end

      parse("def foo(a, b); b.each_answer {|n| data if n == a }; end") do |defn|
        defn.is_parameter_used("a").should == true
        defn.is_parameter_used("b").should == true
      end
    end

    it "method: Can detect some simple optarg params are used" do
      parse("def foo(a,b = {}); b; end").find_node(:defn) do |defn|
        defn.is_parameter_used("a").should == false
        defn.is_parameter_used("b").should == true
      end
    end

    it "method: Can detect zsuper usage" do
      parse("def foo(a,b = {}); super; end").find_node(:defn) do |defn|
        defn.is_parameter_used("a").should == true
        defn.is_parameter_used("b").should == true
      end
    end

    it "block/iter: can parse an empty proc body with unused param [#{v}]" do
      parse("proc do |a|\nend").find_node(:iter) do |iter|
        iter.is_parameter_used("a").should == false
      end
    end

    it "block/iter: Can detect simple parameter is used" do
      parse("proc { |a, b| a; b }").find_node(:iter) do |iter|
        iter.is_parameter_used("a").should == true
        iter.is_parameter_used("b").should == true
      end
    end

    it "block/iter: Can detect simple parameter is used" do
      parse("proc { |a, b| a=1; b }").find_node(:iter) do |iter|
        iter.is_parameter_used("a").should == false
        iter.is_parameter_used("b").should == true
      end
    end

    it "block/iter: Can detect some simple parameters are used" do
      parse("proc {|a,b| b }").find_node(:iter) do |iter|
        iter.is_parameter_used("a").should == false
        iter.is_parameter_used("b").should == true
      end

      parse("proc {|a,b| b if true }").find_node(:iter) do |iter|
        iter.is_parameter_used("a").should == false
        iter.is_parameter_used("b").should == true
      end

      parse("proc {|a,b| proc { b if true } }").find_node(:iter) do |iter|
        iter.is_parameter_used("a").should == false
        iter.is_parameter_used("b").should == true
      end

      parse("proc {|a, b, c| puts a, b, c }").find_node(:iter) do |iter|
        iter.is_parameter_used("a").should == true
        iter.is_parameter_used("b").should == true
        iter.is_parameter_used("c").should == true
      end

      parse("proc {|a, b| b.each_answer {|n| data if n == a } }") do |iter|
        iter.is_parameter_used("a").should == true
        iter.is_parameter_used("b").should == true
      end
    end
  end
end