提交 eb23754e 编写于 作者: P Piotr Sarnacki 提交者: Łukasz Strzałkowski

Move template tests from actionpack to actionview

上级 5bcdf4fa
...@@ -7,14 +7,14 @@ task :default => :test ...@@ -7,14 +7,14 @@ task :default => :test
# Run the unit tests # Run the unit tests
desc "Run all unit tests" desc "Run all unit tests"
task :test => [:test_action_pack, :test_active_record_integration] task :test => [:test_action_pack]
Rake::TestTask.new(:test_action_pack) do |t| Rake::TestTask.new(:test_action_pack) do |t|
t.libs << 'test' t.libs << 'test'
# make sure we include the tests in alphabetical order as on some systems # make sure we include the tests in alphabetical order as on some systems
# this will not happen automatically and the tests (as a whole) will error # this will not happen automatically and the tests (as a whole) will error
t.test_files = Dir.glob('test/{abstract,controller,dispatch,template,assertions,journey}/**/*_test.rb').sort t.test_files = Dir.glob('test/{abstract,controller,dispatch,assertions,journey}/**/*_test.rb').sort
t.warning = true t.warning = true
t.verbose = true t.verbose = true
...@@ -29,19 +29,6 @@ namespace :test do ...@@ -29,19 +29,6 @@ namespace :test do
end end
end end
namespace :test do
Rake::TestTask.new(:template) do |t|
t.libs << 'test'
t.pattern = 'test/template/**/*.rb'
end
end
desc 'ActiveRecord Integration Tests'
Rake::TestTask.new(:test_active_record_integration) do |t|
t.libs << 'test'
t.test_files = Dir.glob("test/activerecord/*_test.rb")
end
spec = eval(File.read('actionpack.gemspec')) spec = eval(File.read('actionpack.gemspec'))
Gem::PackageTask.new(spec) do |p| Gem::PackageTask.new(spec) do |p|
......
require 'rake/testtask'
require 'rake/packagetask'
require 'rubygems/package_task'
desc "Default Task"
task :default => :test
# Run the unit tests
desc "Run all unit tests"
task :test => [:test_action_view, :test_active_record_integration]
Rake::TestTask.new(:test_action_view) do |t|
t.libs << 'test'
# make sure we include the tests in alphabetical order as on some systems
# this will not happen automatically and the tests (as a whole) will error
t.test_files = Dir.glob('test/template/**/*_test.rb').sort
t.warning = true
t.verbose = true
end
namespace :test do
Rake::TestTask.new(:isolated) do |t|
t.libs << 'test'
t.pattern = 'test/ts_isolated.rb'
end
Rake::TestTask.new(:template) do |t|
t.libs << 'test'
t.pattern = 'test/template/**/*.rb'
end
end
desc 'ActiveRecord Integration Tests'
Rake::TestTask.new(:test_active_record_integration) do |t|
t.libs << 'test'
t.test_files = Dir.glob("test/activerecord/*_test.rb")
end
spec = eval(File.read('actionview.gemspec'))
Gem::PackageTask.new(spec) do |p|
p.gem_spec = spec
end
desc "Release to gemcutter"
task :release => :package do
require 'rake/gemcutter'
Rake::Gemcutter::Tasks.new(spec).define
Rake::Task['gem:push'].invoke
end
task :lines do
lines, codelines, total_lines, total_codelines = 0, 0, 0, 0
FileList["lib/**/*.rb"].each do |file_name|
next if file_name =~ /vendor/
File.open(file_name, 'r') do |f|
while line = f.gets
lines += 1
next if line =~ /^\s*$/
next if line =~ /^\s*#/
codelines += 1
end
end
puts "L: #{sprintf("%4d", lines)}, LOC #{sprintf("%4d", codelines)} | #{file_name}"
total_lines += lines
total_codelines += codelines
lines, codelines = 0, 0
end
puts "Total: Lines #{total_lines}, LOC #{total_codelines}"
end
require File.expand_path('../../../load_paths', __FILE__)
$:.unshift(File.dirname(__FILE__) + '/lib')
$:.unshift(File.dirname(__FILE__) + '/fixtures/helpers')
$:.unshift(File.dirname(__FILE__) + '/fixtures/alternate_helpers')
ENV['TMPDIR'] = File.join(File.dirname(__FILE__), 'tmp')
require 'active_support/core_ext/kernel/reporting'
# These are the normal settings that will be set up by Railties
# TODO: Have these tests support other combinations of these values
silence_warnings do
Encoding.default_internal = "UTF-8"
Encoding.default_external = "UTF-8"
end
require 'active_support/testing/autorun'
require 'abstract_controller'
require 'action_controller'
require 'action_view'
require 'action_view/testing/resolvers'
require 'action_dispatch'
require 'active_support/dependencies'
require 'active_model'
require 'active_record'
require 'action_controller/caching'
require 'pp' # require 'pp' early to prevent hidden_methods from not picking up the pretty-print methods until too late
module Rails
class << self
def env
@_env ||= ActiveSupport::StringInquirer.new(ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "test")
end
end
end
ActiveSupport::Dependencies.hook!
Thread.abort_on_exception = true
# Show backtraces for deprecated behavior for quicker cleanup.
ActiveSupport::Deprecation.debug = true
# Register danish language for testing
I18n.backend.store_translations 'da', {}
I18n.backend.store_translations 'pt-BR', {}
ORIGINAL_LOCALES = I18n.available_locales.map {|locale| locale.to_s }.sort
FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures')
FIXTURES = Pathname.new(FIXTURE_LOAD_PATH)
module RackTestUtils
def body_to_string(body)
if body.respond_to?(:each)
str = ""
body.each {|s| str << s }
str
else
body
end
end
extend self
end
module RenderERBUtils
def view
@view ||= begin
path = ActionView::FileSystemResolver.new(FIXTURE_LOAD_PATH)
view_paths = ActionView::PathSet.new([path])
ActionView::Base.new(view_paths)
end
end
def render_erb(string)
@virtual_path = nil
template = ActionView::Template.new(
string.strip,
"test template",
ActionView::Template::Handlers::ERB,
{})
template.render(self, {}).strip
end
end
SharedTestRoutes = ActionDispatch::Routing::RouteSet.new
module ActionDispatch
module SharedRoutes
def before_setup
@routes = SharedTestRoutes
super
end
end
# Hold off drawing routes until all the possible controller classes
# have been loaded.
module DrawOnce
class << self
attr_accessor :drew
end
self.drew = false
def before_setup
super
return if DrawOnce.drew
SharedTestRoutes.draw do
get ':controller(/:action)'
end
ActionDispatch::IntegrationTest.app.routes.draw do
get ':controller(/:action)'
end
DrawOnce.drew = true
end
end
end
module ActiveSupport
class TestCase
include ActionDispatch::DrawOnce
end
end
class RoutedRackApp
attr_reader :routes
def initialize(routes, &blk)
@routes = routes
@stack = ActionDispatch::MiddlewareStack.new(&blk).build(@routes)
end
def call(env)
@stack.call(env)
end
end
class BasicController
attr_accessor :request
def config
@config ||= ActiveSupport::InheritableOptions.new(ActionController::Base.config).tap do |config|
# VIEW TODO: View tests should not require a controller
public_dir = File.expand_path("../fixtures/public", __FILE__)
config.assets_dir = public_dir
config.javascripts_dir = "#{public_dir}/javascripts"
config.stylesheets_dir = "#{public_dir}/stylesheets"
config.assets = ActiveSupport::InheritableOptions.new({ :prefix => "assets" })
config
end
end
end
class ActionDispatch::IntegrationTest < ActiveSupport::TestCase
include ActionDispatch::SharedRoutes
def self.build_app(routes = nil)
RoutedRackApp.new(routes || ActionDispatch::Routing::RouteSet.new) do |middleware|
middleware.use "ActionDispatch::ShowExceptions", ActionDispatch::PublicExceptions.new("#{FIXTURE_LOAD_PATH}/public")
middleware.use "ActionDispatch::DebugExceptions"
middleware.use "ActionDispatch::Callbacks"
middleware.use "ActionDispatch::ParamsParser"
middleware.use "ActionDispatch::Cookies"
middleware.use "ActionDispatch::Flash"
middleware.use "Rack::Head"
yield(middleware) if block_given?
end
end
self.app = build_app
# Stub Rails dispatcher so it does not get controller references and
# simply return the controller#action as Rack::Body.
class StubDispatcher < ::ActionDispatch::Routing::RouteSet::Dispatcher
protected
def controller_reference(controller_param)
controller_param
end
def dispatch(controller, action, env)
[200, {'Content-Type' => 'text/html'}, ["#{controller}##{action}"]]
end
end
def self.stub_controllers
old_dispatcher = ActionDispatch::Routing::RouteSet::Dispatcher
ActionDispatch::Routing::RouteSet.module_eval { remove_const :Dispatcher }
ActionDispatch::Routing::RouteSet.module_eval { const_set :Dispatcher, StubDispatcher }
yield ActionDispatch::Routing::RouteSet.new
ensure
ActionDispatch::Routing::RouteSet.module_eval { remove_const :Dispatcher }
ActionDispatch::Routing::RouteSet.module_eval { const_set :Dispatcher, old_dispatcher }
end
def with_routing(&block)
temporary_routes = ActionDispatch::Routing::RouteSet.new
old_app, self.class.app = self.class.app, self.class.build_app(temporary_routes)
old_routes = SharedTestRoutes
silence_warnings { Object.const_set(:SharedTestRoutes, temporary_routes) }
yield temporary_routes
ensure
self.class.app = old_app
silence_warnings { Object.const_set(:SharedTestRoutes, old_routes) }
end
def with_autoload_path(path)
path = File.join(File.dirname(__FILE__), "fixtures", path)
if ActiveSupport::Dependencies.autoload_paths.include?(path)
yield
else
begin
ActiveSupport::Dependencies.autoload_paths << path
yield
ensure
ActiveSupport::Dependencies.autoload_paths.reject! {|p| p == path}
ActiveSupport::Dependencies.clear
end
end
end
end
# Temporary base class
class Rack::TestCase < ActionDispatch::IntegrationTest
def self.testing(klass = nil)
if klass
@testing = "/#{klass.name.underscore}".sub!(/_controller$/, '')
else
@testing
end
end
def get(thing, *args)
if thing.is_a?(Symbol)
super("#{self.class.testing}/#{thing}", *args)
else
super
end
end
def assert_body(body)
assert_equal body, Array(response.body).join
end
def assert_status(code)
assert_equal code, response.status
end
def assert_response(body, status = 200, headers = {})
assert_body body
assert_status status
headers.each do |header, value|
assert_header header, value
end
end
def assert_content_type(type)
assert_equal type, response.headers["Content-Type"]
end
def assert_header(name, value)
assert_equal value, response.headers[name]
end
end
module ActionController
class Base
include ActionController::Testing
# This stub emulates the Railtie including the URL helpers from a Rails application
include SharedTestRoutes.url_helpers
include SharedTestRoutes.mounted_helpers
self.view_paths = FIXTURE_LOAD_PATH
def self.test_routes(&block)
routes = ActionDispatch::Routing::RouteSet.new
routes.draw(&block)
include routes.url_helpers
end
end
class TestCase
include ActionDispatch::TestProcess
include ActionDispatch::SharedRoutes
end
end
class ::ApplicationController < ActionController::Base
end
module ActionView
class TestCase
# Must repeat the setup because AV::TestCase is a duplication
# of AC::TestCase
include ActionDispatch::SharedRoutes
end
end
class Workshop
extend ActiveModel::Naming
include ActiveModel::Conversion
attr_accessor :id
def initialize(id)
@id = id
end
def persisted?
id.present?
end
def to_s
id.to_s
end
end
module ActionDispatch
class DebugExceptions
private
remove_method :stderr_logger
# Silence logger
def stderr_logger
nil
end
end
end
module ActionDispatch
module RoutingVerbs
def get(uri_or_host, path = nil)
host = uri_or_host.host unless path
path ||= uri_or_host.path
params = {'PATH_INFO' => path,
'REQUEST_METHOD' => 'GET',
'HTTP_HOST' => host}
routes.call(params)[2].join
end
end
end
module RoutingTestHelpers
def url_for(set, options, recall = nil)
set.send(:url_for, options.merge(:only_path => true, :_recall => recall))
end
end
class ResourcesController < ActionController::Base
def index() render :nothing => true end
alias_method :show, :index
end
class ThreadsController < ResourcesController; end
class MessagesController < ResourcesController; end
class CommentsController < ResourcesController; end
class ReviewsController < ResourcesController; end
class AuthorsController < ResourcesController; end
class LogosController < ResourcesController; end
class AccountsController < ResourcesController; end
class AdminController < ResourcesController; end
class ProductsController < ResourcesController; end
class ImagesController < ResourcesController; end
class PreferencesController < ResourcesController; end
module Backoffice
class ProductsController < ResourcesController; end
class TagsController < ResourcesController; end
class ManufacturersController < ResourcesController; end
class ImagesController < ResourcesController; end
module Admin
class ProductsController < ResourcesController; end
class ImagesController < ResourcesController; end
end
end
require 'abstract_unit'
# Define the essentials
class ActiveRecordTestConnector
cattr_accessor :able_to_connect
cattr_accessor :connected
# Set our defaults
self.connected = false
self.able_to_connect = true
end
# Try to grab AR
unless defined?(ActiveRecord) && defined?(FixtureSet)
begin
PATH_TO_AR = "#{File.dirname(__FILE__)}/../../activerecord/lib"
raise LoadError, "#{PATH_TO_AR} doesn't exist" unless File.directory?(PATH_TO_AR)
$LOAD_PATH.unshift PATH_TO_AR
require 'active_record'
rescue LoadError => e
$stderr.print "Failed to load Active Record. Skipping Active Record assertion tests: #{e}"
ActiveRecordTestConnector.able_to_connect = false
end
end
$stderr.flush
# Define the rest of the connector
class ActiveRecordTestConnector
class << self
def setup
unless self.connected || !self.able_to_connect
setup_connection
load_schema
require_fixture_models
self.connected = true
end
rescue Exception => e # errors from ActiveRecord setup
$stderr.puts "\nSkipping ActiveRecord assertion tests: #{e}"
#$stderr.puts " #{e.backtrace.join("\n ")}\n"
self.able_to_connect = false
end
private
def setup_connection
if Object.const_defined?(:ActiveRecord)
defaults = { :database => ':memory:' }
adapter = defined?(JRUBY_VERSION) ? 'jdbcsqlite3' : 'sqlite3'
options = defaults.merge :adapter => adapter, :timeout => 500
ActiveRecord::Base.establish_connection(options)
ActiveRecord::Base.configurations = { 'sqlite3_ar_integration' => options }
ActiveRecord::Base.connection
Object.send(:const_set, :QUOTED_TYPE, ActiveRecord::Base.connection.quote_column_name('type')) unless Object.const_defined?(:QUOTED_TYPE)
else
raise "Can't setup connection since ActiveRecord isn't loaded."
end
end
# Load actionpack sqlite tables
def load_schema
File.read(File.dirname(__FILE__) + "/fixtures/db_definitions/sqlite.sql").split(';').each do |sql|
ActiveRecord::Base.connection.execute(sql) unless sql.blank?
end
end
def require_fixture_models
Dir.glob(File.dirname(__FILE__) + "/fixtures/*.rb").each {|f| require f}
end
end
end
class ActiveRecordTestCase < ActionController::TestCase
include ActiveRecord::TestFixtures
# Set our fixture path
if ActiveRecordTestConnector.able_to_connect
self.fixture_path = [FIXTURE_LOAD_PATH]
self.use_transactional_fixtures = false
end
def self.fixtures(*args)
super if ActiveRecordTestConnector.connected
end
def run(*args)
super if ActiveRecordTestConnector.connected
end
end
ActiveRecordTestConnector.setup
top level partial html
\ No newline at end of file
top level partial
\ No newline at end of file
module FooHelper
redefine_method(:baz) {}
end
<%= greeting %> bad customer: <%= bad_customer.name %><%= bad_customer_counter %>
\ No newline at end of file
/blog/blog.html
\ No newline at end of file
/blog/index.html
\ No newline at end of file
/blog/subdir/index.html
\ No newline at end of file
<h1>Kein Kommentar</h1>
\ No newline at end of file
xml.h1 'No Comment'
\ No newline at end of file
<h1>No Comment</h1>
\ No newline at end of file
<error>No Comment</error>
\ No newline at end of file
thirty_seven_signals:
id: 1
name: 37Signals
rating: 4
TextDrive:
id: 2
name: TextDrive
rating: 4
PlanetArgon:
id: 3
name: Planet Argon
rating: 4
Google:
id: 4
name: Google
rating: 4
Ionist:
id: 5
name: Ioni.st
rating: 4
\ No newline at end of file
class Company < ActiveRecord::Base
has_one :mascot
self.sequence_name = :companies_nonstd_seq
validates_presence_of :name
def validate
errors.add('rating', 'rating should not be 2') if rating == 2
end
end
Hello custom patterns!
\ No newline at end of file
Another template!
\ No newline at end of file
Hello custom patterns!
\ No newline at end of file
<%= greeting %>: <%= customer.name %>
\ No newline at end of file
CREATE TABLE 'companies' (
'id' INTEGER PRIMARY KEY NOT NULL,
'name' TEXT DEFAULT NULL,
'rating' INTEGER DEFAULT 1
);
CREATE TABLE 'replies' (
'id' INTEGER PRIMARY KEY NOT NULL,
'content' text,
'created_at' datetime,
'updated_at' datetime,
'topic_id' integer,
'developer_id' integer
);
CREATE TABLE 'topics' (
'id' INTEGER PRIMARY KEY NOT NULL,
'title' varchar(255),
'subtitle' varchar(255),
'content' text,
'created_at' datetime,
'updated_at' datetime
);
CREATE TABLE 'developers' (
'id' INTEGER PRIMARY KEY NOT NULL,
'name' TEXT DEFAULT NULL,
'salary' INTEGER DEFAULT 70000,
'created_at' DATETIME DEFAULT NULL,
'updated_at' DATETIME DEFAULT NULL
);
CREATE TABLE 'projects' (
'id' INTEGER PRIMARY KEY NOT NULL,
'name' TEXT DEFAULT NULL
);
CREATE TABLE 'developers_projects' (
'developer_id' INTEGER NOT NULL,
'project_id' INTEGER NOT NULL,
'joined_on' DATE DEFAULT NULL,
'access_level' INTEGER DEFAULT 1
);
CREATE TABLE 'mascots' (
'id' INTEGER PRIMARY KEY NOT NULL,
'company_id' INTEGER NOT NULL,
'name' TEXT DEFAULT NULL
);
\ No newline at end of file
class Developer < ActiveRecord::Base
has_and_belongs_to_many :projects
has_many :replies
has_many :topics, :through => :replies
accepts_nested_attributes_for :projects
end
class DeVeLoPeR < ActiveRecord::Base
self.table_name = "developers"
end
david:
id: 1
name: David
salary: 80000
jamis:
id: 2
name: Jamis
salary: 150000
<% (3..10).each do |digit| %>
dev_<%= digit %>:
id: <%= digit %>
name: fixture_<%= digit %>
salary: 100000
<% end %>
poor_jamis:
id: 11
name: Jamis
salary: 9000
\ No newline at end of file
<%= developer.name %>
\ No newline at end of file
david_action_controller:
developer_id: 1
project_id: 2
joined_on: 2004-10-10
david_active_record:
developer_id: 1
project_id: 1
joined_on: 2004-10-10
jamis_active_record:
developer_id: 2
project_id: 1
\ No newline at end of file
<%= render partial: "comments/comment", collection: commentable.comments %>
THIS BE WHERE THEM MESSAGE GO, YO!
\ No newline at end of file
<%= render "header" %>
<%= render partial: "form" %>
<%= render @message %>
<%= render ( @message.events ) %>
<%= render :partial => "comments/comment", :collection => @message.comments %>
<%= render @messages %>
<%= render @events %>
<%# Template Dependency: messages/message %>
<%= render "header" %>
<%= render "comments/comments" %>
<%= render "messages/actions/move" %>
<%= render @message.history.events %>
<%# render "something_missing" %>
<%
# Template Dependency: messages/form
%>
\ No newline at end of file
Living in a nested world
\ No newline at end of file
<% cache do %>
Old fragment caching in a partial
<% end %>
Hello
<%= cache do %>This bit's fragment cached<% end %>
<%= 'Ciao' %>
<body>
<%= cache 'nodigest', skip_digest: true do %><p>ERB</p><% end %>
</body>
<%= render :partial => 'partial' %>
\ No newline at end of file
<%= render :inline => 'Some inline content' %>
<%= cache do %>Some cached content<% end %>
<%= greeting %> good customer: <%= good_customer.name %><%= good_customer_counter %>
\ No newline at end of file
Hello world!
\ No newline at end of file
module AbcHelper
def bare_a() end
def bare_b() end
def bare_c() end
end
module Fun
module GamesHelper
def stratego() "Iz guuut!" end
end
end
\ No newline at end of file
module Fun
module PdfHelper
def foobar() 'baz' end
end
end
module HelperyTestHelper
def helpery_test
"Default"
end
end
module JustMeHelper
def me() "mine!" end
end
\ No newline at end of file
module MeTooHelper
def me() "me too!" end
end
\ No newline at end of file
module Pack1Helper
def conflicting_helper
"pack1"
end
end
module Pack2Helper
def conflicting_helper
"pack2"
end
end
controller_name_space/nested.erb <%= yield %>
\ No newline at end of file
item.erb <%= yield %>
\ No newline at end of file
layout_test.erb <%= yield %>
\ No newline at end of file
../../symlink_parent
\ No newline at end of file
layouts/third_party_template_library.mab
\ No newline at end of file
<div id="column"><%= yield :column %></div>
<div id="content"><%= yield %></div>
\ No newline at end of file
<title><%= yield Struct.new(:name).new("David") %></title>
\ No newline at end of file
<%= render :partial => 'test/partial' %>
<%= yield %>
<%= render(:layout => "layout_for_partial", :locals => { :name => "Anthony" }) do %>Inside from first block in layout<% "Return value should be discarded" %><% end %>
<%= yield %>
<%= render(:layout => "layout_for_partial", :locals => { :name => "Ramm" }) do %>Inside from second block in layout<% end %>
xml.wrapper do
xml << yield
end
\ No newline at end of file
<%= render( :layout => "layout_for_partial", :partial => "partial_for_use_in_layout", :locals => {:name => 'Anthony' } ) %>
<%= yield %>
<%= render( :layout => "layout_for_partial", :partial => "partial_for_use_in_layout", :locals => {:name => 'Ramm' } ) %>
\ No newline at end of file
<html><%= yield %><%= @variable_for_layout %></html>
\ No newline at end of file
<%= yield :header -%>
<%= yield -%>
<%= yield :footer -%>
<%= yield(:unknown).presence || "." -%>
\ No newline at end of file
<title><%= @title || yield(:title) %></title>
<%= yield -%>
\ No newline at end of file
<%= render :partial => "partial_only_html" %><%= yield %>
XHR!
<%= yield %>
\ No newline at end of file
<title><%= yield :title %></title>
<%= yield %>
<%= render :partial => 'test/partial' %>
<%= yield %>
class Mascot < ActiveRecord::Base
belongs_to :company
end
\ No newline at end of file
upload_bird:
id: 1
company_id: 1
name: The Upload Bird
\ No newline at end of file
<%= mascot.name %>
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册