files 0.1.0 → 0.2.0

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.
data/README.md CHANGED
@@ -2,11 +2,35 @@
2
2
 
3
3
  *a simple DSL for creating temporary files and directories*
4
4
 
5
- ## Usage
5
+ Ever want to create a whole bunch of files at once? Like when you're writing tests for a tool that processes files? The Files gem lets you cleanly specify those files and their contents inside your test code, instead of forcing you to create a fixture directory and check it in to your repo. It puts them in a temporary directory and cleans up when your test is done.
6
+
7
+ ## Usage (mixin mode)
8
+
9
+ The mixin mode is a fairly clean API, suitable for use in unit tests. After `include Files` you can call `file` or `dir` to make a temporary file or directory; it'll put them into a new temp dir that is removed on process exit. It also saves a reference to this directory inside an instance variable named `@files` so you can't use that name for your own instance variables.
10
+
11
+ require "files"
12
+ include Files
13
+
14
+ file "hello.txt" # creates file "hello.txt" containing "contents of hello.txt"
15
+
16
+ dir "web" do # creates directory "web"
17
+ file "snippet.html", # creates file "web/snippet.html"...
18
+ "<h1>Fix this!</h1>" # ...containing "<h1>Fix this!</h1>"
19
+ dir "img" do # creates directory "web/img"
20
+ file File.new("data/hello.png") # containing a copy of hello.png
21
+ file "hi.png", File.new("data/hello.png") # and a copy of hello.png named hi.png
22
+ end
23
+ end
24
+
25
+ files.root # creates (or returns) the temporary directory
26
+
27
+ ## Usage (bare function mode)
28
+
29
+ In bare function mode, you call the `Files` method, which doesn't pollute the current object with a `@files` instance variable. It returns a string with the path to the root temp dir that you can use later.
6
30
 
7
31
  require "files"
8
32
 
9
- files = Files do # creates a temporary directory inside Dir.tmpdir
33
+ temp_dir = Files do # creates a temporary directory inside Dir.tmpdir
10
34
  file "hello.txt" # creates file "hello.txt" containing "contents of hello.txt"
11
35
  dir "web" do # creates directory "web"
12
36
  file "snippet.html", # creates file "web/snippet.html"...
@@ -16,24 +40,54 @@
16
40
  file "hi.png", File.new("data/hello.png") # and a copy of hello.png named hi.png
17
41
  end
18
42
  end
19
- end # returns a string with the path to the directory
43
+ end # "Files" returns a string with the path to the directory
20
44
 
21
- see `test/files_test.rb` for more examples
45
+
46
+ see `test/files_test.rb` for more usage examples
22
47
 
23
48
  ## Details
24
49
 
25
50
  * the directory will be removed at exit
26
51
  * unless you pass `:remove => false`
27
52
  * the directory name is based on the name of the source file you called Files from
53
+ * if the first argument to `file` is a String, then a new file is made
54
+ * the content of the new file is either a short, descriptive message, or whatever you passed as the second argument
55
+ * if the argument to `file` is a Ruby `File` object, then it copies the contents of the named file into the temporary location
28
56
 
29
57
  ## TODO
30
58
 
59
+ * test under Windows
31
60
  * :path option -- specifying the parent of the temporary dir (default: Dir.tmpdir)
32
- * take a hash
33
- * take a YAML file or string
34
- * emit a hash
35
- * emit a YAML file or string
36
- * support symlinks (?)
37
- * specify file mode
61
+ * take a hash or a YAML file or YAML string to specify the directory layout and contents
62
+ * emit a hash or a YAML file or string to serialize the directory layout and contents for later
38
63
  * copy an entire data dir
64
+ * support symlinks (?)
65
+ * specify file write mode (?)
39
66
  * play nice with FakeFS (possibly with a :fake option)
67
+ * global/default :remove option
68
+
69
+ ## Credits
70
+
71
+ Written by Alex Chaffee <http://alexchaffee.com> <mailto:alex@stinky.com> <http://github.com/alexch> [@alexch](http://twitter.com/alexch)
72
+
73
+ ## License
74
+
75
+ Copyright (C) 2012 Alex Chaffee
76
+
77
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
78
+ this software and associated documentation files (the "Software"), to deal in
79
+ the Software without restriction, including without limitation the rights to
80
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
81
+ of the Software, and to permit persons to whom the Software is furnished to do
82
+ so, subject to the following conditions:
83
+
84
+ The above copyright notice and this permission notice shall be included in all
85
+ copies or substantial portions of the Software.
86
+
87
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
88
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
89
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
90
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
91
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
92
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
93
+ SOFTWARE.
data/files.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
9
9
  s.email = ["alex@stinky.com"]
10
10
  s.homepage = ""
11
11
  s.summary = %q{a simple DSL for creating temporary files and directories}
12
- s.description = %q{Sometimes you want to create a whole bunch of files at once, like when you're testing a tool that processes a whole bunch of files. The Files gem lets you cleanly specify those files and their contents inside your test code, instead of making you create a fixture directory and check it in to your repo. It puts them in a temporary directory and cleans up when your test is done.}
12
+ s.description = %q{Ever want to create a whole bunch of files at once? Like when you're writing tests for a tool that processes files? The Files gem lets you cleanly specify those files and their contents inside your test code, instead of forcing you to create a fixture directory and check it in to your repo. It puts them in a temporary directory and cleans up when your test is done.}
13
13
 
14
14
  s.rubyforge_project = "files"
15
15
 
data/lib/files.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  require "files/version"
2
2
 
3
-
4
3
  module Files
4
+
5
+ # class methods
5
6
 
6
7
  def self.default_options level = 2
7
8
  {:remove => true, :name => called_from(level)}
@@ -18,11 +19,23 @@ module Files
18
19
  name = options[:name]
19
20
  path = File.join(Dir::tmpdir, "#{name}_#{Time.now.to_i}_#{rand(1000)}")
20
21
 
21
- files = Files.new path, block, options
22
-
23
- files.root
22
+ Files.new path, block, options
24
23
  end
25
24
 
25
+ # mixin methods
26
+ def files options = ::Files.default_options # todo: block
27
+ @files ||= ::Files.create(options)
28
+ end
29
+
30
+ def file *args, &block
31
+ files.file *args, &block
32
+ end
33
+
34
+ def dir *args, &block
35
+ files.dir *args, &block
36
+ end
37
+
38
+ # concrete class for creating files and dirs under a temporary directory
26
39
  class Files
27
40
 
28
41
  attr_reader :root
@@ -31,7 +44,8 @@ module Files
31
44
  @root = path
32
45
  @dirs = []
33
46
  dir path, &block
34
- at_exit {FileUtils.rm_rf(path) if File.exists?(path)} if options[:remove]
47
+ @dirs = [path]
48
+ at_exit {remove} if options[:remove]
35
49
  end
36
50
 
37
51
  def dir name, &block
@@ -62,6 +76,10 @@ module Files
62
76
  end
63
77
  end
64
78
 
79
+ def remove
80
+ FileUtils.rm_rf(@root) if File.exists?(@root)
81
+ end
82
+
65
83
  private
66
84
  def current
67
85
  @dirs.join('/')
@@ -71,5 +89,6 @@ module Files
71
89
  end
72
90
 
73
91
  def Files options = Files.default_options, &block
74
- Files.create options, &block
92
+ files = Files.create options, &block
93
+ files.root
75
94
  end
data/lib/files/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Files
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/test/files_test.rb CHANGED
@@ -5,21 +5,28 @@ here = File.dirname __FILE__
5
5
  $LOAD_PATH.unshift File.join(here, '..', 'lib')
6
6
  require "files"
7
7
 
8
- dir = Files.create do # creates a temporary directory inside Dir.tmpdir
9
- file "hello.txt" # creates file "hello.txt" containing "contents of hello.txt"
10
- dir "web" do # creates directory "web"
11
- file "snippet.html", # creates file "web/snippet.html"...
12
- "<h1>File under F for fantastic!</h1>" # ...containing "<h1>File under F for fantastic!</h1>"
13
- dir "img" do # creates directory "web/img"
14
- file File.new("#{here}/data/cheez_doing_it_wrong.jpg") # containing a copy of cheez_doing_it_wrong.jpg
15
- file "other.jpg", # and a different named file...
16
- File.new("#{here}/data/cheez_doing_it_wrong.jpg") # containing the content of cheez_doing_it_wrong.jpg
17
- end
8
+ ## Testing the Files object
9
+
10
+ files = Files.create # creates a temporary directory inside Dir.tmpdir
11
+
12
+ assert { files.root }
13
+
14
+ files.file "hello.txt" # creates file "hello.txt" containing "contents of hello.txt"
15
+ files.dir "web" do # creates directory "web"
16
+ file "snippet.html", # creates file "web/snippet.html", with content
17
+ "<h1>File under F for fantastic!</h1>"
18
+ dir "img" do # creates directory "web/img"
19
+ file File.new("#{here}/data/cheez_doing_it_wrong.jpg") # containing a copy of cheez_doing_it_wrong.jpg
20
+ file "other.jpg", # and a different named file...
21
+ File.new("#{here}/data/cheez_doing_it_wrong.jpg") # containing the content of cheez_doing_it_wrong.jpg
18
22
  end
19
23
  end
20
24
 
25
+ dir = files.root
21
26
  assert { dir.split('/').last =~ /^files_test/ }
22
27
 
28
+ assert { dir =~ /^#{Dir::tmpdir}/}
29
+
23
30
  assert { File.read("#{dir}/hello.txt") == "contents of hello.txt" }
24
31
  assert { File.read("#{dir}/web/snippet.html") == "<h1>File under F for fantastic!</h1>" }
25
32
  assert {
@@ -31,10 +38,19 @@ assert {
31
38
  File.read("#{here}/data/cheez_doing_it_wrong.jpg")
32
39
  }
33
40
 
41
+ files.remove
42
+ assert("remove removes the root dir and all contents") { !File.exist?(dir) }
43
+ assert("after remove, the object is bogus") do
44
+ rescuing { (files.file "uhoh.txt") }.is_a? Errno::ENOENT
45
+ end
46
+
47
+ ## Testing the Files method (which is the recommended public API)
48
+
34
49
  dir = Files do
35
50
  file "hello.txt"
36
51
  dir("web") { file "hello.html" }
37
52
  end
53
+ assert { dir }
38
54
  assert { File.read("#{dir}/hello.txt") == "contents of hello.txt" }
39
55
  assert { File.read("#{dir}/web/hello.html") == "contents of hello.html" }
40
56
  assert { dir.split('/').last =~ /^files_test/ }
@@ -72,18 +88,17 @@ dir = Files do
72
88
  end
73
89
  assert { File.exist? "#{dir}/a" and File.directory? "#{dir}/a"}
74
90
 
75
-
76
- # the file and dir methods return the path, suitable for saving into a predeclared local var
91
+ # the file and dir methods return the path, suitable for storing in a predeclared local var
77
92
  stuff = nil
78
93
  hello = nil
79
- dir = Files do
94
+ files_dir = Files do
80
95
  stuff = dir "stuff" do
81
96
  hello = file "hello.txt"
82
97
  end
83
98
  end
84
99
 
85
- assert { stuff == "#{dir}/stuff" }
86
- assert { hello == "#{dir}/stuff/hello.txt" }
100
+ assert { stuff == "#{files_dir}/stuff" }
101
+ assert { hello == "#{files_dir}/stuff/hello.txt" }
87
102
 
88
103
  dir_inside_do_block = nil
89
104
  dir = Files do
@@ -95,3 +110,41 @@ end
95
110
  assert("sets the current directory inside the Files block") { File.basename(dir_inside_do_block) == File.basename(dir) }
96
111
  # note that we can't just compare the full paths because some OS's hard link their temp dir to different base paths
97
112
 
113
+ ## Testing the Mixin interface (which is the alternate public API)
114
+ class FilesMixinTest
115
+ include Files
116
+ def go
117
+ assert {@files.nil?}
118
+ file "foo.txt"
119
+ assert("calling file creates an instance var") { @files and @files.root }
120
+ assert("the method 'files' returns the instance var") { @files.object_id == files.object_id }
121
+
122
+ assert("calling file creates a file") { File.exist?("#{@files.root}/foo.txt") }
123
+ assert("the created file contains a nice message") { File.read("#{@files.root}/foo.txt") == "contents of foo.txt" }
124
+
125
+ dir "bar" do
126
+ file "bar.txt"
127
+ assert("the current directory is set inside a dir block") { File.read("bar.txt") == "contents of bar.txt" }
128
+ dir "sub" do
129
+ file "sub.txt"
130
+ assert("the current directory is set inside a nested dir block") { File.read("sub.txt") == "contents of sub.txt" }
131
+ end
132
+ end
133
+ assert("a file created inside the dir block exists under the root dir") {
134
+ File.read("#{@files.root}/bar/bar.txt") == "contents of bar.txt"
135
+ }
136
+
137
+ subdir = dir "baz"
138
+ assert("the dir method creates the dir") { File.exist?("#{@files.root}/baz")}
139
+ assert("the dir method returns the created dir") { subdir == "#{@files.root}/baz"}
140
+ assert { File.directory?("#{@files.root}/baz")}
141
+
142
+ end
143
+ end
144
+ FilesMixinTest.new.go
145
+
146
+ # TODO: allow options to be set in mixin mode
147
+ # TODO: test options from function mode and mixin mode
148
+ # files = Files.create :dummy => true
149
+ # assert { files.options[:dummy] == true }
150
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: files
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,13 +9,13 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-14 00:00:00.000000000Z
12
+ date: 2012-01-24 00:00:00.000000000Z
13
13
  dependencies: []
14
- description: Sometimes you want to create a whole bunch of files at once, like when
15
- you're testing a tool that processes a whole bunch of files. The Files gem lets
16
- you cleanly specify those files and their contents inside your test code, instead
17
- of making you create a fixture directory and check it in to your repo. It puts them
18
- in a temporary directory and cleans up when your test is done.
14
+ description: Ever want to create a whole bunch of files at once? Like when you're
15
+ writing tests for a tool that processes files? The Files gem lets you cleanly specify
16
+ those files and their contents inside your test code, instead of forcing you to
17
+ create a fixture directory and check it in to your repo. It puts them in a temporary
18
+ directory and cleans up when your test is done.
19
19
  email:
20
20
  - alex@stinky.com
21
21
  executables: []
@@ -45,7 +45,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
45
45
  version: '0'
46
46
  segments:
47
47
  - 0
48
- hash: -255388511158483173
48
+ hash: -1401824793539482884
49
49
  required_rubygems_version: !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
@@ -54,7 +54,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
54
54
  version: '0'
55
55
  segments:
56
56
  - 0
57
- hash: -255388511158483173
57
+ hash: -1401824793539482884
58
58
  requirements: []
59
59
  rubyforge_project: files
60
60
  rubygems_version: 1.8.6