nabokov 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +1 -0
  3. data/.gitignore +43 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +113 -0
  6. data/.travis.yml +14 -0
  7. data/CHANGELOG.md +5 -0
  8. data/Gemfile +9 -0
  9. data/LICENSE +21 -0
  10. data/README.md +16 -0
  11. data/Rakefile +22 -0
  12. data/bin/nabokov +5 -0
  13. data/lib/nabokov/commands/runner.rb +22 -0
  14. data/lib/nabokov/commands/setup.rb +75 -0
  15. data/lib/nabokov/commands/syncers/localizations_repo_syncer.rb +101 -0
  16. data/lib/nabokov/commands/syncers/project_syncer.rb +106 -0
  17. data/lib/nabokov/commands/syncers/syncer.rb +68 -0
  18. data/lib/nabokov/core/file_manager.rb +36 -0
  19. data/lib/nabokov/core/nabokovfile.rb +66 -0
  20. data/lib/nabokov/core/nabokovfile_content_validator.rb +51 -0
  21. data/lib/nabokov/core/nabokovfile_keys.rb +34 -0
  22. data/lib/nabokov/git/git_repo.rb +137 -0
  23. data/lib/nabokov/helpers/informator.rb +83 -0
  24. data/lib/nabokov/helpers/merger.rb +86 -0
  25. data/lib/nabokov/models/strings_file.rb +7 -0
  26. data/lib/nabokov/version.rb +8 -0
  27. data/lib/nabokov.rb +14 -0
  28. data/nabokov.gemspec +31 -0
  29. data/spec/fixtures/.DS_Store +0 -0
  30. data/spec/fixtures/README.md +1 -0
  31. data/spec/fixtures/de.strings +1 -0
  32. data/spec/fixtures/en.strings +1 -0
  33. data/spec/fixtures/nabokovfile_example.yaml +9 -0
  34. data/spec/fixtures/nabokovfile_example_invalid.yaml +2 -0
  35. data/spec/fixtures/nabokovfile_example_without_master_branch.yaml +8 -0
  36. data/spec/fixtures/test_git_setup/existed_pre_commit_file +0 -0
  37. data/spec/fixtures/test_git_setup/existed_pre_commit_file_alias +0 -0
  38. data/spec/fixtures/test_git_setup/not_executable_pre_commit_file +0 -0
  39. data/spec/fixtures/test_localizations_repo_syncer/localizations_repo_fixtures/README.md +1 -0
  40. data/spec/fixtures/test_localizations_repo_syncer/nabokovfile.yaml +8 -0
  41. data/spec/fixtures/test_project_syncer/localizations_repo_fixtures/de.strings +2 -0
  42. data/spec/fixtures/test_project_syncer/localizations_repo_fixtures/en.strings +2 -0
  43. data/spec/fixtures/test_project_syncer/project_repo_fixtures/de.strings +2 -0
  44. data/spec/fixtures/test_project_syncer/project_repo_fixtures/en.strings +2 -0
  45. data/spec/fixtures/test_project_syncer/project_repo_fixtures/nabokovfile.yaml +9 -0
  46. data/spec/lib/nabokov/commands/localizations_repo_syncer_spec.rb +137 -0
  47. data/spec/lib/nabokov/commands/project_syncer_spec.rb +61 -0
  48. data/spec/lib/nabokov/commands/runner_spec.rb +7 -0
  49. data/spec/lib/nabokov/commands/setup_spec.rb +101 -0
  50. data/spec/lib/nabokov/commands/syncer_spec.rb +23 -0
  51. data/spec/lib/nabokov/core/file_manager_spec.rb +115 -0
  52. data/spec/lib/nabokov/core/nabokovfile_content_validator_spec.rb +155 -0
  53. data/spec/lib/nabokov/core/nabokovfile_keyes_spec.rb +31 -0
  54. data/spec/lib/nabokov/core/nabokovfile_spec.rb +53 -0
  55. data/spec/lib/nabokov/git/git_repo_spec.rb +670 -0
  56. data/spec/lib/nabokov/helpers/informator_spec.rb +49 -0
  57. data/spec/lib/nabokov/helpers/merger_spec.rb +114 -0
  58. data/spec/lib/nabokov/models/strings_file_spec.rb +7 -0
  59. data/spec/spec_helper.rb +11 -0
  60. metadata +238 -0
@@ -0,0 +1,670 @@
1
+ require "nabokov/git/git_repo"
2
+ require "git"
3
+
4
+ describe Nabokov::GitRepo do
5
+ before do
6
+ @remote_url = "https://github.com/Antondomashnev/nabokov_example.git"
7
+ end
8
+
9
+ describe "initialization" do
10
+ it "stores remote url after initialization" do
11
+ git_repo = Nabokov::GitRepo.new("spec/fixtures/bla", @remote_url)
12
+ expect(git_repo.remote_url).to eql(@remote_url)
13
+ end
14
+
15
+ it "stores local path after initialization" do
16
+ git_repo = Nabokov::GitRepo.new("spec/fixtures/bla", @remote_url)
17
+ expect(git_repo.local_path).to eql(File.expand_path("spec/fixtures/bla"))
18
+ end
19
+ end
20
+
21
+ describe "clone" do
22
+ context "when there is a repo at the given local path" do
23
+ before do
24
+ @repo_local_path = File.expand_path("spec/fixtures/test_git_repo/clone")
25
+ prepare_repo(@repo_local_path, "spec/fixtures/README.md")
26
+ @git_repo = Nabokov::GitRepo.new(@repo_local_path, @remote_url)
27
+ end
28
+
29
+ after do
30
+ FileUtils.rm_rf("spec/fixtures/test_git_repo")
31
+ end
32
+
33
+ it "raises an error to use init method instead" do
34
+ expect { @git_repo.clone }.to raise_error("Git repo has been already cloned at '#{File.expand_path('spec/fixtures/test_git_repo/clone')}', please use 'init' instead")
35
+ end
36
+ end
37
+
38
+ context "when there is no repo at the given local path" do
39
+ before do
40
+ @git_repo = Nabokov::GitRepo.new("spec/fixtures/test_git_clone", @remote_url)
41
+ end
42
+
43
+ it "clones the repo from the correct remote" do
44
+ allow(Git).to receive(:clone).with(@remote_url, anything, anything)
45
+ @git_repo.clone
46
+ end
47
+
48
+ it "clones the repo with the correct localname" do
49
+ allow(Git).to receive(:clone).with(anything, "test_git_clone", anything)
50
+ @git_repo.clone
51
+ end
52
+
53
+ it "clones the repo with the correct local directory path" do
54
+ allow(Git).to receive(:clone).with(anything, anything, { path: File.expand_path("spec/fixtures") })
55
+ @git_repo.clone
56
+ end
57
+ end
58
+ end
59
+
60
+ describe "add" do
61
+ before do
62
+ @repo_local_path = File.expand_path("spec/fixtures/test_git_repo/add")
63
+ prepare_repo(@repo_local_path, "spec/fixtures/README.md")
64
+ @git_repo = Nabokov::GitRepo.new(@repo_local_path, @remote_url)
65
+ end
66
+
67
+ after do
68
+ FileUtils.rm_rf("spec/fixtures/test_git_repo")
69
+ end
70
+
71
+ context "when there is not file to add at the given path" do
72
+ it "raises an error" do
73
+ expect { @git_repo.add("spec/fixtures/qq.strings") }.to raise_error("Could not find any file to add at path 'spec/fixtures/qq.strings'")
74
+ end
75
+ end
76
+
77
+ context "when there is a file to add" do
78
+ context "when git repo has not been initialized yet" do
79
+ it "raises an error" do
80
+ expect { @git_repo.add("spec/fixtures/de.strings") }.to raise_error("'git' is not initialized yet, please call either 'clone' or 'init' before adding new files to the index")
81
+ end
82
+ end
83
+
84
+ context "when git repo has been initialized" do
85
+ before do
86
+ @git_repo.init
87
+ end
88
+
89
+ it "adds file at the given path to the git repo index" do
90
+ FileUtils.cp_r("spec/fixtures/de.strings", @git_repo.local_path)
91
+
92
+ @git_repo.add("#{@repo_local_path}/de.strings")
93
+
94
+ expect(@git_repo.git_repo.status.added.count).to eql(1)
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ describe "commit" do
101
+ before do
102
+ @repo_local_path = File.expand_path("spec/fixtures/test_git_repo/commit")
103
+ prepare_repo(@repo_local_path, "spec/fixtures/README.md")
104
+ @git_repo = Nabokov::GitRepo.new(@repo_local_path, @remote_url)
105
+ end
106
+
107
+ after do
108
+ FileUtils.rm_rf("spec/fixtures/test_git_repo")
109
+ end
110
+
111
+ context "when git repo has not been initialized yet" do
112
+ it "raises an error" do
113
+ expect { @git_repo.commit }.to raise_error("'git' is not initialized yet, please call either 'clone' or 'init' before commiting new files")
114
+ end
115
+ end
116
+
117
+ context "when git repo has been initialized" do
118
+ before do
119
+ @git_repo.init
120
+ end
121
+
122
+ it "makes a commit with correct message" do
123
+ FileUtils.cp_r("spec/fixtures/de.strings", @git_repo.local_path)
124
+ @git_repo.add("#{@repo_local_path}/de.strings")
125
+
126
+ @git_repo.commit
127
+
128
+ expect(@git_repo.git_repo.log.first.message).to eql("Automatic commit by nabokov")
129
+ end
130
+ end
131
+ end
132
+
133
+ describe "push" do
134
+ before do
135
+ @repo_local_path = File.expand_path("spec/fixtures/test_git_repo/push")
136
+ prepare_repo(@repo_local_path, "spec/fixtures/README.md")
137
+ @git_repo = Nabokov::GitRepo.new(@repo_local_path, @remote_url)
138
+ end
139
+
140
+ after do
141
+ FileUtils.rm_rf("spec/fixtures/test_git_repo")
142
+ end
143
+
144
+ context "when git repo has not been initialized yet" do
145
+ it "raises an error" do
146
+ expect { @git_repo.push }.to raise_error("'git' is not initialized yet, please call either 'clone' or 'init' before pushing any changes to remote")
147
+ end
148
+ end
149
+
150
+ context "when git repo has been initialized" do
151
+ before do
152
+ @git_repo.init
153
+ end
154
+
155
+ it "makes a push to the remote" do
156
+ expect(@git_repo.git_repo).to receive(:push)
157
+
158
+ @git_repo.push
159
+ end
160
+ end
161
+ end
162
+
163
+ describe "pull" do
164
+ before do
165
+ @repo_local_path = File.expand_path("spec/fixtures/test_git_repo/pull")
166
+ prepare_repo(@repo_local_path, "spec/fixtures/README.md")
167
+ @git_repo = Nabokov::GitRepo.new(@repo_local_path, @remote_url)
168
+ end
169
+
170
+ after do
171
+ FileUtils.rm_rf("spec/fixtures/test_git_repo")
172
+ end
173
+
174
+ context "when git repo has not been initialized yet" do
175
+ it "raises an error" do
176
+ expect { @git_repo.pull }.to raise_error("'git' is not initialized yet, please call either 'clone' or 'init' before pushing any changes to remote")
177
+ end
178
+ end
179
+
180
+ context "when git repo has been initialized" do
181
+ before do
182
+ @git_repo.init
183
+ end
184
+
185
+ it "makes a pull from the remote" do
186
+ expect(@git_repo.git_repo).to receive(:pull)
187
+
188
+ @git_repo.pull
189
+ end
190
+ end
191
+ end
192
+
193
+ describe "checkout_branch" do
194
+ before do
195
+ @repo_local_path = File.expand_path("spec/fixtures/test_git_repo/checkout_branch")
196
+ prepare_repo(@repo_local_path, "spec/fixtures/README.md")
197
+ @git_repo = Nabokov::GitRepo.new(@repo_local_path, @remote_url)
198
+ end
199
+
200
+ after do
201
+ FileUtils.rm_rf("spec/fixtures/test_git_repo")
202
+ end
203
+
204
+ context "when git repo has not been initialized yet" do
205
+ it "raises an error" do
206
+ expect { @git_repo.checkout_branch("temp") }.to raise_error("'git' is not initialized yet, please call either 'clone' or 'init' before checkouting any branch")
207
+ end
208
+ end
209
+
210
+ context "when git repo is initialized" do
211
+ before do
212
+ @git_repo.init
213
+ end
214
+
215
+ context "when branch name parameter is passed" do
216
+ context "when branch exists" do
217
+ before do
218
+ allow(@git_repo.git_repo).to receive(:is_branch?).with("temp_branch").and_return(true)
219
+ end
220
+
221
+ it "checkouts the given branch" do
222
+ expect(@git_repo.git_repo).to receive(:checkout).with("temp_branch")
223
+
224
+ @git_repo.checkout_branch("temp_branch")
225
+ end
226
+ end
227
+
228
+ context "when branch doesn't exist" do
229
+ before do
230
+ allow(@git_repo.git_repo).to receive(:is_branch?).with("temp_branch").and_return(false)
231
+ end
232
+
233
+ it "checkouts a new branch" do
234
+ expect(@git_repo.git_repo).to receive(:checkout).with("temp_branch", { new_branch: true })
235
+
236
+ @git_repo.checkout_branch("temp_branch")
237
+ end
238
+ end
239
+ end
240
+
241
+ context "when branch name parameter is zero length string" do
242
+ it "raises an error" do
243
+ expect { @git_repo.checkout_branch("") }.to raise_error("branch name could not be nil or zero length")
244
+ end
245
+ end
246
+ end
247
+ end
248
+
249
+ describe "delete_branch" do
250
+ before do
251
+ @repo_local_path = File.expand_path("spec/fixtures/test_git_repo/delete_branch")
252
+ prepare_repo(@repo_local_path, "spec/fixtures/README.md")
253
+ @git_repo = Nabokov::GitRepo.new(@repo_local_path, @remote_url)
254
+ end
255
+
256
+ after do
257
+ FileUtils.rm_rf("spec/fixtures/test_git_repo")
258
+ end
259
+
260
+ context "when git repo has not been initialized yet" do
261
+ it "raises an error" do
262
+ expect { @git_repo.delete_branch("temp") }.to raise_error("'git' is not initialized yet, please call either 'clone' or 'init' before deleting any branch")
263
+ end
264
+ end
265
+
266
+ context "when git repo is initialized" do
267
+ before do
268
+ @git_repo.init
269
+ end
270
+
271
+ context "when branch name parameter is passed" do
272
+ it "deletes a branch with the given name" do
273
+ git_branch = Git::Branch.new("temp_branch", "temp_branch")
274
+ allow(git_branch).to receive(:delete)
275
+
276
+ expect(@git_repo.git_repo).to receive(:branch).with("temp_branch").and_return(git_branch)
277
+
278
+ @git_repo.delete_branch("temp_branch")
279
+ end
280
+ end
281
+
282
+ context "when branch name parameter is zero length string" do
283
+ it "raises an error" do
284
+ expect { @git_repo.delete_branch("") }.to raise_error("branch name could not be nil or zero length")
285
+ end
286
+ end
287
+ end
288
+ end
289
+
290
+ describe "merge_branches" do
291
+ before do
292
+ @repo_local_path = File.expand_path("spec/fixtures/test_git_repo/merge_branches")
293
+ prepare_repo(@repo_local_path, "spec/fixtures/README.md")
294
+ @git_repo = Nabokov::GitRepo.new(@repo_local_path, @remote_url)
295
+ end
296
+
297
+ after do
298
+ FileUtils.rm_rf("spec/fixtures/test_git_repo")
299
+ end
300
+
301
+ context "when git repo has not been initialized yet" do
302
+ it "raises an error" do
303
+ expect { @git_repo.merge_branches("temp1", "temp2") }.to raise_error("'git' is not initialized yet, please call either 'clone' or 'init' before merging any branches")
304
+ end
305
+ end
306
+
307
+ context "when git repo is initialized" do
308
+ before do
309
+ @git_repo.init
310
+ end
311
+
312
+ context "when branch name parameters are passed" do
313
+ it "merges a branch to be merged into original branch" do
314
+ git_original_branch = Git::Branch.new("branch1", "branch1")
315
+ git_branch_to_be_merged = Git::Branch.new("branch2", "branch2")
316
+ allow(git_original_branch).to receive(:merge).with(git_branch_to_be_merged)
317
+ expect(@git_repo.git_repo).to receive(:branch).with("branch1").and_return(git_original_branch)
318
+ expect(@git_repo.git_repo).to receive(:branch).with("branch2").and_return(git_branch_to_be_merged)
319
+ @git_repo.merge_branches("branch1", "branch2")
320
+ end
321
+ end
322
+
323
+ context "when original branch name parameter is zero length string" do
324
+ it "raises an error" do
325
+ expect { @git_repo.merge_branches("", "branch2") }.to raise_error("original branch name could not be nil or zero length")
326
+ end
327
+ end
328
+
329
+ context "when branch to be merged name parameter is zero length string" do
330
+ it "raises an error" do
331
+ expect { @git_repo.merge_branches("branch1", "") }.to raise_error("branch to be merged in name could not be nil or zero length")
332
+ end
333
+ end
334
+ end
335
+ end
336
+
337
+ describe "unfinished_merge?" do
338
+ before do
339
+ @repo_local_path = File.expand_path("spec/fixtures/test_git_repo/unfinished_merge?")
340
+ prepare_repo(@repo_local_path, "spec/fixtures/README.md")
341
+ @git_repo = Nabokov::GitRepo.new(@repo_local_path, @remote_url)
342
+ end
343
+
344
+ after do
345
+ FileUtils.rm_rf("spec/fixtures/test_git_repo")
346
+ end
347
+
348
+ context "when git repo has not been initialized yet" do
349
+ it "raises an error" do
350
+ expect { @git_repo.unfinished_merge? }.to raise_error("'git' is not initialized yet, please call either 'clone' or 'init' before checking if the git repo has unfinished merge")
351
+ end
352
+ end
353
+
354
+ context "when git repo is initialized" do
355
+ before do
356
+ @git_repo.init
357
+ end
358
+
359
+ context "when git repo doesn't have unmerged files" do
360
+ before do
361
+ allow(@git_repo.git_repo).to receive(:has_unmerged_files?).and_return(false)
362
+ end
363
+
364
+ it "returns false" do
365
+ expect(@git_repo.unfinished_merge?).to be_falsy
366
+ end
367
+ end
368
+
369
+ context "when git repo has unmerged files" do
370
+ before do
371
+ allow(@git_repo.git_repo).to receive(:has_unmerged_files?).and_return(true)
372
+ end
373
+
374
+ it "returns false" do
375
+ expect(@git_repo.unfinished_merge?).to be_truthy
376
+ end
377
+ end
378
+ end
379
+ end
380
+
381
+ describe "abort_merge" do
382
+ before do
383
+ @repo_local_path = File.expand_path("spec/fixtures/test_git_repo/abort_merge")
384
+ prepare_repo(@repo_local_path, "spec/fixtures/README.md")
385
+ @git_repo = Nabokov::GitRepo.new(@repo_local_path, @remote_url)
386
+ end
387
+
388
+ after do
389
+ FileUtils.rm_rf("spec/fixtures/test_git_repo")
390
+ end
391
+
392
+ context "when git repo has not been initialized yet" do
393
+ it "raises an error" do
394
+ expect { @git_repo.abort_merge }.to raise_error("'git' is not initialized yet, please call either 'clone' or 'init' before aborting merge")
395
+ end
396
+ end
397
+
398
+ context "when git repo is initialized" do
399
+ before do
400
+ @git_repo.init
401
+ end
402
+
403
+ context "when git repo doesn't have unfinished merge" do
404
+ before do
405
+ allow(@git_repo.git_repo).to receive(:has_unmerged_files?).and_return(false)
406
+ end
407
+
408
+ it "raises an error" do
409
+ expect { @git_repo.abort_merge }.to raise_error("nothing to abort - git repo doesn't have unfinished merge")
410
+ end
411
+ end
412
+
413
+ context "when git repo has unfinished merge" do
414
+ before do
415
+ allow(@git_repo.git_repo).to receive(:has_unmerged_files?).and_return(true)
416
+ end
417
+
418
+ it "aborts merge" do
419
+ expect(@git_repo.git_repo).to receive(:abort_merge)
420
+
421
+ @git_repo.abort_merge
422
+ end
423
+ end
424
+ end
425
+ end
426
+
427
+ describe "unmerged_files" do
428
+ before do
429
+ @repo_local_path = File.expand_path("spec/fixtures/test_git_repo/unmerged_files")
430
+ prepare_repo(@repo_local_path, "spec/fixtures/README.md")
431
+ @git_repo = Nabokov::GitRepo.new(@repo_local_path, @remote_url)
432
+ end
433
+
434
+ after do
435
+ FileUtils.rm_rf("spec/fixtures/test_git_repo")
436
+ end
437
+
438
+ context "when git repo has not been initialized yet" do
439
+ it "raises an error" do
440
+ expect { @git_repo.unmerged_files }.to raise_error("'git' is not initialized yet, please call either 'clone' or 'init' before asking for unmerged files")
441
+ end
442
+ end
443
+
444
+ context "when git repo is initialized" do
445
+ before do
446
+ @git_repo.init
447
+ end
448
+
449
+ context "when git repo has unfinished merge" do
450
+ before do
451
+ allow(@git_repo.git_repo).to receive(:has_unmerged_files?).and_return(true)
452
+ allow(@git_repo.git_repo).to receive(:each_conflict) { |&block|
453
+ block.call("file1.txt", "", "")
454
+ block.call("file2.txt", "", "")
455
+ }
456
+ end
457
+
458
+ it "returns unfinished file pathes" do
459
+ expect(@git_repo.unmerged_files).to eql(["file1.txt", "file2.txt"])
460
+ end
461
+ end
462
+
463
+ context "when git repo doesn't have unfinished merge" do
464
+ before do
465
+ allow(@git_repo.git_repo).to receive(:has_unmerged_files?).and_return(false)
466
+ end
467
+
468
+ it "returns empty array" do
469
+ expect(@git_repo.unmerged_files).to eql([])
470
+ end
471
+ end
472
+ end
473
+ end
474
+
475
+ describe "current_branch" do
476
+ before do
477
+ @repo_local_path = File.expand_path("spec/fixtures/test_git_repo/current_branch")
478
+ prepare_repo(@repo_local_path, "spec/fixtures/README.md")
479
+ @git_repo = Nabokov::GitRepo.new(@repo_local_path, @remote_url)
480
+ end
481
+
482
+ after do
483
+ FileUtils.rm_rf("spec/fixtures/test_git_repo")
484
+ end
485
+
486
+ context "when git repo has not been initialized yet" do
487
+ it "raises an error" do
488
+ expect { @git_repo.current_branch }.to raise_error("'git' is not initialized yet, please call either 'clone' or 'init' before getting the current branch")
489
+ end
490
+ end
491
+
492
+ context "when git repo is initialized" do
493
+ before do
494
+ @git_repo.init
495
+ end
496
+
497
+ it "returns the current branch name" do
498
+ allow(@git_repo.git_repo).to receive(:current_branch).and_return("develop")
499
+
500
+ expect(@git_repo.current_branch).to eql("develop")
501
+ end
502
+ end
503
+ end
504
+
505
+ describe "log" do
506
+ before do
507
+ @repo_local_path = File.expand_path("spec/fixtures/test_git_repo/log")
508
+ prepare_repo(@repo_local_path, "spec/fixtures/README.md")
509
+ @git_repo = Nabokov::GitRepo.new(@repo_local_path, @remote_url)
510
+ end
511
+
512
+ after do
513
+ FileUtils.rm_rf("spec/fixtures/test_git_repo")
514
+ end
515
+
516
+ context "when git repo has not been initialized yet" do
517
+ it "raises an error" do
518
+ expect { @git_repo.log(5) }.to raise_error("'git' is not initialized yet, please call either 'clone' or 'init' before getting the log")
519
+ end
520
+ end
521
+
522
+ context "when git repo is initialized" do
523
+ before do
524
+ @git_repo.init
525
+ end
526
+
527
+ it "returns last n commit shas" do
528
+ commit1 = Git::Object::Commit.new("base", "1234567890", nil)
529
+ allow(commit1).to receive(:sha).and_return("1234567890")
530
+ commit2 = Git::Object::Commit.new("base", "1234567891", nil)
531
+ allow(commit2).to receive(:sha).and_return("1234567891")
532
+ commit3 = Git::Object::Commit.new("base", "1234567892", nil)
533
+ allow(commit3).to receive(:sha).and_return("1234567892")
534
+ commit4 = Git::Object::Commit.new("base", "1234567893", nil)
535
+ allow(commit4).to receive(:sha).and_return("1234567893")
536
+ commit5 = Git::Object::Commit.new("base", "1234567894", nil)
537
+ allow(commit5).to receive(:sha).and_return("1234567894")
538
+ allow(@git_repo.git_repo).to receive(:log).with(3).and_return([commit1, commit2, commit3])
539
+ allow(@git_repo.git_repo).to receive(:log).with(5).and_return([commit1, commit2, commit3, commit4, commit5])
540
+
541
+ expect(@git_repo.log(3)).to eql(["1234567890", "1234567891", "1234567892"])
542
+ expect(@git_repo.log(5)).to eql(["1234567890", "1234567891", "1234567892", "1234567893", "1234567894"])
543
+ end
544
+ end
545
+ end
546
+
547
+ describe "reset_to_commit" do
548
+ before do
549
+ @repo_local_path = File.expand_path("spec/fixtures/test_git_repo/reset_to_commit")
550
+ prepare_repo(@repo_local_path, "spec/fixtures/README.md")
551
+ @git_repo = Nabokov::GitRepo.new(@repo_local_path, @remote_url)
552
+ end
553
+
554
+ after do
555
+ FileUtils.rm_rf("spec/fixtures/test_git_repo")
556
+ end
557
+
558
+ context "when git repo has not been initialized yet" do
559
+ it "raises an error" do
560
+ expect { @git_repo.reset_to_commit("1234567890") }.to raise_error("'git' is not initialized yet, please call either 'clone' or 'init' before resetting")
561
+ end
562
+ end
563
+
564
+ context "when git repo is initialized" do
565
+ before do
566
+ @git_repo.init
567
+ end
568
+
569
+ context "when commit sha is not provided" do
570
+ it "raises an error" do
571
+ expect { @git_repo.reset_to_commit(nil) }.to raise_error("'commit' is a required parameter and could not be nil")
572
+ end
573
+ end
574
+
575
+ context "when commit sha is provided" do
576
+ context "when soft reset" do
577
+ it "does soft reset" do
578
+ expect(@git_repo.git_repo).to receive(:reset).with("1234567890")
579
+
580
+ @git_repo.reset_to_commit("1234567890")
581
+ end
582
+ end
583
+
584
+ context "when hard reset" do
585
+ it "does hard reset" do
586
+ expect(@git_repo.git_repo).to receive(:reset_hard).with("1234567890")
587
+
588
+ @git_repo.reset_to_commit("1234567890", { hard: true })
589
+ end
590
+ end
591
+ end
592
+ end
593
+ end
594
+
595
+ describe "changes?" do
596
+ before do
597
+ @repo_local_path = File.expand_path("spec/fixtures/test_git_repo/changes?")
598
+ prepare_repo(@repo_local_path, "spec/fixtures/README.md")
599
+ @git_repo = Nabokov::GitRepo.new(@repo_local_path, @remote_url)
600
+ end
601
+
602
+ after do
603
+ FileUtils.rm_rf("spec/fixtures/test_git_repo")
604
+ end
605
+
606
+ context "when git repo has not been initialized yet" do
607
+ it "raises an error" do
608
+ expect { @git_repo.changes? }.to raise_error("'git' is not initialized yet, please call either 'clone' or 'init' before checking if the git repo has changes")
609
+ end
610
+ end
611
+
612
+ context "when git repo is initialized" do
613
+ before do
614
+ @git_repo.init
615
+ allow_any_instance_of(Git::Status).to receive(:construct_status) {}
616
+ end
617
+
618
+ context "when the repo has added files" do
619
+ before do
620
+ added_file = object_double(Git::Status::StatusFile.new("base", {}))
621
+ allow_any_instance_of(Git::Status).to receive(:added).and_return({ path: "a", file: added_file })
622
+ allow_any_instance_of(Git::Status).to receive(:changed).and_return([])
623
+ allow_any_instance_of(Git::Status).to receive(:deleted).and_return([])
624
+ end
625
+
626
+ it "returns true" do
627
+ expect(@git_repo.changes?).to be_truthy
628
+ end
629
+ end
630
+
631
+ context "when the repo has deleted files" do
632
+ before do
633
+ deleted_file = object_double(Git::Status::StatusFile.new("base", {}))
634
+ allow_any_instance_of(Git::Status).to receive(:deleted).and_return({ path: "a", file: deleted_file })
635
+ allow_any_instance_of(Git::Status).to receive(:changed).and_return([])
636
+ allow_any_instance_of(Git::Status).to receive(:added).and_return([])
637
+ end
638
+
639
+ it "returns true" do
640
+ expect(@git_repo.changes?).to be_truthy
641
+ end
642
+ end
643
+
644
+ context "when the repo has changed files" do
645
+ before do
646
+ changed_file = object_double(Git::Status::StatusFile.new("base", {}))
647
+ allow_any_instance_of(Git::Status).to receive(:changed).and_return({ path: "a", file: changed_file })
648
+ allow_any_instance_of(Git::Status).to receive(:deleted).and_return([])
649
+ allow_any_instance_of(Git::Status).to receive(:added).and_return([])
650
+ end
651
+
652
+ it "returns true" do
653
+ expect(@git_repo.changes?).to be_truthy
654
+ end
655
+ end
656
+
657
+ context "when the repo has no changed, added and deleted files" do
658
+ before do
659
+ allow_any_instance_of(Git::Status).to receive(:changed).and_return([])
660
+ allow_any_instance_of(Git::Status).to receive(:deleted).and_return([])
661
+ allow_any_instance_of(Git::Status).to receive(:added).and_return([])
662
+ end
663
+
664
+ it "returns false" do
665
+ expect(@git_repo.changes?).to be_falsy
666
+ end
667
+ end
668
+ end
669
+ end
670
+ end