ts-xml 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. data/LICENSE +20 -0
  2. data/README.textile +30 -0
  3. data/features/alternate_primary_key.feature +27 -0
  4. data/features/attribute_transformation.feature +22 -0
  5. data/features/attribute_updates.feature +39 -0
  6. data/features/deleting_instances.feature +67 -0
  7. data/features/direct_attributes.feature +11 -0
  8. data/features/excerpts.feature +13 -0
  9. data/features/extensible_delta_indexing.feature +9 -0
  10. data/features/facets.feature +82 -0
  11. data/features/facets_across_model.feature +29 -0
  12. data/features/handling_edits.feature +92 -0
  13. data/features/retry_stale_indexes.feature +24 -0
  14. data/features/searching_across_models.feature +20 -0
  15. data/features/searching_by_index.feature +40 -0
  16. data/features/searching_by_model.feature +175 -0
  17. data/features/searching_with_find_arguments.feature +56 -0
  18. data/features/sphinx_detection.feature +25 -0
  19. data/features/sphinx_scopes.feature +42 -0
  20. data/features/step_definitions/alpha_steps.rb +7 -0
  21. data/features/step_definitions/beta_steps.rb +7 -0
  22. data/features/step_definitions/common_steps.rb +188 -0
  23. data/features/step_definitions/extensible_delta_indexing_steps.rb +7 -0
  24. data/features/step_definitions/facet_steps.rb +96 -0
  25. data/features/step_definitions/find_arguments_steps.rb +36 -0
  26. data/features/step_definitions/gamma_steps.rb +15 -0
  27. data/features/step_definitions/scope_steps.rb +15 -0
  28. data/features/step_definitions/search_steps.rb +89 -0
  29. data/features/step_definitions/sphinx_steps.rb +35 -0
  30. data/features/sti_searching.feature +19 -0
  31. data/features/support/database.example.yml +3 -0
  32. data/features/support/db/fixtures/alphas.rb +10 -0
  33. data/features/support/db/fixtures/authors.rb +1 -0
  34. data/features/support/db/fixtures/betas.rb +10 -0
  35. data/features/support/db/fixtures/boxes.rb +9 -0
  36. data/features/support/db/fixtures/categories.rb +1 -0
  37. data/features/support/db/fixtures/cats.rb +3 -0
  38. data/features/support/db/fixtures/comments.rb +24 -0
  39. data/features/support/db/fixtures/developers.rb +29 -0
  40. data/features/support/db/fixtures/dogs.rb +3 -0
  41. data/features/support/db/fixtures/extensible_betas.rb +10 -0
  42. data/features/support/db/fixtures/foxes.rb +3 -0
  43. data/features/support/db/fixtures/gammas.rb +10 -0
  44. data/features/support/db/fixtures/people.rb +1001 -0
  45. data/features/support/db/fixtures/posts.rb +6 -0
  46. data/features/support/db/fixtures/robots.rb +14 -0
  47. data/features/support/db/fixtures/tags.rb +27 -0
  48. data/features/support/db/migrations/create_alphas.rb +7 -0
  49. data/features/support/db/migrations/create_animals.rb +5 -0
  50. data/features/support/db/migrations/create_authors.rb +3 -0
  51. data/features/support/db/migrations/create_authors_posts.rb +6 -0
  52. data/features/support/db/migrations/create_betas.rb +5 -0
  53. data/features/support/db/migrations/create_boxes.rb +5 -0
  54. data/features/support/db/migrations/create_categories.rb +3 -0
  55. data/features/support/db/migrations/create_comments.rb +10 -0
  56. data/features/support/db/migrations/create_developers.rb +9 -0
  57. data/features/support/db/migrations/create_extensible_betas.rb +5 -0
  58. data/features/support/db/migrations/create_gammas.rb +3 -0
  59. data/features/support/db/migrations/create_people.rb +13 -0
  60. data/features/support/db/migrations/create_posts.rb +5 -0
  61. data/features/support/db/migrations/create_robots.rb +4 -0
  62. data/features/support/db/migrations/create_taggings.rb +5 -0
  63. data/features/support/db/migrations/create_tags.rb +4 -0
  64. data/features/support/env.rb +21 -0
  65. data/features/support/lib/generic_delta_handler.rb +8 -0
  66. data/features/support/models/alpha.rb +21 -0
  67. data/features/support/models/animal.rb +5 -0
  68. data/features/support/models/author.rb +3 -0
  69. data/features/support/models/beta.rb +8 -0
  70. data/features/support/models/box.rb +8 -0
  71. data/features/support/models/cat.rb +3 -0
  72. data/features/support/models/category.rb +4 -0
  73. data/features/support/models/comment.rb +10 -0
  74. data/features/support/models/developer.rb +16 -0
  75. data/features/support/models/dog.rb +3 -0
  76. data/features/support/models/extensible_beta.rb +9 -0
  77. data/features/support/models/fox.rb +5 -0
  78. data/features/support/models/gamma.rb +5 -0
  79. data/features/support/models/person.rb +23 -0
  80. data/features/support/models/post.rb +21 -0
  81. data/features/support/models/robot.rb +12 -0
  82. data/features/support/models/tag.rb +3 -0
  83. data/features/support/models/tagging.rb +4 -0
  84. data/lib/thinking_sphinx/xml.rb +5 -0
  85. data/lib/thinking_sphinx/xml/adapters/abstract_adapter.rb +34 -0
  86. data/lib/thinking_sphinx/xml/adapters/oracle_adapter.rb +123 -0
  87. data/lib/thinking_sphinx/xml/adapters/sqlite3_adapter.rb +95 -0
  88. data/lib/thinking_sphinx/xml/source.rb +46 -0
  89. data/lib/thinking_sphinx/xml/tasks.rb +95 -0
  90. data/spec/cucumber_env.rb +22 -0
  91. metadata +183 -0
@@ -0,0 +1,7 @@
1
+ When /I change the name of extensible beta (\w+) to (\w+)$/ do |current, replacement|
2
+ ExtensibleBeta.find_by_name(current).update_attributes(:name => replacement)
3
+ end
4
+
5
+ Then /^the generic delta handler should handle the delta indexing$/ do
6
+ ExtensibleBeta.find(:first, :conditions => {:changed_by_generic => true}).should_not be_nil
7
+ end
@@ -0,0 +1,96 @@
1
+ When /^I am requesting facet results$/ do
2
+ @results = nil
3
+ @method = :facets
4
+ end
5
+
6
+ When /^I am requesting just the facet (\w+)$/ do |facet|
7
+ @results = nil
8
+ @options[:facets] = facet.downcase.to_sym
9
+ end
10
+
11
+ When /^I am requesting just the facets (\w+) and (\w+)$/ do |one, two|
12
+ @results = nil
13
+ @options[:facets] = [one.downcase.to_sym, two.downcase.to_sym]
14
+ end
15
+
16
+ When "I want classes included" do
17
+ @options[:class_facet] = true
18
+ end
19
+
20
+ When "I don't want classes included" do
21
+ @options[:class_facet] = false
22
+ end
23
+
24
+ When "I want all possible attributes" do
25
+ @options[:all_facets] = true
26
+ end
27
+
28
+ When /^I drill down where (\w+) is (\w+)$/ do |facet, value|
29
+ @results = results.for(facet.downcase.to_sym => value)
30
+ end
31
+
32
+ When /^I drill down where (\w+) is (\w+) and (\w+) is (\w+)$/ do |facet_one, value_one, facet_two, value_two|
33
+ value_one = value_one.to_i unless value_one[/^\d+$/].nil?
34
+ value_two = value_two.to_i unless value_two[/^\d+$/].nil?
35
+
36
+ @results = results.for(
37
+ facet_one.downcase.to_sym => value_one,
38
+ facet_two.downcase.to_sym => value_two
39
+ )
40
+ end
41
+
42
+ When /^I drill down where ([\w_]+) includes the id of tag (\w+)$/ do |facet, text|
43
+ tag = Tag.find_by_text(text)
44
+ @results = results.for(facet.downcase.to_sym => tag.id)
45
+ end
46
+
47
+ When /^I drill down where ([\w_]+) includes the id of tags (\w+) or (\w+)$/ do |facet, text_one, text_two|
48
+ tag_one = Tag.find_by_text(text_one)
49
+ tag_two = Tag.find_by_text(text_two)
50
+ @results = results.for(facet.downcase.to_sym => [tag_one.id, tag_two.id])
51
+ end
52
+
53
+ Then "I should have valid facet results" do
54
+ results.should be_kind_of(Hash)
55
+ results.values.each { |value| value.should be_kind_of(Hash) }
56
+ end
57
+
58
+ Then /^I should have (\d+) facets?$/ do |count|
59
+ results.keys.length.should == count.to_i
60
+ end
61
+
62
+ Then /^I should have the facet ([\w_\s]+)$/ do |name|
63
+ results[facet_name(name)].should be_kind_of(Hash)
64
+ end
65
+
66
+ Then /^I should not have the facet ([\w_\s]+)$/ do |name|
67
+ results.keys.should_not include(facet_name(name))
68
+ end
69
+
70
+ Then /^the ([\w_\s]+) facet should have an? "([\w\s_]+)" key with (\d+) hits$/ do |name, key, hit_count|
71
+ facet_name = facet_name name
72
+ results[facet_name].keys.should include(key)
73
+ results[facet_name][key].should eql(hit_count.to_i)
74
+ end
75
+
76
+ Then /^the ([\w_\s]+) facet should have an? "(\w+)" key$/ do |name, key|
77
+ results[facet_name(name)].keys.should include(key)
78
+ end
79
+
80
+ Then /^the ([\w_\s]+) facet should have an? (\d+\.?\d*) key$/ do |name, key|
81
+ if key[/\./]
82
+ key = key.to_f
83
+ else
84
+ key = key.to_i
85
+ end
86
+
87
+ results[facet_name(name)].keys.should include(key)
88
+ end
89
+
90
+ Then /^the ([\w\s]+) facet should have (\d+) keys$/ do |name, count|
91
+ results[facet_name(name)].keys.length.should == count.to_i
92
+ end
93
+
94
+ def facet_name(string)
95
+ string.gsub(/\s/, '').underscore.to_sym
96
+ end
@@ -0,0 +1,36 @@
1
+ When "I include comments" do
2
+ @results = nil
3
+ @options[:include] = :comments
4
+ end
5
+
6
+ When /^I get the first comment$/ do
7
+ @comment = Comment.find(:first)
8
+ end
9
+
10
+ When /^I track queries$/ do
11
+ $queries_executed = []
12
+ end
13
+
14
+ When /^I compare comments$/ do
15
+ results.first.comments.first.should == @comment
16
+ end
17
+
18
+ When /^I select only content$/ do
19
+ @results = nil
20
+ @options[:select] = "id, content"
21
+ end
22
+
23
+ Then /^I should have (\d+) quer[yies]+$/ do |count|
24
+ $queries_executed.length.should == count.to_i
25
+ end
26
+
27
+ Then /^I should not get an error accessing the subject$/ do
28
+ lambda { results.first.subject }.should_not raise_error
29
+ end
30
+
31
+ Then /^I should get an error accessing the subject$/ do
32
+ error_class = NoMethodError
33
+ error_class = ActiveRecord::MissingAttributeError if ActiveRecord.constants.include?("MissingAttributeError")
34
+
35
+ lambda { results.first.subject }.should raise_error(error_class)
36
+ end
@@ -0,0 +1,15 @@
1
+ When /^I destroy gamma (\w+) without callbacks$/ do |name|
2
+ @results = nil
3
+ gamma = Gamma.find_by_name(name)
4
+ Gamma.delete(gamma.id) if gamma
5
+ end
6
+
7
+ Then "I should get a single result of nil" do
8
+ results.to_a.should == [nil]
9
+ end
10
+
11
+ Then /^I should get a single gamma result with a name of (\w+)$/ do |name|
12
+ results.length.should == 1
13
+ results.first.should be_a(Gamma)
14
+ results.first.name.should == name
15
+ end
@@ -0,0 +1,15 @@
1
+ When /^I use the ([\w]+) scope$/ do |scope|
2
+ @results = results.send(scope.to_sym)
3
+ end
4
+
5
+ When /^I use the ([\w]+) scope set to "([^\"]*)"$/ do |scope, value|
6
+ @results = results.send(scope.to_sym, value)
7
+ end
8
+
9
+ When /^I use the ([\w]+) scope set to (\d+)$/ do |scope, int|
10
+ @results = results.send(scope.to_sym, int.to_i)
11
+ end
12
+
13
+ When /^I am retrieving the scoped result count$/ do
14
+ @results = results.search_count
15
+ end
@@ -0,0 +1,89 @@
1
+ # encoding: UTF-8
2
+ When /^I search for the specific id of (\d+) in the (\w+) index$/ do |id, index|
3
+ @id = id.to_i
4
+ @index = index
5
+ end
6
+
7
+ When /^I search for the document id of (\w+) (\w+) in the (\w+) index$/ do |model, name, index|
8
+ model = model.gsub(/\s/, '_').camelize.constantize
9
+ @id = model.find_by_name(name).sphinx_document_id
10
+ @index = index
11
+ end
12
+
13
+ Then "it should exist" do
14
+ ThinkingSphinx::Search.search_for_id(@id, @index).should == true
15
+ end
16
+
17
+ Then "it should not exist" do
18
+ ThinkingSphinx::Search.search_for_id(@id, @index).should == false
19
+ end
20
+
21
+ Then "it should exist if using Rails 2.1 or newer" do
22
+ require 'active_record/version'
23
+ unless ActiveRecord::VERSION::STRING.to_f < 2.1
24
+ ThinkingSphinx::Search.search_for_id(@id, @index).should == true
25
+ end
26
+ end
27
+
28
+ Then "it should not exist if using Rails 2.1 or newer" do
29
+ require 'active_record/version'
30
+ unless ActiveRecord::VERSION::STRING.to_f < 2.1
31
+ ThinkingSphinx::Search.search_for_id(@id, @index).should == false
32
+ end
33
+ end
34
+
35
+ Then /^I can iterate by result and group and count$/ do
36
+ results.each_with_groupby_and_count do |result, group, count|
37
+ result.should be_kind_of(@model)
38
+ count.should be_kind_of(Integer)
39
+ group.should be_kind_of(Integer)
40
+ end
41
+ end
42
+
43
+ Then "each result id should match the corresponding sphinx internal id" do
44
+ results.each_with_sphinx_internal_id do |result, id|
45
+ result.id.should == id
46
+ end
47
+ end
48
+
49
+ Then "I should have an array of integers" do
50
+ results.each do |result|
51
+ result.should be_kind_of(Integer)
52
+ end
53
+ end
54
+
55
+ Then "searching for ids should match the record ids of the normal search results" do
56
+ normal_results = results
57
+
58
+ # reset search, switch method
59
+ @results = nil
60
+ @method = :search_for_ids
61
+
62
+ results.to_a.should == normal_results.collect(&:id)
63
+ end
64
+
65
+ Then /^I should get a value of (\d+)$/ do |count|
66
+ results.should == count.to_i
67
+ end
68
+
69
+ Then /^the (\w+) excerpt of the first result is "(.*)"$/ do |column, string|
70
+ excerpt = results.excerpt_for(results.first.send(column))
71
+ if excerpt.respond_to?(:force_encoding)
72
+ excerpt = excerpt.force_encoding('UTF-8')
73
+ end
74
+
75
+ excerpt.should == string
76
+ end
77
+
78
+ Then /^calling (\w+) on the first result excerpts object should return "(.*)"$/ do |column, string|
79
+ excerpt = results.first.excerpts.send(column)
80
+ if excerpt.respond_to?(:force_encoding)
81
+ excerpt = excerpt.force_encoding('UTF-8')
82
+ end
83
+
84
+ excerpt.should == string
85
+ end
86
+
87
+ Then /^the first result should have a (\w+\s?\w*) of (\d+)$/ do |attribute, value|
88
+ results.first.sphinx_attributes[attribute.gsub(/\s+/, '_')].should == value.to_i
89
+ end
@@ -0,0 +1,35 @@
1
+ Given "Sphinx is running" do
2
+ ThinkingSphinx::Configuration.instance.controller.should be_running
3
+ end
4
+
5
+ When "I kill the Sphinx process" do
6
+ Process.kill(9, ThinkingSphinx.sphinx_pid.to_i)
7
+ end
8
+
9
+ When "I wait for Sphinx to catch up" do
10
+ sleep(0.25)
11
+ end
12
+
13
+ When /^I start Sphinx/ do
14
+ ThinkingSphinx::Configuration.instance.controller.start
15
+ end
16
+
17
+ When "I stop Sphinx" do
18
+ ThinkingSphinx::Configuration.instance.controller.stop
19
+ end
20
+
21
+ When /^I (enable|disable) delta updates$/ do |mode|
22
+ ThinkingSphinx.deltas_enabled = (mode == 'enable')
23
+ end
24
+
25
+ When /^I process the (\w+) index$/ do |index|
26
+ ThinkingSphinx::Configuration.instance.controller.index index
27
+ end
28
+
29
+ Then /^Sphinx should be running/ do
30
+ ThinkingSphinx.sphinx_running?.should be_true
31
+ end
32
+
33
+ Then "Sphinx should not be running" do
34
+ ThinkingSphinx.sphinx_running?.should be_false
35
+ end
@@ -0,0 +1,19 @@
1
+ Feature: Searching via STI model relationships
2
+ In order to be used easy in applications with STI relationships
3
+ Thinking Sphinx
4
+ Should return expected results depending on where in the hierarchy searches are called from.
5
+
6
+ Scenario: Searching from a parent model
7
+ Given Sphinx is running
8
+ And I am searching on animals
9
+ Then I should get as many results as there are animals
10
+
11
+ Scenario: Searching from a child model
12
+ Given Sphinx is running
13
+ And I am searching on cats
14
+ Then I should get as many results as there are cats
15
+
16
+ Scenario: Searching across super and subclass indexes
17
+ Given Sphinx is running
18
+ When I search for "fantastic"
19
+ Then I should get 1 result
@@ -0,0 +1,3 @@
1
+ username: root
2
+ host: localhost
3
+ password:
@@ -0,0 +1,10 @@
1
+ Alpha.create :name => "one", :value => 1, :cost => 1.51, :created_on => 1.day.ago.to_date, :created_at => 1.day.ago
2
+ Alpha.create :name => "two", :value => 2, :cost => 2.52, :created_on => 2.day.ago.to_date, :created_at => 2.day.ago
3
+ Alpha.create :name => "three", :value => 3, :cost => 3.53, :created_on => 3.day.ago.to_date, :created_at => 3.day.ago
4
+ Alpha.create :name => "four", :value => 4, :cost => 4.54, :created_on => 4.day.ago.to_date, :created_at => 4.day.ago
5
+ Alpha.create :name => "five", :value => 5, :cost => 5.55, :created_on => 5.day.ago.to_date, :created_at => 5.day.ago
6
+ Alpha.create :name => "six", :value => 6, :cost => 6.56, :created_on => 6.day.ago.to_date, :created_at => 6.day.ago
7
+ Alpha.create :name => "seven", :value => 7, :cost => 7.57, :created_on => 7.day.ago.to_date, :created_at => 7.day.ago
8
+ Alpha.create :name => "eight", :value => 8, :cost => 8.58, :created_on => 8.day.ago.to_date, :created_at => 8.day.ago
9
+ Alpha.create :name => "nine", :value => 9, :cost => 9.59, :created_on => 9.day.ago.to_date, :created_at => 9.day.ago
10
+ Alpha.create :name => "ten", :value => 10, :cost => 10.50, :created_on => 10.day.ago.to_date, :created_at => 10.day.ago
@@ -0,0 +1 @@
1
+ Author.create :name => "William Shakespeare"
@@ -0,0 +1,10 @@
1
+ Beta.create :name => "one", :value => 1
2
+ Beta.create :name => "two", :value => 2
3
+ Beta.create :name => "three", :value => 3
4
+ Beta.create :name => "four", :value => 4
5
+ Beta.create :name => "five", :value => 5
6
+ Beta.create :name => "six", :value => 6
7
+ Beta.create :name => "seven", :value => 7
8
+ Beta.create :name => "eight", :value => 8
9
+ Beta.create :name => "nine", :value => 9
10
+ Beta.create :name => "ten", :value => 10
@@ -0,0 +1,9 @@
1
+ (1..10).each do |i|
2
+ Box.create :width => i, :length => i, :depth => i
3
+ end
4
+
5
+ (11..20).each do |i|
6
+ Box.create :width => i, :length => i+1, :depth => i+2
7
+ end
8
+
9
+ Box.create :width => 5, :length => 5, :depth => nil
@@ -0,0 +1 @@
1
+ Category.create :name => "hello"
@@ -0,0 +1,3 @@
1
+ %w( rogue nat molly jasper moggy ).each do |name|
2
+ Cat.create :name => name
3
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: UTF-8
2
+ Comment.create(
3
+ :name => "Pat",
4
+ :content => "+1",
5
+ :post_id => 1,
6
+ :category_id => 1
7
+ ).update_attribute(:created_at, Time.utc(2001, 01, 01))
8
+
9
+ Comment.create(
10
+ :name => "Menno",
11
+ :content => "Second post!",
12
+ :post_id => 1,
13
+ :category_id => 1
14
+ )
15
+
16
+ Comment.create :name => 'A', :post_id => 1, :content => 'Es un hecho establecido hace demasiado tiempo que un lector se distraerá con el contenido del texto', :category_id => 1
17
+ Comment.create :name => 'B', :post_id => 1, :content => 'de un sitio mientras que mira su diseño. El punto de usar Lorem Ipsum es que tiene una distribución', :category_id => 1
18
+ Comment.create :name => 'C', :post_id => 1, :content => 'más o menos normal de las letras, al contrario de usar textos como por ejemplo "Contenido aquí', :category_id => 1
19
+ Comment.create :name => 'D', :post_id => 1, :content => 'contenido aquí". Estos textos hacen parecerlo un español que se puede leer. Muchos paquetes de', :category_id => 1
20
+ Comment.create :name => 'E', :post_id => 1, :content => 'autoedición y editores de páginas web usan el Lorem Ipsum como su texto por defecto, y al hacer una', :category_id => 1
21
+ Comment.create :name => 'F', :post_id => 1, :content => 'búsqueda de "Lorem Ipsum" va a dar por resultado muchos sitios web que usan este texto si se', :category_id => 1
22
+
23
+ # The one we'll really want to find via Sphinx search
24
+ Comment.create :name => 'G', :post_id => 1, :content => 'Turtle', :category_id => 1
@@ -0,0 +1,29 @@
1
+ Developer.create :name => "Pat Allan", :city => "Melbourne", :state => "Victoria", :country => "Australia", :age => 26
2
+
3
+ 2.times do
4
+ Developer.create :name => Faker::Name.name, :city => "Melbourne", :state => "Victoria", :country => "Australia", :age => 30
5
+ end
6
+
7
+ 2.times do
8
+ Developer.create :name => Faker::Name.name, :city => "Sydney", :state => "New South Wales", :country => "Australia", :age => 28
9
+ end
10
+
11
+ 2.times do
12
+ Developer.create :name => Faker::Name.name, :city => "Adelaide", :state => "South Australia", :country => "Australia", :age => 32
13
+ end
14
+
15
+ 2.times do
16
+ Developer.create :name => Faker::Name.name, :city => "Bendigo", :state => "Victoria", :country => "Australia", :age => 30
17
+ end
18
+
19
+ 2.times do
20
+ Developer.create :name => Faker::Name.name, :city => "Goulburn", :state => "New South Wales", :country => "Australia", :age => 28
21
+ end
22
+
23
+ 2.times do
24
+ Developer.create :name => Faker::Name.name, :city => "Auckland", :state => "North Island", :country => "New Zealand", :age => 32
25
+ end
26
+
27
+ 2.times do
28
+ Developer.create :name => Faker::Name.name, :city => "Christchurch", :state => "South Island", :country => "New Zealand", :age => 30
29
+ end
@@ -0,0 +1,3 @@
1
+ %w( rover lassie gaspode ).each do |name|
2
+ Dog.create :name => name
3
+ end
@@ -0,0 +1,10 @@
1
+ ExtensibleBeta.create :name => "one"
2
+ ExtensibleBeta.create :name => "two"
3
+ ExtensibleBeta.create :name => "three"
4
+ ExtensibleBeta.create :name => "four"
5
+ ExtensibleBeta.create :name => "five"
6
+ ExtensibleBeta.create :name => "six"
7
+ ExtensibleBeta.create :name => "seven"
8
+ ExtensibleBeta.create :name => "eight"
9
+ ExtensibleBeta.create :name => "nine"
10
+ ExtensibleBeta.create :name => "ten"