77 "path/filepath"
88 "runtime"
99 "strings"
10+ "syscall"
1011 "testing"
1112)
1213
@@ -120,6 +121,23 @@ func TestNewInvalid(t *testing.T) {
120121 t .Errorf ("Should produce a 'not found' error, but got %[1]T (%[1]v)" , err )
121122 }
122123 })
124+ t .Run ("target dir is not a directory" , func (t * testing.T ) {
125+ tmpDir := t .TempDir ()
126+ parentPath := filepath .Join (tmpDir , "not-a-dir" )
127+ err := os .WriteFile (parentPath , nil , testMode ())
128+ if err != nil {
129+ t .Fatalf ("Error writing file: %v" , err )
130+ }
131+ fileName := filepath .Join (parentPath , "new-file.txt" )
132+ writer , err := New (fileName , testMode ())
133+ if writer != nil {
134+ t .Errorf ("Should not have created writer" )
135+ }
136+ // This should match the behavior of os.WriteFile, which returns a [os.PathError] with [syscall.ENOTDIR].
137+ if ! errors .Is (err , syscall .ENOTDIR ) {
138+ t .Errorf ("Should produce a 'not a directory' error, but got %[1]T (%[1]v)" , err )
139+ }
140+ })
123141 t .Run ("empty filename" , func (t * testing.T ) {
124142 writer , err := New ("" , testMode ())
125143 if writer != nil {
@@ -139,6 +157,24 @@ func TestNewInvalid(t *testing.T) {
139157 t .Errorf ("Should produce a 'cannot write to a directory' error, but got %[1]T (%[1]v)" , err )
140158 }
141159 })
160+ t .Run ("symlinked file" , func (t * testing.T ) {
161+ tmpDir := t .TempDir ()
162+ linkTarget := filepath .Join (tmpDir , "symlink-target" )
163+ if err := os .WriteFile (linkTarget , []byte ("orig content" ), testMode ()); err != nil {
164+ t .Fatal (err )
165+ }
166+ fileName := filepath .Join (tmpDir , "symlinked-file" )
167+ if err := os .Symlink (linkTarget , fileName ); err != nil {
168+ t .Fatal (err )
169+ }
170+ writer , err := New (fileName , testMode ())
171+ if writer != nil {
172+ t .Errorf ("Should not have created writer" )
173+ }
174+ if err == nil || err .Error () != "cannot write to a symbolic link directly" {
175+ t .Errorf ("Should produce a 'cannot write to a symbolic link directly' error, but got %[1]T (%[1]v)" , err )
176+ }
177+ })
142178}
143179
144180func TestWriteFile (t * testing.T ) {
@@ -178,7 +214,9 @@ func TestWriteFile(t *testing.T) {
178214 t .Run ("symlinked file" , func (t * testing.T ) {
179215 tmpDir := t .TempDir ()
180216 linkTarget := filepath .Join (tmpDir , "symlink-target" )
181- if err := os .WriteFile (linkTarget , []byte ("orig content" ), testMode ()); err != nil {
217+ originalContent := []byte ("original content" )
218+ fileMode := testMode ()
219+ if err := os .WriteFile (linkTarget , originalContent , fileMode ); err != nil {
182220 t .Fatal (err )
183221 }
184222 if err := os .Symlink (linkTarget , filepath .Join (tmpDir , "symlinked-file" )); err != nil {
@@ -188,15 +226,12 @@ func TestWriteFile(t *testing.T) {
188226 assertFileCount (t , tmpDir , origFileCount )
189227
190228 fileName := filepath .Join (tmpDir , "symlinked-file" )
191- fileContent := []byte ("new content" )
192- fileMode := testMode ()
193- if err := WriteFile (fileName , fileContent , fileMode ); err != nil {
194- t .Fatalf ("Error writing to file: %v" , err )
229+ err := WriteFile (fileName , []byte ("new content" ), testMode ())
230+ if err == nil || err .Error () != "cannot write to a symbolic link directly" {
231+ t .Errorf ("Should produce a 'cannot write to a symbolic link directly' error, but got %[1]T (%[1]v)" , err )
195232 }
196- assertFile (t , fileName , fileContent , fileMode )
233+ assertFile (t , linkTarget , originalContent , fileMode )
197234 assertFileCount (t , tmpDir , origFileCount )
198- // FIXME(thaJeztah): [os.Rename] does not resolve symlinks, so writing to a symlinked location replaces the link with a file.
199- // assertFile(t, linkTarget, fileContent, fileMode)
200235 })
201236 t .Run ("symlinked directory" , func (t * testing.T ) {
202237 tmpDir := t .TempDir ()
0 commit comments