1+ require 'spec_helper'
2+ require 'mini_i18n/cli'
3+ require 'csv'
4+ require 'tempfile'
5+
6+ RSpec . describe MiniI18n ::CLI do
7+ let ( :cli ) { described_class . new ( args ) }
8+
9+ describe '#run' do
10+ context 'with version command' do
11+ let ( :args ) { [ 'version' ] }
12+
13+ it 'prints the version' do
14+ expect { cli . run } . to output ( "#{ MiniI18n ::VERSION } \n " ) . to_stdout
15+ end
16+ end
17+
18+ context 'with help command' do
19+ let ( :args ) { [ 'help' ] }
20+
21+ it 'prints help information' do
22+ expect { cli . run } . to output ( /Usage: mi18n/ ) . to_stdout
23+ end
24+ end
25+
26+ context 'with no arguments' do
27+ let ( :args ) { [ ] }
28+
29+ it 'prints help information' do
30+ expect { cli . run } . to output ( /Usage: mi18n/ ) . to_stdout
31+ end
32+ end
33+
34+ context 'with unknown command' do
35+ let ( :args ) { [ 'unknown' ] }
36+
37+ it 'prints error and exits' do
38+ expect { cli . run } . to output ( /Unknown command: unknown/ ) . to_stdout
39+ expect { cli . run } . to raise_error ( SystemExit )
40+ end
41+ end
42+ end
43+
44+ describe 'with translation files' do
45+ let ( :temp_dir ) { Dir . mktmpdir }
46+
47+ before do
48+ # Create test translation files
49+ en_content = {
50+ 'en' => {
51+ 'hello' => 'Hello' ,
52+ 'nested' => { 'greeting' => 'Good morning' }
53+ }
54+ }
55+
56+ es_content = {
57+ 'es' => {
58+ 'hello' => 'Hola' ,
59+ 'nested' => { 'greeting' => '' }
60+ }
61+ }
62+
63+ File . write ( File . join ( temp_dir , 'en.yml' ) , en_content . to_yaml )
64+ File . write ( File . join ( temp_dir , 'es.yml' ) , es_content . to_yaml )
65+
66+ # Mock the glob pattern to find our test files
67+ allow ( Dir ) . to receive ( :glob ) . and_call_original
68+ allow ( Dir ) . to receive ( :glob ) . with ( 'config/locales/*.yml' ) . and_return ( [ ] )
69+ allow ( Dir ) . to receive ( :glob ) . with ( 'config/locales/*.yaml' ) . and_return ( [ ] )
70+ allow ( Dir ) . to receive ( :glob ) . with ( 'locales/*.yml' ) . and_return ( [
71+ File . join ( temp_dir , 'en.yml' ) ,
72+ File . join ( temp_dir , 'es.yml' )
73+ ] )
74+ end
75+
76+ after do
77+ FileUtils . rm_rf ( temp_dir )
78+ end
79+
80+ context 'with stats command' do
81+ let ( :args ) { [ 'stats' ] }
82+
83+ it 'shows translation statistics' do
84+ output = capture_stdout { cli . run }
85+
86+ expect ( output ) . to include ( 'Translation Statistics:' )
87+ expect ( output ) . to include ( 'Number of locales: 2' )
88+ expect ( output ) . to include ( 'Total unique keys: 2' )
89+ expect ( output ) . to include ( 'en: 2/2 keys (100.0% complete)' )
90+ expect ( output ) . to include ( 'es: 1/2 keys (50.0% complete)' )
91+ end
92+ end
93+
94+ context 'with missing command' do
95+ let ( :args ) { [ 'missing' ] }
96+
97+ it 'shows missing translation keys' do
98+ output = capture_stdout { cli . run }
99+
100+ expect ( output ) . to include ( "Missing keys for 'es' locale:" )
101+ expect ( output ) . to include ( 'nested.greeting' )
102+ end
103+ end
104+
105+ context 'with missing command and locale filter' do
106+ let ( :args ) { [ 'missing' , '--locale=es' ] }
107+
108+ it 'shows missing keys for specific locale' do
109+ output = capture_stdout { cli . run }
110+
111+ expect ( output ) . to include ( "Missing keys for 'es' locale:" )
112+ expect ( output ) . to include ( 'nested.greeting' )
113+ expect ( output ) . not_to include ( "Missing keys for 'en' locale:" )
114+ end
115+ end
116+
117+ context 'with export command' do
118+ let ( :temp_csv ) { Tempfile . new ( [ 'test' , '.csv' ] ) }
119+ let ( :args ) { [ 'export' , "--file=#{ temp_csv . path } " ] }
120+
121+ after do
122+ temp_csv . close
123+ temp_csv . unlink
124+ end
125+
126+ it 'exports translations to CSV' do
127+ output = capture_stdout { cli . run }
128+
129+ expect ( output ) . to include ( "Translations exported successfully to #{ temp_csv . path } " )
130+
131+ csv_content = CSV . read ( temp_csv . path , headers : true )
132+ expect ( csv_content . headers ) . to eq ( [ 'key' , 'en' , 'es' ] )
133+ expect ( csv_content . map ( &:to_h ) ) . to include (
134+ { 'key' => 'hello' , 'en' => 'Hello' , 'es' => 'Hola' }
135+ )
136+ end
137+ end
138+ end
139+
140+ private
141+
142+ def capture_stdout
143+ original_stdout = $stdout
144+ $stdout = StringIO . new
145+ yield
146+ $stdout. string
147+ ensure
148+ $stdout = original_stdout
149+ end
150+ end
0 commit comments