neeto-translate-cli 0.1.1 → 0.1.3
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.
- checksums.yaml +4 -4
- data/lib/neeto_translate_cli/cli.rb +12 -1
- data/lib/neeto_translate_cli/payload_builder.rb +9 -1
- data/lib/neeto_translate_cli/version.rb +1 -1
- data/test/neeto_translate_cli/api_test.rb +107 -0
- data/test/neeto_translate_cli/cli_test.rb +101 -0
- data/test/neeto_translate_cli/integration_test.rb +142 -0
- data/test/neeto_translate_cli/payload_builder_test.rb +123 -1
- data/test/neeto_translate_cli/translator_test.rb +108 -0
- data/test/neeto_translate_cli/version_test.rb +20 -0
- data/test/test_helper.rb +5 -0
- metadata +7 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8da56632b83b84dc6b5f035e2d618c68132c622459514e5af6ad0f485bfd150f
|
|
4
|
+
data.tar.gz: f9d7f52510d0683e2fa3d3412d4a369d401f0d2024cba9bfb664325b9b7fc930
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0d0478fa14e85769ef5a421c47e5db0629edaf5f4c369161b905e87acd6668eb81c3b0a24411b1d574234e37df3408161056895ac8af6149a62604ff8fa36ad6
|
|
7
|
+
data.tar.gz: caf06404f0984879c000e41e8b872c013661f205edba51c5ef5809274924b2a56c122a13bd712f263bca86bc73e20bcd0e554644d6ff124e70ed26e2b4730ea0
|
|
@@ -20,6 +20,13 @@ module NeetoTranslateCli
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def run
|
|
23
|
+
options = parse_options(@args)
|
|
24
|
+
run_with_options(options)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def parse_options(args)
|
|
23
30
|
options = {
|
|
24
31
|
frontend: DEFAULT_FRONTEND_LOCALE_PATH,
|
|
25
32
|
backend: DEFAULT_BACKEND_LOCALE_PATH,
|
|
@@ -36,8 +43,12 @@ module NeetoTranslateCli
|
|
|
36
43
|
opts.on("--repo NAME", "Name of the GitHub repository (eg: neetozone/neeto-cal-web).") do |path|
|
|
37
44
|
options[:repo] = path
|
|
38
45
|
end
|
|
39
|
-
end.parse!(
|
|
46
|
+
end.parse!(args)
|
|
47
|
+
|
|
48
|
+
options
|
|
49
|
+
end
|
|
40
50
|
|
|
51
|
+
def run_with_options(options)
|
|
41
52
|
Translator.new(options).process!
|
|
42
53
|
end
|
|
43
54
|
end
|
|
@@ -9,7 +9,7 @@ module NeetoTranslateCli
|
|
|
9
9
|
|
|
10
10
|
def initialize(options)
|
|
11
11
|
@options = options
|
|
12
|
-
commit_id =
|
|
12
|
+
commit_id = git_commit_id
|
|
13
13
|
@updated_keys = commit_id.empty? ? { frontend: [], backend: [] } : find_updated_keys(commit_id)
|
|
14
14
|
end
|
|
15
15
|
|
|
@@ -31,6 +31,10 @@ module NeetoTranslateCli
|
|
|
31
31
|
|
|
32
32
|
private
|
|
33
33
|
|
|
34
|
+
def git_commit_id
|
|
35
|
+
`git log --author="#{COMMIT_AUTHOR}" --grep="\[neeto-translate\]" -n 1 --pretty=format:"%H"`.strip
|
|
36
|
+
end
|
|
37
|
+
|
|
34
38
|
def en_json_flattened
|
|
35
39
|
@_en_json_flattened ||= flatten_hash(load_json(File.expand_path("en.json", options[:frontend])))
|
|
36
40
|
end
|
|
@@ -91,10 +95,14 @@ module NeetoTranslateCli
|
|
|
91
95
|
end
|
|
92
96
|
|
|
93
97
|
def load_json(file_path)
|
|
98
|
+
return {} unless File.file?(file_path)
|
|
99
|
+
|
|
94
100
|
JSON.parse(File.read(file_path, encoding: "utf-8"))
|
|
95
101
|
end
|
|
96
102
|
|
|
97
103
|
def load_yml(file_path)
|
|
104
|
+
return {} unless File.file?(file_path)
|
|
105
|
+
|
|
98
106
|
YAML.load_file(file_path, aliases: true)
|
|
99
107
|
end
|
|
100
108
|
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
class NeetoTranslateCli::APITest < Minitest::Test
|
|
4
|
+
def setup
|
|
5
|
+
@api = NeetoTranslateCli::Api.new
|
|
6
|
+
@original_env = ENV.to_hash
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def teardown
|
|
10
|
+
ENV.replace(@original_env)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_translate_makes_post_request
|
|
14
|
+
payload = { test: "data" }
|
|
15
|
+
response = "mocked response"
|
|
16
|
+
|
|
17
|
+
@api.stub :connection, MockConnection.new(self, "/translation", payload.to_json, response) do
|
|
18
|
+
result = @api.translate!(payload)
|
|
19
|
+
assert_equal response, result
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_connection_uses_default_url
|
|
24
|
+
ENV.delete("NEETO_TRANSLATE_URL")
|
|
25
|
+
connection = @api.send(:connection)
|
|
26
|
+
|
|
27
|
+
assert_equal "https://translate.neeto.com", connection.url_prefix.to_s.chomp("/")
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_connection_uses_env_url
|
|
31
|
+
ENV["NEETO_TRANSLATE_URL"] = "https://custom.translate.com"
|
|
32
|
+
connection = @api.send(:connection)
|
|
33
|
+
|
|
34
|
+
assert_equal "https://custom.translate.com", connection.url_prefix.to_s.chomp("/")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def test_headers_include_content_type
|
|
38
|
+
headers = @api.send(:headers)
|
|
39
|
+
|
|
40
|
+
assert_equal "application/json", headers["Content-Type"]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def test_headers_include_token_from_env
|
|
44
|
+
ENV["NEETO_TRANSLATE_X_TOKEN"] = "test-token-123"
|
|
45
|
+
headers = @api.send(:headers)
|
|
46
|
+
|
|
47
|
+
assert_equal "test-token-123", headers["NEETO-TRANSLATE-X-TOKEN"]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def test_headers_without_token
|
|
51
|
+
ENV.delete("NEETO_TRANSLATE_X_TOKEN")
|
|
52
|
+
headers = @api.send(:headers)
|
|
53
|
+
|
|
54
|
+
assert_nil headers["NEETO-TRANSLATE-X-TOKEN"]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def test_connection_is_cached
|
|
58
|
+
connection1 = @api.send(:connection)
|
|
59
|
+
connection2 = @api.send(:connection)
|
|
60
|
+
|
|
61
|
+
assert_same connection1, connection2
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def test_translate_with_real_payload
|
|
65
|
+
payload = {
|
|
66
|
+
frontend: { en: { "key" => "value" }, missing_keys: { "es" => ["key"] } },
|
|
67
|
+
backend: { en: { "key" => "value" }, missing_keys: { "es" => ["key"] } },
|
|
68
|
+
metadata: { repo: "test-repo", frontend: "path", backend: "path" }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
response = "mocked response"
|
|
72
|
+
|
|
73
|
+
@api.stub :connection, MockConnection.new(self, "/translation", payload.to_json, response) do
|
|
74
|
+
result = @api.translate!(payload)
|
|
75
|
+
assert_equal response, result
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
|
|
81
|
+
class MockConnection
|
|
82
|
+
def initialize(test_context, expected_path, expected_body, response)
|
|
83
|
+
@test_context = test_context
|
|
84
|
+
@expected_path = expected_path
|
|
85
|
+
@expected_body = expected_body
|
|
86
|
+
@response = response
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def post(path)
|
|
90
|
+
@test_context.assert_equal @expected_path, path
|
|
91
|
+
request = MockRequest.new(@test_context, @expected_body)
|
|
92
|
+
yield request
|
|
93
|
+
@response
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
class MockRequest
|
|
98
|
+
def initialize(test_context, expected_body)
|
|
99
|
+
@test_context = test_context
|
|
100
|
+
@expected_body = expected_body
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def body=(actual_body)
|
|
104
|
+
@test_context.assert_equal @expected_body, actual_body
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
class NeetoTranslateCli::CLITest < Minitest::Test
|
|
4
|
+
def setup
|
|
5
|
+
@original_env = ENV.to_hash
|
|
6
|
+
@original_git_repo = `git rev-parse --show-toplevel`.split("/").last.strip
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def teardown
|
|
10
|
+
ENV.replace(@original_env)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_start_with_default_options
|
|
14
|
+
cli = NeetoTranslateCli::CLI.new([])
|
|
15
|
+
options = cli.send(:parse_options, [])
|
|
16
|
+
|
|
17
|
+
assert_equal "app/javascript/src/translations", options[:frontend]
|
|
18
|
+
assert_equal "config/locales", options[:backend]
|
|
19
|
+
assert_equal %w[en fr de es], options[:default_languages]
|
|
20
|
+
assert_equal @original_git_repo, options[:repo]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_start_with_custom_frontend_path
|
|
24
|
+
cli = NeetoTranslateCli::CLI.new([])
|
|
25
|
+
options = cli.send(:parse_options, ["--frontend", "custom/frontend/path"])
|
|
26
|
+
|
|
27
|
+
assert_equal "custom/frontend/path", options[:frontend]
|
|
28
|
+
assert_equal "config/locales", options[:backend]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_start_with_custom_backend_path
|
|
32
|
+
cli = NeetoTranslateCli::CLI.new([])
|
|
33
|
+
options = cli.send(:parse_options, ["--backend", "custom/backend/path"])
|
|
34
|
+
|
|
35
|
+
assert_equal "app/javascript/src/translations", options[:frontend]
|
|
36
|
+
assert_equal "custom/backend/path", options[:backend]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_start_with_custom_languages
|
|
40
|
+
cli = NeetoTranslateCli::CLI.new([])
|
|
41
|
+
options = cli.send(:parse_options, ["--defaults", "ja,ko,zh"])
|
|
42
|
+
|
|
43
|
+
assert_equal %w[ja ko zh], options[:default_languages]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def test_start_with_custom_repo
|
|
47
|
+
cli = NeetoTranslateCli::CLI.new([])
|
|
48
|
+
options = cli.send(:parse_options, ["--repo", "neetozone/custom-repo"])
|
|
49
|
+
|
|
50
|
+
assert_equal "neetozone/custom-repo", options[:repo]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def test_start_with_all_custom_options
|
|
54
|
+
cli = NeetoTranslateCli::CLI.new([])
|
|
55
|
+
options = cli.send(:parse_options, [
|
|
56
|
+
"--frontend", "custom/frontend",
|
|
57
|
+
"--backend", "custom/backend",
|
|
58
|
+
"--defaults", "ja,ko",
|
|
59
|
+
"--repo", "neetozone/test-repo"
|
|
60
|
+
])
|
|
61
|
+
|
|
62
|
+
assert_equal "custom/frontend", options[:frontend]
|
|
63
|
+
assert_equal "custom/backend", options[:backend]
|
|
64
|
+
assert_equal %w[ja ko], options[:default_languages]
|
|
65
|
+
assert_equal "neetozone/test-repo", options[:repo]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def test_default_languages_from_env
|
|
69
|
+
ENV["DEFAULT_LANGUAGES"] = "ja,ko,zh"
|
|
70
|
+
cli = NeetoTranslateCli::CLI.new([])
|
|
71
|
+
options = cli.send(:parse_options, [])
|
|
72
|
+
|
|
73
|
+
assert_equal %w[ja ko zh], options[:default_languages]
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def test_run_calls_translator
|
|
77
|
+
mock_translator = Minitest::Mock.new
|
|
78
|
+
mock_translator.expect :process!, nil
|
|
79
|
+
|
|
80
|
+
options = {
|
|
81
|
+
frontend: "test/fixtures/frontend",
|
|
82
|
+
backend: "test/fixtures/backend",
|
|
83
|
+
default_languages: %w[es de],
|
|
84
|
+
repo: "test-repo"
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
NeetoTranslateCli::Translator.stub :new, mock_translator do
|
|
88
|
+
cli = NeetoTranslateCli::CLI.new([])
|
|
89
|
+
cli.send(:run_with_options, options)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
mock_translator.verify
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
private
|
|
96
|
+
|
|
97
|
+
def parse_options(args)
|
|
98
|
+
cli = NeetoTranslateCli::CLI.new(args)
|
|
99
|
+
cli.send(:parse_options, args)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
class NeetoTranslateCli::IntegrationTest < Minitest::Test
|
|
4
|
+
def setup
|
|
5
|
+
@original_env = ENV.to_hash
|
|
6
|
+
@options = {
|
|
7
|
+
frontend: "test/fixtures/frontend",
|
|
8
|
+
backend: "test/fixtures/backend",
|
|
9
|
+
default_languages: %w[es de],
|
|
10
|
+
repo: "test-repo"
|
|
11
|
+
}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def teardown
|
|
15
|
+
ENV.replace(@original_env)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_full_translation_flow_with_changes
|
|
19
|
+
# Mock the API response
|
|
20
|
+
mock_response = Minitest::Mock.new
|
|
21
|
+
mock_response.expect :body, "Translation job submitted successfully"
|
|
22
|
+
|
|
23
|
+
# Mock the API class
|
|
24
|
+
mock_api = Minitest::Mock.new
|
|
25
|
+
mock_api.expect :translate!, mock_response do |payload|
|
|
26
|
+
# Verify payload structure
|
|
27
|
+
assert payload.key?(:frontend)
|
|
28
|
+
assert payload.key?(:backend)
|
|
29
|
+
assert payload.key?(:metadata)
|
|
30
|
+
assert payload[:frontend].key?(:en)
|
|
31
|
+
assert payload[:frontend].key?(:missing_keys)
|
|
32
|
+
assert payload[:backend].key?(:en)
|
|
33
|
+
assert payload[:backend].key?(:missing_keys)
|
|
34
|
+
assert_equal "test-repo", payload[:metadata][:repo]
|
|
35
|
+
mock_response
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
output = capture_io do
|
|
39
|
+
NeetoTranslateCli::Api.stub :new, mock_api do
|
|
40
|
+
translator = NeetoTranslateCli::Translator.new(@options)
|
|
41
|
+
translator.process!
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
assert_includes output.join, "Translation job submitted successfully"
|
|
46
|
+
mock_api.verify
|
|
47
|
+
mock_response.verify
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def test_full_translation_flow_with_no_changes
|
|
51
|
+
# Create a payload builder that returns no changes
|
|
52
|
+
mock_payload_builder = Minitest::Mock.new
|
|
53
|
+
mock_payload = {
|
|
54
|
+
frontend: { missing_keys: { "es" => [], "de" => [] } },
|
|
55
|
+
backend: { missing_keys: { "es" => [], "de" => [] } }
|
|
56
|
+
}
|
|
57
|
+
mock_payload_builder.expect :process!, mock_payload
|
|
58
|
+
mock_payload_builder.expect :no_new_changes?, true, [mock_payload]
|
|
59
|
+
|
|
60
|
+
output = capture_io do
|
|
61
|
+
NeetoTranslateCli::PayloadBuilder.stub :new, mock_payload_builder do
|
|
62
|
+
translator = NeetoTranslateCli::Translator.new(@options)
|
|
63
|
+
translator.process!
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
assert_includes output.join, "Nothing to see here. You are all good."
|
|
68
|
+
mock_payload_builder.verify
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def test_cli_integration_with_custom_options
|
|
72
|
+
args = [
|
|
73
|
+
"--frontend", "custom/frontend",
|
|
74
|
+
"--backend", "custom/backend",
|
|
75
|
+
"--defaults", "ja,ko",
|
|
76
|
+
"--repo", "neetozone/custom-repo"
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
mock_translator = Minitest::Mock.new
|
|
80
|
+
mock_translator.expect :process!, nil
|
|
81
|
+
|
|
82
|
+
NeetoTranslateCli::Translator.stub :new, mock_translator do
|
|
83
|
+
cli = NeetoTranslateCli::CLI.new(args)
|
|
84
|
+
cli.run
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
mock_translator.verify
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def test_api_integration_with_real_connection
|
|
91
|
+
# This test would require a real API endpoint or a mock server
|
|
92
|
+
# For now, we'll test the connection setup
|
|
93
|
+
api = NeetoTranslateCli::Api.new
|
|
94
|
+
|
|
95
|
+
# Test default URL
|
|
96
|
+
ENV.delete("NEETO_TRANSLATE_URL")
|
|
97
|
+
connection = api.send(:connection)
|
|
98
|
+
assert_equal "https://translate.neeto.com", connection.url_prefix.to_s.chomp("/")
|
|
99
|
+
|
|
100
|
+
# Test custom URL
|
|
101
|
+
ENV["NEETO_TRANSLATE_URL"] = "https://custom.translate.com"
|
|
102
|
+
api = NeetoTranslateCli::Api.new
|
|
103
|
+
connection = api.send(:connection)
|
|
104
|
+
assert_equal "https://custom.translate.com", connection.url_prefix.to_s.chomp("/")
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def test_payload_builder_integration_with_real_files
|
|
108
|
+
# Test with actual fixture files
|
|
109
|
+
payload_builder = NeetoTranslateCli::PayloadBuilder.new(@options)
|
|
110
|
+
payload = payload_builder.process!
|
|
111
|
+
|
|
112
|
+
# Verify payload structure
|
|
113
|
+
assert payload.key?(:frontend)
|
|
114
|
+
assert payload.key?(:backend)
|
|
115
|
+
assert payload.key?(:metadata)
|
|
116
|
+
|
|
117
|
+
# Verify frontend data
|
|
118
|
+
assert payload[:frontend].key?(:en)
|
|
119
|
+
assert payload[:frontend].key?(:missing_keys)
|
|
120
|
+
refute_empty payload[:frontend][:en]
|
|
121
|
+
|
|
122
|
+
# Verify backend data
|
|
123
|
+
assert payload[:backend].key?(:en)
|
|
124
|
+
assert payload[:backend].key?(:missing_keys)
|
|
125
|
+
refute_empty payload[:backend][:en]
|
|
126
|
+
|
|
127
|
+
# Verify metadata
|
|
128
|
+
assert_equal "test-repo", payload[:metadata][:repo]
|
|
129
|
+
assert_equal "test/fixtures/frontend", payload[:metadata][:frontend]
|
|
130
|
+
assert_equal "test/fixtures/backend", payload[:metadata][:backend]
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def test_error_handling_in_integration
|
|
134
|
+
# Test what happens when files don't exist
|
|
135
|
+
bad_options = @options.merge(frontend: "nonexistent/path")
|
|
136
|
+
|
|
137
|
+
assert_raises Errno::ENOENT do
|
|
138
|
+
payload_builder = NeetoTranslateCli::PayloadBuilder.new(bad_options)
|
|
139
|
+
payload_builder.process!
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
@@ -5,7 +5,8 @@ class NeetoTranslateCli::PayloadBuilderTest < Minitest::Test
|
|
|
5
5
|
@options = {
|
|
6
6
|
frontend: "test/fixtures/frontend",
|
|
7
7
|
backend: "test/fixtures/backend",
|
|
8
|
-
default_languages: %w[es de]
|
|
8
|
+
default_languages: %w[es de],
|
|
9
|
+
repo: "test-repo"
|
|
9
10
|
}
|
|
10
11
|
@payload_builder = NeetoTranslateCli::PayloadBuilder.new(@options)
|
|
11
12
|
@payload = @payload_builder.process!
|
|
@@ -48,6 +49,127 @@ class NeetoTranslateCli::PayloadBuilderTest < Minitest::Test
|
|
|
48
49
|
assert_equal es_missing_keys, @payload.dig(:backend, :missing_keys, "es").sort
|
|
49
50
|
end
|
|
50
51
|
|
|
52
|
+
def test_no_new_changes_with_empty_missing_keys
|
|
53
|
+
payload = {
|
|
54
|
+
frontend: { missing_keys: { "es" => [], "de" => [] } },
|
|
55
|
+
backend: { missing_keys: { "es" => [], "de" => [] } }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
assert @payload_builder.no_new_changes?(payload)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def test_no_new_changes_with_frontend_changes
|
|
62
|
+
payload = {
|
|
63
|
+
frontend: { missing_keys: { "es" => ["key1"], "de" => [] } },
|
|
64
|
+
backend: { missing_keys: { "es" => [], "de" => [] } }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
refute @payload_builder.no_new_changes?(payload)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def test_no_new_changes_with_backend_changes
|
|
71
|
+
payload = {
|
|
72
|
+
frontend: { missing_keys: { "es" => [], "de" => [] } },
|
|
73
|
+
backend: { missing_keys: { "es" => [], "de" => ["key1"] } }
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
refute @payload_builder.no_new_changes?(payload)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def test_metadata_in_payload
|
|
80
|
+
assert_equal @options[:repo], @payload[:metadata][:repo]
|
|
81
|
+
assert_equal @options[:frontend], @payload[:metadata][:frontend]
|
|
82
|
+
assert_equal @options[:backend], @payload[:metadata][:backend]
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def test_languages_excludes_english
|
|
86
|
+
languages = @payload_builder.send(:languages)
|
|
87
|
+
|
|
88
|
+
refute_includes languages, "en"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def test_languages_includes_default_and_project_languages
|
|
92
|
+
languages = @payload_builder.send(:languages)
|
|
93
|
+
|
|
94
|
+
assert_includes languages, "es"
|
|
95
|
+
assert_includes languages, "de"
|
|
96
|
+
assert_includes languages, "jp"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def test_flatten_hash_with_nested_structure
|
|
100
|
+
nested_hash = {
|
|
101
|
+
"common" => {
|
|
102
|
+
"buttons" => {
|
|
103
|
+
"save" => "Save",
|
|
104
|
+
"cancel" => "Cancel"
|
|
105
|
+
},
|
|
106
|
+
"messages" => {
|
|
107
|
+
"success" => "Success"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
expected = {
|
|
113
|
+
"common.buttons.save" => "Save",
|
|
114
|
+
"common.buttons.cancel" => "Cancel",
|
|
115
|
+
"common.messages.success" => "Success"
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
assert_equal expected, @payload_builder.send(:flatten_hash, nested_hash)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def test_flatten_hash_with_symbol_keys
|
|
122
|
+
nested_hash = {
|
|
123
|
+
common: {
|
|
124
|
+
buttons: {
|
|
125
|
+
save: "Save"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
expected = {
|
|
131
|
+
"common.buttons.save" => "Save"
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
assert_equal expected, @payload_builder.send(:flatten_hash, nested_hash)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def test_find_missing_keys_for_nonexistent_file
|
|
138
|
+
# Test with a language that doesn't have a file
|
|
139
|
+
missing_keys = @payload_builder.send(:find_missing_keys_for, :frontend)
|
|
140
|
+
|
|
141
|
+
assert_includes missing_keys.keys, "de"
|
|
142
|
+
assert_equal @payload_builder.send(:en_json_flattened).keys, missing_keys["de"]
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def test_find_missing_keys_for_existing_file
|
|
146
|
+
# Test with a language that has a file
|
|
147
|
+
missing_keys = @payload_builder.send(:find_missing_keys_for, :frontend)
|
|
148
|
+
|
|
149
|
+
assert_includes missing_keys.keys, "es"
|
|
150
|
+
# Should have some missing keys since es.json exists but is incomplete
|
|
151
|
+
refute_empty missing_keys["es"]
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def test_updated_keys_initialization_with_no_commit
|
|
155
|
+
# Mock git command to return empty string (no commit found)
|
|
156
|
+
@payload_builder.stub :git_commit_id, "" do
|
|
157
|
+
payload_builder = NeetoTranslateCli::PayloadBuilder.new(@options)
|
|
158
|
+
assert_equal({ frontend: [], backend: [] }, payload_builder.updated_keys)
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def test_updated_keys_initialization_with_commit
|
|
163
|
+
# Mock git command to return a commit ID
|
|
164
|
+
@payload_builder.stub :git_commit_id, "565b43e" do
|
|
165
|
+
# Mock git show commands to return previous content
|
|
166
|
+
Object.stub :`, "{}" do
|
|
167
|
+
payload_builder = NeetoTranslateCli::PayloadBuilder.new(@options)
|
|
168
|
+
assert_equal({ frontend: [], backend: [] }, payload_builder.updated_keys)
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
51
173
|
private
|
|
52
174
|
|
|
53
175
|
def flatten_hash(hash, prefix = nil)
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
class NeetoTranslateCli::TranslatorTest < Minitest::Test
|
|
4
|
+
def setup
|
|
5
|
+
@options = {
|
|
6
|
+
frontend: "test/fixtures/frontend",
|
|
7
|
+
backend: "test/fixtures/backend",
|
|
8
|
+
default_languages: %w[es de],
|
|
9
|
+
repo: "test-repo"
|
|
10
|
+
}
|
|
11
|
+
@translator = NeetoTranslateCli::Translator.new(@options)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_initialization
|
|
15
|
+
assert_instance_of NeetoTranslateCli::Api, @translator.api
|
|
16
|
+
assert_equal @options, @translator.options
|
|
17
|
+
assert_nil @translator.job_id
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_process_calls_translate
|
|
21
|
+
mock_payload_builder = Minitest::Mock.new
|
|
22
|
+
mock_payload = { frontend: { missing_keys: { "es" => [] } }, backend: { missing_keys: { "es" => [] } } }
|
|
23
|
+
mock_payload_builder.expect :process!, mock_payload
|
|
24
|
+
mock_payload_builder.expect :no_new_changes?, true, [mock_payload]
|
|
25
|
+
|
|
26
|
+
mock_api = Minitest::Mock.new
|
|
27
|
+
|
|
28
|
+
NeetoTranslateCli::PayloadBuilder.stub :new, mock_payload_builder do
|
|
29
|
+
NeetoTranslateCli::Api.stub :new, mock_api do
|
|
30
|
+
translator = NeetoTranslateCli::Translator.new(@options)
|
|
31
|
+
translator.process!
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
mock_payload_builder.verify
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_process_with_no_changes_outputs_message
|
|
39
|
+
mock_payload_builder = Minitest::Mock.new
|
|
40
|
+
mock_payload = { frontend: { missing_keys: { "es" => [] } }, backend: { missing_keys: { "es" => [] } } }
|
|
41
|
+
mock_payload_builder.expect :process!, mock_payload
|
|
42
|
+
mock_payload_builder.expect :no_new_changes?, true, [mock_payload]
|
|
43
|
+
|
|
44
|
+
mock_api = Minitest::Mock.new
|
|
45
|
+
|
|
46
|
+
output = capture_io do
|
|
47
|
+
NeetoTranslateCli::PayloadBuilder.stub :new, mock_payload_builder do
|
|
48
|
+
NeetoTranslateCli::Api.stub :new, mock_api do
|
|
49
|
+
translator = NeetoTranslateCli::Translator.new(@options)
|
|
50
|
+
translator.process!
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
assert_includes output.join, "Nothing to see here. You are all good."
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def test_process_with_changes_calls_api
|
|
59
|
+
mock_payload_builder = Minitest::Mock.new
|
|
60
|
+
mock_payload = { frontend: { missing_keys: { "es" => ["key1"] } }, backend: { missing_keys: { "es" => [] } } }
|
|
61
|
+
mock_payload_builder.expect :process!, mock_payload
|
|
62
|
+
mock_payload_builder.expect :no_new_changes?, false, [mock_payload]
|
|
63
|
+
|
|
64
|
+
mock_response = Minitest::Mock.new
|
|
65
|
+
mock_response.expect :body, "Translation job submitted successfully"
|
|
66
|
+
|
|
67
|
+
mock_api = Minitest::Mock.new
|
|
68
|
+
mock_api.expect :translate!, mock_response, [mock_payload]
|
|
69
|
+
|
|
70
|
+
output = capture_io do
|
|
71
|
+
NeetoTranslateCli::PayloadBuilder.stub :new, mock_payload_builder do
|
|
72
|
+
NeetoTranslateCli::Api.stub :new, mock_api do
|
|
73
|
+
translator = NeetoTranslateCli::Translator.new(@options)
|
|
74
|
+
translator.process!
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
assert_includes output.join, "Translation job submitted successfully"
|
|
80
|
+
mock_api.verify
|
|
81
|
+
mock_response.verify
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def test_process_with_backend_changes_calls_api
|
|
85
|
+
mock_payload_builder = Minitest::Mock.new
|
|
86
|
+
mock_payload = { frontend: { missing_keys: { "es" => [] } }, backend: { missing_keys: { "es" => ["key1"] } } }
|
|
87
|
+
mock_payload_builder.expect :process!, mock_payload
|
|
88
|
+
mock_payload_builder.expect :no_new_changes?, false, [mock_payload]
|
|
89
|
+
|
|
90
|
+
mock_response = Minitest::Mock.new
|
|
91
|
+
mock_response.expect :body, "Translation job submitted successfully"
|
|
92
|
+
|
|
93
|
+
mock_api = Minitest::Mock.new
|
|
94
|
+
mock_api.expect :translate!, mock_response, [mock_payload]
|
|
95
|
+
|
|
96
|
+
output = capture_io do
|
|
97
|
+
NeetoTranslateCli::PayloadBuilder.stub :new, mock_payload_builder do
|
|
98
|
+
NeetoTranslateCli::Api.stub :new, mock_api do
|
|
99
|
+
translator = NeetoTranslateCli::Translator.new(@options)
|
|
100
|
+
translator.process!
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
assert_includes output.join, "Translation job submitted successfully"
|
|
106
|
+
mock_api.verify
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
class NeetoTranslateCli::VersionTest < Minitest::Test
|
|
4
|
+
def test_version_constant_exists
|
|
5
|
+
assert defined?(NeetoTranslateCli::VERSION)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def test_version_is_string
|
|
9
|
+
assert_instance_of String, NeetoTranslateCli::VERSION
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_version_follows_semantic_versioning
|
|
13
|
+
version = NeetoTranslateCli::VERSION
|
|
14
|
+
assert_match(/\A\d+\.\d+\.\d+\z/, version, "Version should follow semantic versioning format (x.y.z)")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_version_is_not_empty
|
|
18
|
+
refute_empty NeetoTranslateCli::VERSION
|
|
19
|
+
end
|
|
20
|
+
end
|
data/test/test_helper.rb
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative "../lib/neeto_translate_cli/cli"
|
|
4
|
+
require_relative "../lib/neeto_translate_cli/version"
|
|
5
|
+
require_relative "../lib/neeto_translate_cli/api"
|
|
6
|
+
require_relative "../lib/neeto_translate_cli/payload_builder"
|
|
7
|
+
require_relative "../lib/neeto_translate_cli/translator"
|
|
4
8
|
|
|
5
9
|
require "minitest/autorun"
|
|
10
|
+
require "minitest/mock"
|
|
6
11
|
require "pry-byebug"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: neeto-translate-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Abhay V Ashokan
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-07-
|
|
11
|
+
date: 2025-07-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -49,7 +49,12 @@ files:
|
|
|
49
49
|
- test/fixtures/frontend/en.json
|
|
50
50
|
- test/fixtures/frontend/es.json
|
|
51
51
|
- test/fixtures/frontend/jp.json
|
|
52
|
+
- test/neeto_translate_cli/api_test.rb
|
|
53
|
+
- test/neeto_translate_cli/cli_test.rb
|
|
54
|
+
- test/neeto_translate_cli/integration_test.rb
|
|
52
55
|
- test/neeto_translate_cli/payload_builder_test.rb
|
|
56
|
+
- test/neeto_translate_cli/translator_test.rb
|
|
57
|
+
- test/neeto_translate_cli/version_test.rb
|
|
53
58
|
- test/test_helper.rb
|
|
54
59
|
homepage: https://github.com/neetozone/neeto-translate
|
|
55
60
|
licenses: []
|