gmail_search_syntax 0.1.0

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.
@@ -0,0 +1,185 @@
1
+ require "test_helper"
2
+
3
+ class TokenizerTest < Minitest::Test
4
+ def tokenize(input)
5
+ GmailSearchSyntax::Tokenizer.new(input).tokenize
6
+ end
7
+
8
+ def test_tokenize_simple_from
9
+ tokens = tokenize("from:amy@example.com")
10
+ assert_equal 4, tokens.length
11
+ assert_equal :word, tokens[0].type
12
+ assert_equal "from", tokens[0].value
13
+ assert_equal :colon, tokens[1].type
14
+ assert_equal :email, tokens[2].type
15
+ assert_equal "amy@example.com", tokens[2].value
16
+ assert_equal :eof, tokens[3].type
17
+ end
18
+
19
+ def test_tokenize_quoted_string
20
+ tokens = tokenize('"hello world"')
21
+ assert_equal 2, tokens.length
22
+ assert_equal :quoted_string, tokens[0].type
23
+ assert_equal "hello world", tokens[0].value
24
+ end
25
+
26
+ def test_tokenize_operators
27
+ tokens = tokenize("from:amy@example.com OR to:bob@example.com")
28
+
29
+ assert_equal 8, tokens.length
30
+ assert_equal :word, tokens[0].type
31
+ assert_equal "from", tokens[0].value
32
+ assert_equal :colon, tokens[1].type
33
+ assert_equal :email, tokens[2].type
34
+ assert_equal "amy@example.com", tokens[2].value
35
+ assert_equal :or, tokens[3].type
36
+ assert_equal :word, tokens[4].type
37
+ assert_equal "to", tokens[4].value
38
+ assert_equal :colon, tokens[5].type
39
+ assert_equal :email, tokens[6].type
40
+ assert_equal "bob@example.com", tokens[6].value
41
+ assert_equal :eof, tokens[7].type
42
+ end
43
+
44
+ def test_tokenize_parentheses
45
+ tokens = tokenize("subject:(meeting call)")
46
+
47
+ assert_equal 7, tokens.length
48
+ assert_equal :word, tokens[0].type
49
+ assert_equal "subject", tokens[0].value
50
+ assert_equal :colon, tokens[1].type
51
+ assert_equal :lparen, tokens[2].type
52
+ assert_equal :word, tokens[3].type
53
+ assert_equal "meeting", tokens[3].value
54
+ assert_equal :word, tokens[4].type
55
+ assert_equal "call", tokens[4].value
56
+ assert_equal :rparen, tokens[5].type
57
+ assert_equal :eof, tokens[6].type
58
+ end
59
+
60
+ def test_tokenize_braces
61
+ tokens = tokenize("{from:a from:b}")
62
+
63
+ assert_equal 9, tokens.length
64
+ assert_equal :lbrace, tokens[0].type
65
+ assert_equal :word, tokens[1].type
66
+ assert_equal "from", tokens[1].value
67
+ assert_equal :colon, tokens[2].type
68
+ assert_equal :word, tokens[3].type
69
+ assert_equal "a", tokens[3].value
70
+ assert_equal :word, tokens[4].type
71
+ assert_equal "from", tokens[4].value
72
+ assert_equal :colon, tokens[5].type
73
+ assert_equal :word, tokens[6].type
74
+ assert_equal "b", tokens[6].value
75
+ assert_equal :rbrace, tokens[7].type
76
+ assert_equal :eof, tokens[8].type
77
+ end
78
+
79
+ def test_tokenize_negation
80
+ tokens = tokenize("dinner -movie")
81
+ assert_equal 4, tokens.length
82
+ assert_equal :word, tokens[0].type
83
+ assert_equal "dinner", tokens[0].value
84
+ assert_equal :minus, tokens[1].type
85
+ assert_equal :word, tokens[2].type
86
+ assert_equal "movie", tokens[2].value
87
+ end
88
+
89
+ def test_tokenize_around
90
+ tokens = tokenize("holiday AROUND 10 vacation")
91
+
92
+ assert_equal 5, tokens.length
93
+ assert_equal :word, tokens[0].type
94
+ assert_equal "holiday", tokens[0].value
95
+ assert_equal :around, tokens[1].type
96
+ assert_equal :number, tokens[2].type
97
+ assert_equal 10, tokens[2].value
98
+ assert_equal :word, tokens[3].type
99
+ assert_equal "vacation", tokens[3].value
100
+ assert_equal :eof, tokens[4].type
101
+ end
102
+
103
+ def test_tokenize_date
104
+ tokens = tokenize("after:2004/04/16")
105
+ assert_equal 4, tokens.length
106
+ assert_equal :word, tokens[0].type
107
+ assert_equal "after", tokens[0].value
108
+ assert_equal :colon, tokens[1].type
109
+ assert_equal :date, tokens[2].type
110
+ assert_equal "2004/04/16", tokens[2].value
111
+ end
112
+
113
+ def test_tokenize_relative_time
114
+ tokens = tokenize("older_than:1y")
115
+ assert_equal 4, tokens.length
116
+ assert_equal :word, tokens[0].type
117
+ assert_equal "older_than", tokens[0].value
118
+ assert_equal :colon, tokens[1].type
119
+ assert_equal :relative_time, tokens[2].type
120
+ assert_equal "1y", tokens[2].value
121
+ end
122
+
123
+ def test_tokenize_number
124
+ tokens = tokenize("size:1000000")
125
+ assert_equal 4, tokens.length
126
+ assert_equal :word, tokens[0].type
127
+ assert_equal "size", tokens[0].value
128
+ assert_equal :colon, tokens[1].type
129
+ assert_equal :number, tokens[2].type
130
+ assert_equal 1000000, tokens[2].value
131
+ end
132
+
133
+ def test_tokenize_and_operator
134
+ tokens = tokenize("from:amy@example.com AND to:bob@example.com")
135
+
136
+ and_token = tokens.find { |t| t.type == :and }
137
+ refute_nil and_token
138
+ assert_equal "AND", and_token.value
139
+ end
140
+
141
+ def test_tokenize_plus
142
+ tokens = tokenize("+unicorn")
143
+ assert_equal 3, tokens.length
144
+ assert_equal :plus, tokens[0].type
145
+ assert_equal :word, tokens[1].type
146
+ assert_equal "unicorn", tokens[1].value
147
+ end
148
+
149
+ def test_tokenize_complex_query
150
+ tokens = tokenize('from:boss@example.com subject:"urgent meeting" has:attachment')
151
+
152
+ assert_equal 10, tokens.length
153
+ assert_equal :word, tokens[0].type
154
+ assert_equal "from", tokens[0].value
155
+ assert_equal :colon, tokens[1].type
156
+ assert_equal :email, tokens[2].type
157
+ assert_equal "boss@example.com", tokens[2].value
158
+ assert_equal :word, tokens[3].type
159
+ assert_equal "subject", tokens[3].value
160
+ assert_equal :colon, tokens[4].type
161
+ assert_equal :quoted_string, tokens[5].type
162
+ assert_equal "urgent meeting", tokens[5].value
163
+ assert_equal :word, tokens[6].type
164
+ assert_equal "has", tokens[6].value
165
+ assert_equal :colon, tokens[7].type
166
+ assert_equal :word, tokens[8].type
167
+ assert_equal "attachment", tokens[8].value
168
+ assert_equal :eof, tokens[9].type
169
+ end
170
+
171
+ def test_tokenize_email_with_plus
172
+ tokens = tokenize("to:user+tag@example.com")
173
+ email_token = tokens.find { |t| t.type == :email }
174
+ assert_equal "user+tag@example.com", email_token.value
175
+ end
176
+
177
+ def test_tokenize_multiple_words
178
+ tokens = tokenize("project report meeting")
179
+ word_tokens = tokens.select { |t| t.type == :word }
180
+ assert_equal 3, word_tokens.length
181
+ assert_equal "project", word_tokens[0].value
182
+ assert_equal "report", word_tokens[1].value
183
+ assert_equal "meeting", word_tokens[2].value
184
+ end
185
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gmail_search_syntax
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - me@julik.nl
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: minitest
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '5.0'
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '5.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rake
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '13.0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '13.0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: sqlite3
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.6'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "<"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.6'
54
+ - !ruby/object:Gem::Dependency
55
+ name: standard
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '1.0'
68
+ executables: []
69
+ extensions: []
70
+ extra_rdoc_files: []
71
+ files:
72
+ - ARCHITECTURE.md
73
+ - README.md
74
+ - Rakefile
75
+ - SCHEMA.md
76
+ - examples/alias_collision_fix.rb
77
+ - examples/demo.rb
78
+ - examples/gmail_message_id_demo.rb
79
+ - examples/postgres_vs_sqlite.rb
80
+ - examples/sql_query.rb
81
+ - lib/GMAIL_SEARCH_OPERATORS.md
82
+ - lib/gmail_search_syntax.rb
83
+ - lib/gmail_search_syntax/ast.rb
84
+ - lib/gmail_search_syntax/parser.rb
85
+ - lib/gmail_search_syntax/sql_visitor.rb
86
+ - lib/gmail_search_syntax/tokenizer.rb
87
+ - lib/gmail_search_syntax/version.rb
88
+ - test/gmail_search_syntax_test.rb
89
+ - test/integration_test.rb
90
+ - test/postgres_visitor_test.rb
91
+ - test/sql_visitor_test.rb
92
+ - test/test_helper.rb
93
+ - test/tokenizer_test.rb
94
+ homepage: https://github.com/julik/gmail_search_syntax
95
+ licenses:
96
+ - MIT
97
+ metadata: {}
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '3.0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubygems_version: 3.6.7
113
+ specification_version: 4
114
+ summary: Gmail search syntax parser
115
+ test_files: []