activegroonga 0.0.7 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. data/README.ja.rdoc +4 -1
  2. data/README.rdoc +4 -1
  3. data/Rakefile +18 -4
  4. data/lib/active_groonga.rb +25 -52
  5. data/lib/active_groonga/base.rb +164 -1480
  6. data/lib/active_groonga/callbacks.rb +26 -7
  7. data/lib/active_groonga/database.rb +55 -0
  8. data/lib/active_groonga/{dirty.rb → error.rb} +20 -10
  9. data/lib/active_groonga/locale/en.yml +5 -0
  10. data/lib/active_groonga/migration.rb +44 -113
  11. data/lib/active_groonga/migrator.rb +172 -0
  12. data/lib/active_groonga/persistence.rb +172 -0
  13. data/lib/active_groonga/railtie.rb +66 -0
  14. data/lib/active_groonga/railties/configurable.rb +47 -0
  15. data/lib/active_groonga/railties/groonga.rake +167 -0
  16. data/lib/active_groonga/result_set.rb +89 -0
  17. data/lib/active_groonga/schema.rb +54 -188
  18. data/lib/active_groonga/validations.rb +54 -5
  19. data/lib/active_groonga/vector.rb +64 -0
  20. data/lib/active_groonga/version.rb +3 -3
  21. data/lib/{active_groonga/aggregations.rb → rails/generators/active_groonga.rb} +17 -10
  22. data/lib/rails/generators/active_groonga/migration/column.rb +101 -0
  23. data/lib/rails/generators/active_groonga/migration/migration_generator.rb +53 -0
  24. data/lib/rails/generators/active_groonga/migration/templates/migration.rb +29 -0
  25. data/lib/rails/generators/active_groonga/model/model_generator.rb +60 -0
  26. data/lib/rails/generators/active_groonga/model/templates/migration.rb +16 -0
  27. data/lib/rails/generators/active_groonga/model/templates/model.rb +2 -0
  28. data/lib/rails/generators/active_groonga/model/templates/module.rb +5 -0
  29. data/test-unit-notify/COPYING +502 -0
  30. data/test-unit-notify/Rakefile +47 -0
  31. data/test-unit-notify/lib/test/unit/notify.rb +127 -0
  32. data/test-unit/COPYING +56 -0
  33. data/test-unit/GPL +340 -0
  34. data/test-unit/PSFL +271 -0
  35. data/test-unit/Rakefile +18 -5
  36. data/test-unit/html/bar.svg +153 -0
  37. data/test-unit/html/developer.svg +469 -0
  38. data/test-unit/html/favicon.ico +0 -0
  39. data/test-unit/html/favicon.svg +82 -0
  40. data/test-unit/html/heading-mark.svg +393 -0
  41. data/test-unit/html/index.html +235 -13
  42. data/test-unit/html/index.html.ja +258 -15
  43. data/test-unit/html/install.svg +636 -0
  44. data/test-unit/html/logo.svg +483 -0
  45. data/test-unit/html/test-unit.css +339 -0
  46. data/test-unit/html/tutorial.svg +559 -0
  47. data/test-unit/lib/test/unit.rb +29 -43
  48. data/test-unit/lib/test/unit/assertionfailederror.rb +11 -0
  49. data/test-unit/lib/test/unit/assertions.rb +202 -20
  50. data/test-unit/lib/test/unit/autorunner.rb +51 -20
  51. data/test-unit/lib/test/unit/collector.rb +1 -8
  52. data/test-unit/lib/test/unit/collector/dir.rb +1 -1
  53. data/test-unit/lib/test/unit/collector/load.rb +16 -9
  54. data/test-unit/lib/test/unit/color-scheme.rb +19 -3
  55. data/test-unit/lib/test/unit/diff.rb +240 -38
  56. data/test-unit/lib/test/unit/error.rb +4 -0
  57. data/test-unit/lib/test/unit/failure.rb +31 -5
  58. data/test-unit/lib/test/unit/notification.rb +8 -4
  59. data/test-unit/lib/test/unit/omission.rb +51 -3
  60. data/test-unit/lib/test/unit/pending.rb +4 -0
  61. data/test-unit/lib/test/unit/priority.rb +2 -3
  62. data/test-unit/lib/test/unit/testcase.rb +65 -7
  63. data/test-unit/lib/test/unit/testresult.rb +34 -2
  64. data/test-unit/lib/test/unit/ui/console/testrunner.rb +197 -45
  65. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +14 -0
  66. data/test-unit/lib/test/unit/ui/tap/testrunner.rb +2 -12
  67. data/test-unit/lib/test/unit/ui/testrunner.rb +33 -0
  68. data/test-unit/lib/test/unit/util/backtracefilter.rb +1 -0
  69. data/test-unit/lib/test/unit/util/output.rb +31 -0
  70. data/test-unit/lib/test/unit/version.rb +1 -1
  71. data/test-unit/sample/{tc_adder.rb → test_adder.rb} +3 -1
  72. data/test-unit/sample/{tc_subtracter.rb → test_subtracter.rb} +3 -1
  73. data/test-unit/sample/test_user.rb +1 -0
  74. data/test-unit/test/collector/test-descendant.rb +2 -4
  75. data/test-unit/test/collector/test-load.rb +121 -8
  76. data/test-unit/test/collector/test_objectspace.rb +7 -5
  77. data/test-unit/test/run-test.rb +2 -0
  78. data/test-unit/test/test-color-scheme.rb +11 -2
  79. data/test-unit/test/test-diff.rb +48 -7
  80. data/test-unit/test/test-omission.rb +1 -1
  81. data/test-unit/test/test-testcase.rb +57 -20
  82. data/test-unit/test/test_assertions.rb +128 -13
  83. data/test-unit/test/ui/test_tap.rb +33 -0
  84. data/test-unit/test/util/test-output.rb +11 -0
  85. data/test/active-groonga-test-utils.rb +50 -36
  86. data/test/fixtures/site.rb +2 -0
  87. data/test/run-test.rb +36 -9
  88. data/test/test-associations.rb +5 -2
  89. data/test/test-base.rb +39 -31
  90. data/test/test-callbacks.rb +13 -3
  91. data/test/test-persistence.rb +53 -0
  92. data/{lib/active_groonga/observer.rb → test/test-result-set.rb} +14 -12
  93. data/test/test-schema.rb +85 -22
  94. data/{lib/active_groonga/rails_support.rb → test/test-validations.rb} +15 -13
  95. metadata +85 -52
  96. data/lib/active_groonga/associations.rb +0 -93
  97. data/lib/active_groonga/associations/belongs_to_association.rb +0 -25
  98. data/lib/active_groonga/attribute_methods.rb +0 -36
  99. data/lib/active_groonga/column.rb +0 -137
  100. data/lib/active_groonga/dynamic_record_expression_builder.rb +0 -40
  101. data/lib/active_groonga/reflection.rb +0 -30
  102. data/lib/active_groonga/schema_dumper.rb +0 -163
  103. data/lib/active_groonga/tasks.rb +0 -16
  104. data/lib/active_groonga/tasks/groonga.rake +0 -164
  105. data/lib/active_groonga/timestamp.rb +0 -30
  106. data/rails/README +0 -28
  107. data/rails/init.rb +0 -70
  108. data/rails_generators/index_table_groonga/USAGE +0 -23
  109. data/rails_generators/index_table_groonga/index_table_groonga_generator.rb +0 -44
  110. data/rails_generators/index_table_groonga/templates/migration.rb +0 -12
  111. data/rails_generators/migration_groonga/USAGE +0 -29
  112. data/rails_generators/migration_groonga/migration_groonga_generator.rb +0 -19
  113. data/rails_generators/migration_groonga/templates/migration.rb +0 -11
  114. data/rails_generators/model_groonga/USAGE +0 -28
  115. data/rails_generators/model_groonga/model_groonga_generator.rb +0 -45
  116. data/rails_generators/model_groonga/templates/fixtures.yml +0 -17
  117. data/rails_generators/model_groonga/templates/migration.rb +0 -16
  118. data/rails_generators/model_groonga/templates/model.rb +0 -2
  119. data/rails_generators/model_groonga/templates/unit_test.rb +0 -8
  120. data/test-unit/html/classic.html +0 -15
  121. data/test-unit/sample/ts_examples.rb +0 -7
  122. data/test/test-schema-dumper.rb +0 -48
@@ -0,0 +1,172 @@
1
+ # Copyright (C) 2009-2010 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ module ActiveGroonga
17
+ module Persistence
18
+ def new_record?
19
+ @new_record
20
+ end
21
+
22
+ def destroyed?
23
+ @destroyed
24
+ end
25
+
26
+ def persisted?
27
+ not (new_record? or destroyed?)
28
+ end
29
+
30
+ def save(options={})
31
+ create_or_update
32
+ end
33
+
34
+ def save!(options={})
35
+ create_or_update or raise(RecordNotSaved)
36
+ end
37
+
38
+ def delete
39
+ table.delete(record_id) if persisted?
40
+ @destroyed = true
41
+ freeze
42
+ end
43
+
44
+ def destroy
45
+ table.delete(record_id) if persisted?
46
+ @destroyed = true
47
+ freeze
48
+ end
49
+
50
+ def becomes(klass)
51
+ became = klass.new
52
+ became.instance_variable_set("@attributes", @attributes)
53
+ became.instance_variable_set("@attributes_cache", @attributes_cache)
54
+ became.instance_variable_set("@new_record", new_record?)
55
+ became.instance_variable_set("@destroyed", destroyed?)
56
+ became
57
+ end
58
+
59
+ def update_attribute(name, value)
60
+ name = name.to_s
61
+ send("#{name}=", value)
62
+ save(:validate => false)
63
+ end
64
+
65
+ def update_attributes(attributes)
66
+ self.attributes = attributes
67
+ save
68
+ end
69
+
70
+ def update_attributes!(attributes)
71
+ self.attributes = attributes
72
+ save!
73
+ end
74
+
75
+ def reload
76
+ if new_record?
77
+ record = nil
78
+ else
79
+ record = table[record_id]
80
+ end
81
+ reload_attributes(record)
82
+ @attributes_cache = {}
83
+ self
84
+ end
85
+
86
+ private
87
+ def create_or_update
88
+ success = new_record? ? create : update
89
+ success != false
90
+ end
91
+
92
+ def create
93
+ attributes = {}
94
+ @attributes.each do |key, value|
95
+ next if value.nil?
96
+ if value.is_a?(Base)
97
+ value.save if value.new_record?
98
+ value = value.id
99
+ end
100
+ attributes[key] = value
101
+ end
102
+ if table.support_key?
103
+ record = table.add(key, attributes)
104
+ else
105
+ record = table.add(attributes)
106
+ end
107
+ record["created_at"] = Time.now if record.have_column?("created_at")
108
+ reload_attributes(record)
109
+ @id = record.id
110
+ @key = record.key if record.support_key?
111
+ @new_record = false
112
+ true
113
+ end
114
+
115
+ def update
116
+ record = self.class.table[record_id]
117
+ @attributes.each do |key, value|
118
+ if value.respond_to?(:record_id)
119
+ value = value.record_id
120
+ elsif value.is_a?(Hash) and value["id"]
121
+ value = value["id"]
122
+ end
123
+ record[key] = value
124
+ end
125
+ record["updated_at"] = Time.now if record.have_column?("updated_at")
126
+ true
127
+ end
128
+
129
+ def initial_attributes
130
+ attributes = {}
131
+ self.class.table.columns.each do |column|
132
+ next if column.index?
133
+ attributes[column.local_name] = nil
134
+ end
135
+ attributes
136
+ end
137
+
138
+ def extract_attributes(record)
139
+ attributes = {}
140
+ if record.support_key?
141
+ attributes["key"] = record.key
142
+ else
143
+ attributes["id"] = record.id
144
+ end
145
+ record.columns.each do |column|
146
+ next if column.is_a?(Groonga::IndexColumn)
147
+ value = record[column.local_name]
148
+ if value and column.reference?
149
+ value_class = self.class.custom_reference_class(column.local_name)
150
+ value_class ||= column.range.name.camelize.singularize.constantize
151
+ if column.vector?
152
+ value = Vector.new(self, value_class, value)
153
+ else
154
+ value = value_class.instantiate(value)
155
+ end
156
+ end
157
+ attributes[column.local_name] = value
158
+ end
159
+ attributes
160
+ end
161
+
162
+ def reload_attributes(record=nil)
163
+ if record.nil?
164
+ @attributes = initial_attributes
165
+ else
166
+ @attributes = extract_attributes(record)
167
+ end
168
+ @id = @attributes.delete("id")
169
+ @key = @attributes.delete("key")
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,66 @@
1
+ # Copyright (C) 2010 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ require "active_groonga"
17
+ require "rails"
18
+ require "active_model/railtie"
19
+
20
+ require "active_groonga/railties/configurable"
21
+
22
+ module ActiveGroonga
23
+ class Railtie < Rails::Railtie
24
+ config.active_groonga = ActiveSupport::OrderedOptions.new
25
+
26
+ config.generators.orm(:active_groonga,
27
+ :migration => true,
28
+ :timestamps => true)
29
+
30
+ config.before_configuration do
31
+ application_config = Rails.application.config
32
+ application_config.extend(Railties::Configurable)
33
+ application_config.paths.config.groonga("config/groonga.yml")
34
+ end
35
+
36
+ rake_tasks do
37
+ load "active_groonga/railties/groonga.rake"
38
+ end
39
+
40
+ console do
41
+ ActiveGroonga::Base
42
+ end
43
+
44
+ initializer("active_groonga.logger") do
45
+ ActiveSupport.on_load(:active_groonga) do
46
+ self.logger ||= ::Rails.logger
47
+ end
48
+ end
49
+
50
+ initializer("active_groonga.set_configurations") do |app|
51
+ ActiveSupport.on_load(:active_groonga) do
52
+ app.config.active_groonga.each do |key, value|
53
+ send("#{key}=", value)
54
+ end
55
+ end
56
+ end
57
+
58
+ initializer("active_groonga.initialize_database") do |app|
59
+ ActiveSupport.on_load(:active_groonga) do
60
+ self.configurations = app.config.groonga_configurations
61
+ configure(Rails.env)
62
+ database.ensure_available
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,47 @@
1
+ # Copyright (C) 2010 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ module ActiveGroonga
17
+ module Railties
18
+ module Configurable
19
+ def groonga_configurations
20
+ groonga_yml = paths.config.groonga.first
21
+ unless File.exist?(groonga_yml)
22
+ groonga_yml_example = "#{groonga_yml}.example"
23
+ if File.exist?(groonga_yml_example)
24
+ cp(groonga_yml_example, groonga_yml)
25
+ else
26
+ File.open(groonga_yml, "w") do |yml|
27
+ yml.puts(<<-EOC)
28
+ development:
29
+ database: db/groonga/development/db
30
+
31
+ # Warning: The database defined as "test" will be erased and
32
+ # re-generated from your development database when you run "rake".
33
+ # Do not set this db to the same as development or production.
34
+ test:
35
+ database: db/groonga/test/db
36
+
37
+ production:
38
+ database: db/groonga/production/db
39
+ EOC
40
+ end
41
+ end
42
+ end
43
+ YAML.load(ERB.new(IO.read(groonga_yml)).result)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,167 @@
1
+ # -*- ruby -*-
2
+ #
3
+ # Copyright (C) 2010 Kouhei Sutou <kou@clear-code.com>
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License version 2.1 as published by the Free Software Foundation.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+
18
+ namespace :groonga do
19
+ task :load_config => :rails_env do
20
+ require "active_groonga"
21
+ configurations = Rails.application.config.groonga_configurations
22
+ ActiveGroonga::Base.configurations = configurations
23
+ ActiveGroonga::Base.configure(Rails.env)
24
+ end
25
+
26
+ desc "Drops the database."
27
+ task :drop => :load_config do
28
+ database = ActiveGroonga::Base.database
29
+ database.remove if database
30
+ database_path = ActiveGroonga::Base.database_path
31
+ tables_path = Pathname("#{database_path}.talbes")
32
+ rm_rf(tables_path) if tables_path.exist?
33
+ end
34
+
35
+ desc "Create the database."
36
+ task :create => :load_config do
37
+ ActiveGroonga::Base.database.ensure_available
38
+ end
39
+
40
+ migrations_path = Proc.new do
41
+ Rails.root + "db" + "groonga" + "migrate"
42
+ end
43
+ desc "Migrate the database (options: VERSION=x)."
44
+ task :migrate => :environment do
45
+ version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
46
+ migrator = ActiveGroonga::Migrator.new(:up, migrations_path.call)
47
+ migrator.migrate(version)
48
+ Rake::Task["groonga:schema:dump"].invoke
49
+ end
50
+
51
+ desc 'Rolls the schema back to the previous version (specify steps w/ STEP=n).'
52
+ task :rollback => :environment do
53
+ step = ENV['STEP'] ? ENV['STEP'].to_i : 1
54
+ migrator = ActiveGroonga::Migrator.new(:down, migrations_path.call)
55
+ version, migrated_at = migrator.migrated_versions[-step]
56
+ migrator.migrate(version)
57
+ Rake::Task["groonga:schema:dump"].invoke
58
+ end
59
+
60
+ namespace :migrate do
61
+ desc 'Rolls the schema back and migrate the schema again.'
62
+ task :redo => :environment do
63
+ if ENV["VERSION"]
64
+ Rake::Task["groonga:migrate:down"].invoke
65
+ Rake::Task["groonga:migrate:up"].invoke
66
+ else
67
+ Rake::Task["groonga:rollback"].invoke
68
+ Rake::Task["groonga:migrate"].invoke
69
+ end
70
+ end
71
+
72
+ desc 'Migrate the schema up to the version (options: VERSION=x).'
73
+ task :up => :environment do
74
+ version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
75
+ raise "VERSION is required" unless version
76
+ migrator = ActiveGroonga::Migrator.new(:up, migrations_path.call)
77
+ migrator.migrate(version)
78
+ Rake::Task["groonga:schema:dump"].invoke
79
+ end
80
+
81
+ desc 'Migrate the schema down to the version (options: VERSION=x).'
82
+ task :down => :environment do
83
+ version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
84
+ raise "VERSION is required" unless version
85
+ migrator = ActiveGroonga::Migrator.new(:down, migrations_path.call)
86
+ migrator.migrate(version)
87
+ Rake::Task["groonga:schema:dump"].invoke
88
+ end
89
+ end
90
+
91
+ namespace :schema do
92
+ schema_name = Proc.new do
93
+ Pathname(ENV['SCHEMA'] || (Rails.root + "db" + "groonga" + "schema.rb"))
94
+ end
95
+
96
+ desc "Load the schema."
97
+ task :load => "groonga:load_config" do
98
+ schema = schema_name.call
99
+ if schema.exist?
100
+ load(schema)
101
+ else
102
+ Rake::Task["groonga:migrate"].invoke
103
+ end
104
+ end
105
+
106
+ desc "Dump the schema."
107
+ task :dump => "groonga:load_config" do
108
+ schema = schema_name.call
109
+ mkdir_p(schema.dirname.to_s) unless schema.dirname.exist?
110
+ begin
111
+ schema.open("w") do |schema_file|
112
+ ActiveGroonga::Schema.dump(schema_file)
113
+ end
114
+ rescue Exception
115
+ rm_f(schema.to_s)
116
+ raise
117
+ end
118
+ end
119
+ end
120
+
121
+ desc('Load the seed data from db/groonga/seeds/#{RAILS_ENV}.grn, ' +
122
+ 'db/groonga/seeds/#{RAILS_ENV}.rb, db/groonga/seeds.grn or ' +
123
+ 'db/groonga/seeds.rb')
124
+ task :seed => :load_config do
125
+ base_dir = Rails.root + "db" + "groonga"
126
+ candidates = [base_dir + "seeds" + "#{Rails.env}.grn",
127
+ base_dir + "seeds" + "#{Rails.env}.rb",
128
+ base_dir + "seeds.grn",
129
+ base_dir + "seeds.rb"]
130
+ seed_file_path = candidates.find(&:exist?)
131
+ break unless seed_file_path
132
+ case seed_file_path.extname
133
+ when /\A\.grn\z/i
134
+ ActiveGroonga::Base.database.ensure_available
135
+ context = ActiveGroonga::Base.context
136
+ seed_file_path.open do |seed_file|
137
+ seed_file.each_line do |line|
138
+ puts("> #{line}")
139
+ context.send(line)
140
+ id, result = context.receive
141
+ puts(result) unless result.empty?
142
+ end
143
+ end
144
+ when /\A\.rb\z/i
145
+ load(seed_file_path)
146
+ else
147
+ raise "unsupported seed file type: <#{seed_file_path}>"
148
+ end
149
+ end
150
+
151
+ desc "Create the database and load the schema."
152
+ task :setup => [:create, "groonga:schema:load", :seed]
153
+
154
+ task :reset => [:drop, :setup]
155
+
156
+ namespace :test do
157
+ desc "Prepare groonga database for testing"
158
+ task :prepare do
159
+ ActiveGroonga::Base.configure("test")
160
+ Rake::Task["groonga:drop"].invoke
161
+ Rake::Task["groonga:create"].invoke
162
+ Rake::Task["groonga:schema:load"].invoke
163
+ end
164
+ end
165
+ end
166
+
167
+ task "test:prepare" => "groonga:test:prepare"