rails4-autocomplete 1.0.7

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 (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