files 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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