2
2
3
3
require 'spec_helper'
4
4
require 'fileutils'
5
+ require 'generators/ruby_llm/install_generator'
5
6
6
- RSpec . describe "Generator template files" , type : :generator do
7
+ RSpec . describe RubyLLM :: InstallGenerator , type : :generator do
7
8
# Use the actual template directory
8
- let ( :template_dir ) { " /Users/kieranklaassen/rails/ruby_llm/lib/generators/ruby_llm/install/templates" }
9
-
10
- describe " migration templates" do
11
- it " has expected migration template files" do
9
+ let ( :template_dir ) { ' /Users/kieranklaassen/rails/ruby_llm/lib/generators/ruby_llm/install/templates' }
10
+
11
+ describe ' migration templates' do
12
+ it ' has expected migration template files' do
12
13
expected_files = [
13
- " create_chats_migration.rb.tt" ,
14
- " create_messages_migration.rb.tt" ,
15
- " create_tool_calls_migration.rb.tt"
14
+ ' create_chats_migration.rb.tt' ,
15
+ ' create_messages_migration.rb.tt' ,
16
+ ' create_tool_calls_migration.rb.tt'
16
17
]
17
-
18
+
18
19
expected_files . each do |file |
19
20
expect ( File . exist? ( File . join ( template_dir , file ) ) ) . to be ( true ) , "Expected template file #{ file } to exist"
20
21
end
21
22
end
22
-
23
- it "has proper migration content" do
24
- chat_migration = File . read ( File . join ( template_dir , "create_chats_migration.rb.tt" ) )
25
- expect ( chat_migration ) . to include ( "create_table :chats" )
26
- expect ( chat_migration ) . to include ( "t.string :model_id" )
27
-
28
- message_migration = File . read ( File . join ( template_dir , "create_messages_migration.rb.tt" ) )
29
- expect ( message_migration ) . to include ( "create_table :messages" )
30
- expect ( message_migration ) . to include ( "t.references :chat" )
31
- expect ( message_migration ) . to include ( "t.string :role" )
32
- expect ( message_migration ) . to include ( "t.text :content" )
33
- expect ( message_migration ) . to include ( "t.references :tool_call" )
34
-
35
- tool_call_migration = File . read ( File . join ( template_dir , "create_tool_calls_migration.rb.tt" ) )
36
- expect ( tool_call_migration ) . to include ( "create_table :tool_calls" )
37
- expect ( tool_call_migration ) . to include ( "t.string :tool_call_id" )
38
- expect ( tool_call_migration ) . to include ( "t.string :name" )
39
-
40
- # Should check for database-agnostic JSON handling
41
- expect ( tool_call_migration ) . to include ( "if postgresql?" )
42
- expect ( tool_call_migration ) . to include ( "t.jsonb :arguments" )
43
- expect ( tool_call_migration ) . to include ( "else" )
44
- expect ( tool_call_migration ) . to include ( "t.json :arguments" )
45
- expect ( tool_call_migration ) . to include ( "end" )
23
+
24
+ it 'has proper chats migration content' do
25
+ chat_migration = File . read ( File . join ( template_dir , 'create_chats_migration.rb.tt' ) )
26
+ expect ( chat_migration ) . to include ( 'create_table :chats' )
27
+ expect ( chat_migration ) . to include ( 't.string :model_id' )
28
+ end
29
+
30
+ it 'has proper messages migration content' do
31
+ message_migration = File . read ( File . join ( template_dir , 'create_messages_migration.rb.tt' ) )
32
+ expect ( message_migration ) . to include ( 'create_table :messages' )
33
+ expect ( message_migration ) . to include ( 't.references :chat' )
34
+ expect ( message_migration ) . to include ( 't.string :role' )
35
+ expect ( message_migration ) . to include ( 't.text :content' )
36
+ end
37
+
38
+ it 'has proper tool_calls migration content' do
39
+ tool_call_migration = File . read ( File . join ( template_dir , 'create_tool_calls_migration.rb.tt' ) )
40
+ expect ( tool_call_migration ) . to include ( 'create_table :tool_calls' )
41
+ expect ( tool_call_migration ) . to include ( 't.string :tool_call_id' )
42
+ expect ( tool_call_migration ) . to include ( 't.string :name' )
43
+ end
44
+
45
+ it 'supports database-agnostic JSON handling in migrations' do
46
+ tool_call_migration = File . read ( File . join ( template_dir , 'create_tool_calls_migration.rb.tt' ) )
47
+ expect ( tool_call_migration ) . to include ( 'if postgresql?' )
48
+ expect ( tool_call_migration ) . to include ( 't.jsonb :arguments' )
49
+ expect ( tool_call_migration ) . to include ( 'else' )
50
+ expect ( tool_call_migration ) . to include ( 't.json :arguments' )
46
51
end
47
52
end
48
-
49
- describe " model templates" do
50
- it " has expected model template files" do
53
+
54
+ describe ' model templates' do
55
+ it ' has expected model template files' do
51
56
expected_files = [
52
- " chat_model.rb.tt" ,
53
- " message_model.rb.tt" ,
54
- " tool_call_model.rb.tt"
57
+ ' chat_model.rb.tt' ,
58
+ ' message_model.rb.tt' ,
59
+ ' tool_call_model.rb.tt'
55
60
]
56
-
61
+
57
62
expected_files . each do |file |
58
63
expect ( File . exist? ( File . join ( template_dir , file ) ) ) . to be ( true ) , "Expected template file #{ file } to exist"
59
64
end
60
65
end
61
-
62
- it "has proper acts_as declarations in model templates" do
63
- chat_content = File . read ( File . join ( template_dir , "chat_model.rb.tt" ) )
64
- expect ( chat_content ) . to include ( "acts_as_chat" )
65
-
66
- message_content = File . read ( File . join ( template_dir , "message_model.rb.tt" ) )
67
- expect ( message_content ) . to include ( "acts_as_message" )
68
-
69
- tool_call_content = File . read ( File . join ( template_dir , "tool_call_model.rb.tt" ) )
70
- expect ( tool_call_content ) . to include ( "acts_as_tool_call" )
66
+
67
+ it 'has proper acts_as_chat declaration in chat model' do
68
+ chat_content = File . read ( File . join ( template_dir , 'chat_model.rb.tt' ) )
69
+ expect ( chat_content ) . to include ( 'acts_as_chat' )
70
+ end
71
+
72
+ it 'has proper acts_as_message declaration in message model' do
73
+ message_content = File . read ( File . join ( template_dir , 'message_model.rb.tt' ) )
74
+ expect ( message_content ) . to include ( 'acts_as_message' )
75
+ end
76
+
77
+ it 'has proper acts_as_tool_call declaration in tool call model' do
78
+ tool_call_content = File . read ( File . join ( template_dir , 'tool_call_model.rb.tt' ) )
79
+ expect ( tool_call_content ) . to include ( 'acts_as_tool_call' )
71
80
end
72
81
end
73
-
74
- describe "initializer template" do
75
- it "has expected initializer template file" do
76
- expect ( File . exist? ( File . join ( template_dir , "initializer.rb.tt" ) ) ) . to be ( true )
77
- end
78
-
79
- it "has proper configuration content" do
80
- initializer_content = File . read ( File . join ( template_dir , "initializer.rb.tt" ) )
81
- expect ( initializer_content ) . to include ( "RubyLLM.configure do |config|" )
82
- expect ( initializer_content ) . to include ( "config.openai_api_key" )
83
- expect ( initializer_content ) . to include ( "ENV[\" OPENAI_API_KEY\" ]" )
84
- expect ( initializer_content ) . to include ( "config.anthropic_api_key" )
82
+
83
+ describe 'initializer template' do
84
+ it 'has expected initializer template file' do
85
+ expect ( File . exist? ( File . join ( template_dir , 'initializer.rb.tt' ) ) ) . to be ( true )
86
+ end
87
+
88
+ it 'includes RubyLLM configuration block' do
89
+ initializer_content = File . read ( File . join ( template_dir , 'initializer.rb.tt' ) )
90
+ expect ( initializer_content ) . to include ( 'RubyLLM.configure do |config|' )
91
+ end
92
+
93
+ it 'includes API key configuration options' do
94
+ initializer_content = File . read ( File . join ( template_dir , 'initializer.rb.tt' ) )
95
+ expect ( initializer_content ) . to include ( 'config.openai_api_key' )
96
+ expect ( initializer_content ) . to include ( 'config.anthropic_api_key' )
85
97
end
86
98
end
87
-
88
- describe "README template" do
89
- it "has a README template file" do
90
- expect ( File . exist? ( File . join ( template_dir , "README.md" ) ) ) . to be ( true )
91
- end
92
-
93
- it "has helpful post-installation instructions" do
94
- readme_content = File . read ( File . join ( template_dir , "README.md" ) )
95
- expect ( readme_content ) . to include ( "RubyLLM Rails Setup Complete" )
96
- expect ( readme_content ) . to include ( "Run migrations" )
97
- expect ( readme_content ) . to include ( "rails db:migrate" )
98
- expect ( readme_content ) . to include ( "Set your API keys" )
99
- expect ( readme_content ) . to include ( "Start using RubyLLM in your code" )
100
- expect ( readme_content ) . to include ( "For streaming responses" )
99
+
100
+ describe 'README template' do
101
+ it 'has a README template file' do
102
+ expect ( File . exist? ( File . join ( template_dir , 'README.md' ) ) ) . to be ( true )
103
+ end
104
+
105
+ it 'has a welcome message and setup information' do
106
+ readme_content = File . read ( File . join ( template_dir , 'README.md' ) )
107
+ expect ( readme_content ) . to include ( 'RubyLLM Rails Setup Complete' )
108
+ expect ( readme_content ) . to include ( 'Run migrations' )
109
+ end
110
+
111
+ it 'includes database migration instructions' do
112
+ readme_content = File . read ( File . join ( template_dir , 'README.md' ) )
113
+ expect ( readme_content ) . to include ( 'rails db:migrate' )
114
+ end
115
+
116
+ it 'includes API configuration instructions' do
117
+ readme_content = File . read ( File . join ( template_dir , 'README.md' ) )
118
+ expect ( readme_content ) . to include ( 'Set your API keys' )
119
+ end
120
+
121
+ it 'includes basic usage examples' do
122
+ readme_content = File . read ( File . join ( template_dir , 'README.md' ) )
123
+ expect ( readme_content ) . to include ( 'Start using RubyLLM in your code' )
124
+ expect ( readme_content ) . to include ( 'For streaming responses' )
101
125
end
102
126
end
103
-
104
- describe " generator file structure" do
105
- it " has proper directory structure" do
106
- generator_file = " /Users/kieranklaassen/rails/ruby_llm/lib/generators/ruby_llm/install_generator.rb"
127
+
128
+ describe ' generator file structure' do
129
+ it ' has a valid generator file' do
130
+ generator_file = ' /Users/kieranklaassen/rails/ruby_llm/lib/generators/ruby_llm/install_generator.rb'
107
131
expect ( File . exist? ( generator_file ) ) . to be ( true )
108
-
132
+ end
133
+
134
+ it 'inherits from Rails::Generators::Base' do
135
+ generator_file = '/Users/kieranklaassen/rails/ruby_llm/lib/generators/ruby_llm/install_generator.rb'
136
+ generator_content = File . read ( generator_file )
137
+ expect ( generator_content ) . to include ( 'class InstallGenerator < Rails::Generators::Base' )
138
+ end
139
+
140
+ it 'includes Rails::Generators::Migration' do
141
+ generator_file = '/Users/kieranklaassen/rails/ruby_llm/lib/generators/ruby_llm/install_generator.rb'
109
142
generator_content = File . read ( generator_file )
110
- expect ( generator_content ) . to include ( "class InstallGenerator < Rails::Generators::Base" )
111
- expect ( generator_content ) . to include ( "include Rails::Generators::Migration" )
112
- expect ( generator_content ) . to include ( "def create_migration_files" )
113
- expect ( generator_content ) . to include ( "def create_model_files" )
114
- expect ( generator_content ) . to include ( "def create_initializer" )
115
- expect ( generator_content ) . to include ( "def show_readme" )
116
- end
117
-
118
- it "creates migrations in the correct order" do
119
- generator_file = "/Users/kieranklaassen/rails/ruby_llm/lib/generators/ruby_llm/install_generator.rb"
143
+ expect ( generator_content ) . to include ( 'include Rails::Generators::Migration' )
144
+ end
145
+
146
+ it 'defines all required methods' do
147
+ generator_file = '/Users/kieranklaassen/rails/ruby_llm/lib/generators/ruby_llm/install_generator.rb'
148
+ generator_content = File . read ( generator_file )
149
+ expect ( generator_content ) . to include ( 'def create_migration_files' )
150
+ expect ( generator_content ) . to include ( 'def create_model_files' )
151
+ expect ( generator_content ) . to include ( 'def create_initializer' )
152
+ expect ( generator_content ) . to include ( 'def show_readme' )
153
+ end
154
+
155
+ it 'has migrations in the correct order' do
156
+ generator_file = '/Users/kieranklaassen/rails/ruby_llm/lib/generators/ruby_llm/install_generator.rb'
120
157
generator_content = File . read ( generator_file )
121
-
122
- # Check for correct order in migration creation
123
- # 1. First chats table (no dependencies)
124
- # 2. Then tool_calls table (will be referenced by messages)
125
- # 3. Finally messages table (depends on both chats and tool_calls)
126
-
158
+
127
159
# Simply check the order of template calls
128
- # Chats should come before tool_calls, which should come before messages
129
160
chats_position = generator_content . index ( 'create_chats.rb' )
130
- tool_calls_position = generator_content . index ( 'create_tool_calls.rb' )
161
+ tool_calls_position = generator_content . index ( 'create_tool_calls.rb' )
131
162
messages_position = generator_content . index ( 'create_messages.rb' )
132
-
163
+
133
164
# Verify order: chats -> tool_calls -> messages
134
165
expect ( chats_position ) . to be < tool_calls_position
135
166
expect ( tool_calls_position ) . to be < messages_position
136
-
137
- # Also test that the method enforces sequential timestamps
138
- expect ( generator_content ) . to include ( "@migration_number = Time.now.utc.strftime" )
139
- expect ( generator_content ) . to include ( "@migration_number = (@migration_number.to_i + 1).to_s" )
140
- expect ( generator_content ) . to include ( "@migration_number = (@migration_number.to_i + 2).to_s" )
167
+ end
168
+
169
+ it 'enforces sequential migration timestamps' do
170
+ generator_file = '/Users/kieranklaassen/rails/ruby_llm/lib/generators/ruby_llm/install_generator.rb'
171
+ generator_content = File . read ( generator_file )
172
+
173
+ expect ( generator_content ) . to include ( '@migration_number = Time.now.utc.strftime' )
174
+ expect ( generator_content ) . to include ( '@migration_number = (@migration_number.to_i + 1).to_s' )
141
175
end
142
176
end
143
-
144
- describe "database adapter detection" do
145
- it "has proper postgresql detection method" do
146
- generator_file = "/Users/kieranklaassen/rails/ruby_llm/lib/generators/ruby_llm/install_generator.rb"
177
+
178
+ describe 'database adapter detection' do
179
+ it 'defines a postgresql? method' do
180
+ generator_file = '/Users/kieranklaassen/rails/ruby_llm/lib/generators/ruby_llm/install_generator.rb'
181
+ generator_content = File . read ( generator_file )
182
+ expect ( generator_content ) . to include ( 'def postgresql?' )
183
+ end
184
+
185
+ it 'detects PostgreSQL by adapter name' do
186
+ generator_file = '/Users/kieranklaassen/rails/ruby_llm/lib/generators/ruby_llm/install_generator.rb'
187
+ generator_content = File . read ( generator_file )
188
+ expect ( generator_content ) . to include ( 'ActiveRecord::Base.connection.adapter_name.downcase.include?' )
189
+ end
190
+
191
+ it 'handles exceptions gracefully' do
192
+ generator_file = '/Users/kieranklaassen/rails/ruby_llm/lib/generators/ruby_llm/install_generator.rb'
147
193
generator_content = File . read ( generator_file )
148
-
149
- # Check proper postgresql? method implementation
150
- expect ( generator_content ) . to include ( "def postgresql?" )
151
- expect ( generator_content ) . to include ( "ActiveRecord::Base.connection.adapter_name.downcase.include?(\" postgresql\" )" )
152
- expect ( generator_content ) . to include ( "rescue" )
153
- expect ( generator_content ) . to include ( "false" )
194
+ expect ( generator_content ) . to include ( 'rescue' )
195
+ expect ( generator_content ) . to include ( 'false' )
154
196
end
155
197
end
156
- end
198
+ end
0 commit comments