rails4-autocomplete 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +31 -0
  3. data/README.md +374 -0
  4. data/Rakefile +21 -0
  5. data/lib/assets/javascripts/autocomplete-rails-uncompressed.js +136 -0
  6. data/lib/assets/javascripts/autocomplete-rails.js +16 -0
  7. data/lib/cucumber/autocomplete.rb +6 -0
  8. data/lib/generators/autocomplete/install_generator.rb +14 -0
  9. data/lib/generators/autocomplete/uncompressed_generator.rb +14 -0
  10. data/lib/rails4-autocomplete.rb +23 -0
  11. data/lib/rails4-autocomplete/autocomplete.rb +96 -0
  12. data/lib/rails4-autocomplete/form_helper.rb +47 -0
  13. data/lib/rails4-autocomplete/formtastic.rb +41 -0
  14. data/lib/rails4-autocomplete/formtastic_plugin.rb +44 -0
  15. data/lib/rails4-autocomplete/orm.rb +8 -0
  16. data/lib/rails4-autocomplete/orm/active_record.rb +52 -0
  17. data/lib/rails4-autocomplete/orm/mongo_mapper.rb +30 -0
  18. data/lib/rails4-autocomplete/orm/mongoid.rb +34 -0
  19. data/lib/rails4-autocomplete/rails/engine.rb +5 -0
  20. data/lib/rails4-autocomplete/simple_form_plugin.rb +84 -0
  21. data/lib/rails4-autocomplete/version.rb +3 -0
  22. data/lib/steak/autocomplete.rb +12 -0
  23. data/test/form_helper_test.rb +25 -0
  24. data/test/generators/autocomplete/install_generator_test.rb +25 -0
  25. data/test/generators/autocomplete/uncompressed_generator_test.rb +25 -0
  26. data/test/lib/rails3-jquery-autocomplete/autocomplete_test.rb +59 -0
  27. data/test/lib/rails3-jquery-autocomplete/orm/active_record_test.rb +145 -0
  28. data/test/lib/rails3-jquery-autocomplete/orm/mongo_mapper_test.rb +60 -0
  29. data/test/lib/rails3-jquery-autocomplete/orm/mongoid_test.rb +60 -0
  30. data/test/lib/rails3-jquery-autocomplete/simple_form_plugin_test.rb +33 -0
  31. data/test/lib/rails3-jquery-autocomplete_test.rb +38 -0
  32. data/test/test_helper.rb +36 -0
  33. data/test/view_test_helper.rb +108 -0
  34. metadata +268 -0
@@ -0,0 +1,84 @@
1
+ module SimpleForm
2
+ module Inputs
3
+ module Autocomplete
4
+ #
5
+ # Method used to rename the autocomplete key to a more standard
6
+ # data-autocomplete key
7
+ #
8
+ def rewrite_autocomplete_option
9
+ new_options = {}
10
+ new_options["data-update-elements"] = JSON.generate(options.delete :update_elements) if options[:update_elements]
11
+ new_options["data-id-element"] = options.delete :id_element if options[:id_element]
12
+ input_html_options.merge new_options
13
+ end
14
+ end
15
+
16
+ class AutocompleteInput < Base
17
+ include Autocomplete
18
+
19
+ def input
20
+ @builder.autocomplete_field(
21
+ attribute_name,
22
+ options[:url],
23
+ rewrite_autocomplete_option
24
+ )
25
+ end
26
+
27
+ protected
28
+ def limit
29
+ column && column.limit
30
+ end
31
+
32
+ def has_placeholder?
33
+ placeholder_present?
34
+ end
35
+ end
36
+
37
+ class AutocompleteCollectionInput < CollectionInput
38
+ include Autocomplete
39
+
40
+ def input
41
+ # http://www.codeofficer.com/blog/entry/form_builders_in_rails_discovering_field_names_and_ids_for_javascript/
42
+ hidden_id = "#{object_name}_#{attribute_name}_hidden".gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")
43
+ id_element = options[:id_element]
44
+ if id_element
45
+ id_element << ", #" << hidden_id
46
+ else
47
+ id_element = "#" + hidden_id
48
+ end
49
+ options[:id_element] = id_element
50
+ autocomplete_options = rewrite_autocomplete_option
51
+ #
52
+ label_method, value_method = detect_collection_methods
53
+ association = object.send(reflection.name)
54
+ if association && association.respond_to?(label_method)
55
+ autocomplete_options[:value] = association.send(label_method)
56
+ end
57
+ out = @builder.autocomplete_field(
58
+ attribute_name,
59
+ options[:url],
60
+ autocomplete_options
61
+ )
62
+ hidden_options = if association && association.respond_to?(value_method)
63
+ new_options = {}
64
+ new_options[:value] = association.send(value_method)
65
+ input_html_options.merge new_options
66
+ else
67
+ input_html_options
68
+ end
69
+ hidden_options[:id] = hidden_id
70
+ out << @builder.hidden_field(
71
+ attribute_name,
72
+ hidden_options
73
+ )
74
+ out.html_safe
75
+ end
76
+ end
77
+ end
78
+
79
+ class FormBuilder
80
+ map_type :autocomplete, :to => SimpleForm::Inputs::AutocompleteInput
81
+ map_type :autocomplete_collection, :to => SimpleForm::Inputs::AutocompleteCollectionInput
82
+ end
83
+
84
+ end
@@ -0,0 +1,3 @@
1
+ module Rails4Autocomplete
2
+ VERSION = '1.0.7'
3
+ end
@@ -0,0 +1,12 @@
1
+ module Steak
2
+ module Autocomplete
3
+ def choose_autocomplete_result(text, input_id="input[data-autocomplete]")
4
+ page.execute_script %Q{ $('#{input_id}').trigger("focus") }
5
+ page.execute_script %Q{ $('#{input_id}').trigger("keydown") }
6
+ sleep 1
7
+ page.execute_script %Q{ $('.ui-menu-item a:contains("#{text}")').trigger("mouseenter").trigger("click"); }
8
+ end
9
+ end
10
+ end
11
+
12
+ RSpec.configuration.include Steak::Autocomplete, :type => :acceptance
@@ -0,0 +1,25 @@
1
+ require "test_helper"
2
+
3
+ class Post
4
+ attr_accessor :author
5
+ end
6
+
7
+ class FormHelperTest < ActionView::TestCase
8
+ def test_text_field_tag
9
+ assert_match(/autocomplete=\"some\/path\"/, text_field_tag('field_name', '', :autocomplete => 'some/path'))
10
+ end
11
+
12
+ def test_text_field
13
+ post = Post.new
14
+ assert_match(/autocomplete=\"some\/path\"/, text_field(:post, :author, :autocomplete => 'some/path'))
15
+ end
16
+
17
+ def test_autocomplete_field_tag
18
+ assert_match(/data-autocomplete=\"some\/path\"/, autocomplete_field_tag('field_name', '', 'some/path'))
19
+ end
20
+
21
+ def test_autocomplete_field
22
+ post= Post.new
23
+ assert_match(/data-autocomplete=\"some\/path\"/, autocomplete_field(:post, :author, 'some/path'))
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ require 'test_helper'
2
+ require 'generators/autocomplete/install_generator'
3
+
4
+ module Autocomplete
5
+ class InstallGeneratorTest < Test::Unit::TestCase
6
+ def setup
7
+ @destination = File.join('tmp', 'test_app')
8
+ @source = InstallGenerator.source_root
9
+ @filename = File.join(@destination, 'public', 'javascripts', 'autocomplete-rails.js')
10
+
11
+ File.unlink(@filename) if File.exists?(@filename)
12
+
13
+ InstallGenerator.start([], :destination_root => @destination)
14
+ end
15
+
16
+ def test_install
17
+ assert File.exists?(@filename)
18
+
19
+ assert_equal(
20
+ File.read(File.join(@source, 'autocomplete-rails.js')),
21
+ File.read(@filename)
22
+ )
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ require 'test_helper'
2
+ require 'generators/autocomplete/uncompressed_generator'
3
+
4
+ module Autocomplete
5
+ class UncompressedGeneratorTest < Test::Unit::TestCase
6
+ def setup
7
+ @destination = File.join('tmp', 'test_app')
8
+ @source = UncompressedGenerator.source_root
9
+ @filename = File.join(@destination, 'public', 'javascripts', 'autocomplete-rails.js')
10
+
11
+ File.unlink(@filename) if File.exists?(@filename)
12
+
13
+ UncompressedGenerator.start([], :destination_root => @destination)
14
+ end
15
+
16
+ def test_install
17
+ assert File.exists?(@filename)
18
+
19
+ assert_equal(
20
+ File.read(File.join(@source, 'autocomplete-rails-uncompressed.js')),
21
+ File.read(@filename)
22
+ )
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,59 @@
1
+ require 'test_helper'
2
+
3
+ module Rails4Autocomplete
4
+ class AutocompleteTest < Test::Unit::TestCase
5
+ include Rails4Autocomplete::Autocomplete
6
+
7
+ context '#get_autocomplete_limit' do
8
+ context 'the limit option was specified' do
9
+ should "return the limit option" do
10
+ assert_equal 99, get_autocomplete_limit({:limit => 99})
11
+ end
12
+ end
13
+
14
+ context 'the limit option is not specified' do
15
+ should 'return 10' do
16
+ assert_equal 10, get_autocomplete_limit({})
17
+ end
18
+ end
19
+ end
20
+
21
+ context '#get_object' do
22
+ should 'return the specified sym as a class name' do
23
+ symbol = Object.new
24
+ class_object = Class.new
25
+ mock(symbol).to_s.mock!.camelize.mock!.constantize { class_object }
26
+ assert_equal class_object, get_object(symbol)
27
+ end
28
+ end
29
+
30
+ context '#json_for_autocomplete' do
31
+ should 'parse items to JSON' do
32
+ item = mock(Object)
33
+ mock(item).send(:name).times(2) { 'Object Name' }
34
+ mock(item).id { 1 }
35
+ items = [item]
36
+ response = self.json_for_autocomplete(items, :name).first
37
+ assert_equal response["id"], "1"
38
+ assert_equal response["value"], "Object Name"
39
+ assert_equal response["label"], "Object Name"
40
+ end
41
+
42
+ context 'with extra data' do
43
+ should 'add that extra data to result' do
44
+ item = mock(Object)
45
+ mock(item).send(:name).times(2) { 'Object Name' }
46
+ mock(item).id { 1 }
47
+ mock(item).send("extra") { 'Object Extra ' }
48
+
49
+ items = [item]
50
+ response = self.json_for_autocomplete(items, :name, ["extra"]).first
51
+
52
+ assert_equal "1" , response["id"]
53
+ assert_equal "Object Name" , response["value"]
54
+ assert_equal "Object Name" , response["label"]
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,145 @@
1
+ require 'test_helper'
2
+
3
+ module Rails4Autocomplete
4
+ module Orm
5
+ class ActiveRecordTest < Test::Unit::TestCase
6
+ include Rails4Autocomplete::Orm::ActiveRecord
7
+
8
+ context "#get_autocomplete_order" do
9
+ context 'order is specified' do
10
+ should 'returns that order option' do
11
+ assert_equal "field ASC", get_autocomplete_order(:field, {:order => 'field ASC'})
12
+ end
13
+ end
14
+
15
+ context 'no order is specified' do
16
+ should 'return the order clause by the field ASC' do
17
+ assert_equal "field ASC", get_autocomplete_order(:field, {})
18
+ end
19
+
20
+ context 'a different model is specified' do
21
+ should 'return the order clause by the table_name.field ASC' do
22
+ model = Object.new
23
+ mock(model).table_name { 'table_name' }
24
+ assert_equal "table_name.field ASC", get_autocomplete_order(:field, {}, model)
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ context '#get_autocomplete_items' do
31
+ should 'retrieve the items from ActiveRecord' do
32
+ class Dog ; end
33
+
34
+ model = Dog
35
+ scoped = []
36
+ whered = []
37
+ term = 'query'
38
+ method = :field
39
+
40
+ options = {
41
+ :model => model,
42
+ :term => term,
43
+ :method => method,
44
+ :options => {}
45
+ }
46
+
47
+ mock(self).get_autocomplete_limit(anything) { 10 }
48
+ mock(self).get_autocomplete_order(anything, anything, anything) { "order ASC" }
49
+ mock(self).get_autocomplete_select_clause(model, method, {}) { ["field"] }
50
+ mock(self).get_autocomplete_where_clause(model, term, method, {}) { ["WHERE something"] }
51
+ mock(model).table_name.times(any_times) { 'model_table_name' }
52
+
53
+ mock(model).scoped { model }
54
+ mock(model).select(["field"]) { model }
55
+ mock(model).where(["WHERE something"]).mock!.limit(10).mock!.
56
+ order("order ASC") { 1 }
57
+
58
+ assert_equal 1, get_autocomplete_items(options)
59
+ end
60
+ end
61
+
62
+ context '#get_autocomplete_select_clause' do
63
+ setup do
64
+ @model = Object.new
65
+ mock(@model).table_name { 'table_name' }
66
+ mock(@model).primary_key { 'id' }
67
+ end
68
+
69
+ should 'create a select clause' do
70
+ assert_equal ["table_name.id", "table_name.method"],
71
+ get_autocomplete_select_clause(@model, :method, {})
72
+ end
73
+
74
+ context 'with extra options' do
75
+ should 'return those extra fields on the clause' do
76
+ options = {:extra_data => ['table_name.created_at']}
77
+
78
+ assert_equal ["table_name.id", "table_name.method", "table_name.created_at"],
79
+ get_autocomplete_select_clause(@model, :method, options)
80
+ end
81
+ end
82
+ end
83
+
84
+ context '#get_autocomplete_where_clause' do
85
+ setup do
86
+ @model = Object.new
87
+ mock(@model).table_name { 'table_name' }
88
+
89
+ @term = 'query'
90
+ @options = {}
91
+ @method = :method
92
+ end
93
+
94
+ context 'Not Postgres' do
95
+ should 'return options for where' do
96
+ mock(self).postgres?(@model) { false }
97
+ assert_equal ["LOWER(table_name.method) LIKE ?", "query%"], get_autocomplete_where_clause(@model, @term, @method, @options)
98
+ end
99
+ end
100
+
101
+ context 'Postgres' do
102
+ should 'return options for where with ILIKE' do
103
+ mock(self).postgres?(@model) { true }
104
+ assert_equal ["LOWER(table_name.method) ILIKE ?", "query%"], get_autocomplete_where_clause(@model, @term, @method, @options)
105
+ end
106
+ end
107
+
108
+ context 'full search' do
109
+ should 'return options for where with the term sourrounded by %%' do
110
+ mock(self).postgres?(@model) { false }
111
+ @options[:full] = true
112
+ assert_equal ["LOWER(table_name.method) LIKE ?", "%query%"], get_autocomplete_where_clause(@model, @term, @method, @options)
113
+ end
114
+ end
115
+ end
116
+
117
+ context '#postgres?' do
118
+ setup do
119
+ @model = stub
120
+ end
121
+
122
+ context 'the connection class is not postgres' do
123
+ setup do
124
+ mock(@model).connection { stub }
125
+ end
126
+
127
+ should 'return nil if the connection class matches PostgreSQLAdapter' do
128
+ assert_nil self.postgres?(@model)
129
+ end
130
+ end
131
+
132
+ context 'the connection class matches PostgreSQLAdapter' do
133
+ setup do
134
+ class PostgreSQLAdapter; end
135
+ mock(@model).connection { PostgreSQLAdapter.new }
136
+ end
137
+
138
+ should 'return true' do
139
+ assert self.postgres?(@model)
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,60 @@
1
+ require 'test_helper'
2
+
3
+ module Rails4Autocomplete
4
+ module Orm
5
+ class MongoMapperTest < Test::Unit::TestCase
6
+ include Rails4Autocomplete::Orm::MongoMapper
7
+
8
+ context "#get_autocomplete_order" do
9
+ context "order is specified" do
10
+ should 'returns the parametrized order for Mongoid' do
11
+ assert_equal [[:field, :asc], [:state, :desc]],
12
+ get_autocomplete_order(:method, :order => 'field ASC, state DESC')
13
+ end
14
+ end
15
+
16
+ context 'order is not specified' do
17
+ should 'return the method ordered ASC by default' do
18
+ assert_equal [[:method, :asc]],
19
+ get_autocomplete_order(:method, {})
20
+ end
21
+ end
22
+ end
23
+
24
+ context "#get_autocomplete_items" do
25
+ setup do
26
+ @model = mock(Object)
27
+
28
+ @parameters = {
29
+ :model => @model,
30
+ :method => :field,
31
+ :term => 'query',
32
+ :options => {:full => false}
33
+ }
34
+ mock(self).get_autocomplete_limit(anything) { 10 }
35
+ mock(self).get_autocomplete_order(anything, anything) { [[:order, :asc]] }
36
+ end
37
+
38
+ context 'not a full search' do
39
+ should 'do stuff' do
40
+ mock(@model).where({:field=>/^query.*/i}).mock!.limit(10).
41
+ mock!.sort([[:order, :asc]])
42
+
43
+ get_autocomplete_items(@parameters)
44
+ end
45
+ end
46
+
47
+ context 'full search' do
48
+ should 'return a full search query' do
49
+ @parameters[:options] = {:full => true}
50
+
51
+ mock(@model).where({:field => /.*query.*/i}).mock!.limit(10).
52
+ mock!.sort([[:order, :asc]])
53
+
54
+ get_autocomplete_items(@parameters)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end