require "spec_helper" describe "BPM::Package class" do it "should create from_spec" it "should tell if package root" do BPM::Package.is_package_root?(fixtures('packages', 'backbone')).should be_true BPM::Package.is_package_root?(fixtures('projects', 'hello_world')).should be_false BPM::Package.is_package_root?(fixtures('packages', 'non_existent')).should be_false end end describe BPM::Package do it "should have 'lib' as default lib_path'" do subject.send(:lib_path).should == 'lib' end it "should have 'tests' as default tests_path'" do subject.send(:tests_path).should == 'tests' end end describe BPM::Package, "#to_spec" do let(:email) { "user@example.com" } before do FileUtils.mkdir_p(home("core-test", "lib")) FileUtils.mkdir_p(home("core-test", "resources")) FileUtils.mkdir_p(home("core-test", "tests")) cd home('core-test') end subject do package = BPM::Package.new(nil, :email => email) package.json_path = package_fixture("core-test", "package.json") if spec = package.to_spec spec else puts "Errors: #{package.errors}" nil end end def expand_sort(files) files.map { |f| File.expand_path(f) }.sort end it "transforms the name" do subject.name.should == "core-test" end it "transforms the version" do subject.version.should == LibGems::Version.new("0.4.9") end it "transforms the author" do subject.authors.should == ["Charles Jolley"] end it "transforms the email" do subject.email.should == email end it "transforms the homepage" do subject.homepage.should == "https://github.com/strobecorp/core-test" end it "transforms the description" do subject.description.should == "Flexible testing library for JavaScript." end it "transforms the description" do subject.summary.should == "A fully featured asynchronous testing library for JavaScript, compatible with other frameworks." end it "transforms the dependencies" do subject.dependencies.map{|d| [d.name, d.requirement]}.should == [["ivory", "= 0.0.1"], ["optparse", "= 1.0.1"]] end it "packs metadata into requirements" do metadata = JSON.parse(subject.requirements.first) metadata["licenses"].should == [ {"type" => "MIT", "url" => "https://github.com/strobecorp/core-test/raw/master/LICENSE"} ] metadata["engines"].should == ["browser", "all"] metadata["main"].should == "./lib/main" metadata["bin"].should == {"cot" => "./bin/cot"} end it "expands paths from the directories and bpm:build" do others = ["tmp/blah.js", "tmp/whee.txt"] files = ["bin/cot", "lib/main.js", "lib/core.js", "lib/test.js", "package.json", "resources/additions.css", "resources/runner.css", "index.html", "extras/extra_file.html"] test_files = ["tests/apis/core-test.js", "tests/system/test/assert-test.js"] FileUtils.mkdir_p(["bin/", "resources/", "lib/", "tests/apis", "tests/system/test", "tmp/", "extras/"]) FileUtils.touch(files + test_files + others) expand_sort(subject.files).should == expand_sort(files + test_files) expand_sort(subject.test_files).should == expand_sort(test_files) end it "hacks the file name to return .bpkg" do subject.file_name.should == "core-test-0.4.9.bpkg" end it "sets the rubyforge_project to appease older versions of rubygems" do subject.rubyforge_project.should == "bpm" end end describe BPM::Package, "#to_s" do let(:email) { "user@example.com" } subject do package = BPM::Package.new package_fixture('core-test') package.valid? package end it "gives the name and version" do subject.full_name.should == "core-test-0.4.9" end end describe BPM::Package, "converting" do before do cd(home) end subject do package = BPM::Package.new package.fill_from_gemspec(fixtures('gems', "core-test-0.4.9.bpkg")) package.as_json end it "can recreate the same package.json from the package" do # These don't come out in the same order actual = Hash[subject.sort] expected = Hash[JSON.parse(File.read(package_fixture("core-test", "package.json"))).sort].reject{|k,v| v.empty? } actual.should == expected end end describe BPM::Package, "validating" do before do FileUtils.mkdir_p home('core-test') cd home('core-test') end subject { BPM::Package.new } shared_examples_for "a good parser" do it "had a problem parsing package.json" do lambda { subject.load_json }.should raise_error end end context "with a blank file" do before do FileUtils.touch("package.json") subject.json_path = "package.json" end it_should_behave_like "a good parser" end context "with bad json" do before do File.open("package.json", "w") do |f| f.write "---bad json---" end subject.json_path = "package.json" end it_should_behave_like "a good parser" end context "json can't be read" do before do FileUtils.cp package_fixture("core-test", "package.json"), "." FileUtils.chmod 0000, "package.json" subject.json_path = "package.json" end it_should_behave_like "a good parser" end context "json can't be found" do before do subject.json_path = "package.json" end it_should_behave_like "a good parser" end end describe BPM::Package, "validation errors" do let(:email) { "user@example.com" } before do FileUtils.mkdir_p home("core-test", "lib") FileUtils.mkdir_p home("core-test", "tests") cd home("core-test") end subject do BPM::Package.new(nil, :email => email) end def write_package path = home("core-test", "package.json") package = JSON.parse(File.read(package_fixture("core-test","package.json"))) yield package File.open(path, "w") do |file| file.write package.to_json end subject.json_path = path end %w[name summary version].each do |field| it "is invalid without a #{field} field" do write_package do |package| package.delete(field) end subject.should have_error("Package requires a '#{field}' field") end end it "is invalid without a proper version number" do write_package do |package| package["version"] = "bad" end subject.should have_error("Malformed version number string bad") end it "is valid without specifying a test directory" do write_package do |package| package["directories"].delete("tests") end subject.should be_valid subject.to_spec.test_files.should == [] end it "is valid and has files without specifying bin" do write_package do |package| package.delete("bin") end subject.should be_valid subject.to_spec.files.should == ["package.json"] end %w(lib tests).each do |dir| it "is invalid if #{dir} points to a file" do FileUtils.touch(home("core-test", "somefile")) write_package do |package| package["directories"][dir] = "./somefile" end subject.should have_error("'./somefile', specified for #{dir} directory, is not a directory") end it "is invalid with a #{dir} directory that doesn't exist" do write_package do |package| package["directories"][dir] = "nope" end subject.should have_error("'nope', specified for #{dir} directory, is not a directory") end it "is valid with a #{dir} directory that exists" do FileUtils.mkdir_p(home("core-test", "somewhere", "else")) write_package do |package| package["directories"][dir] = "./somewhere/else" end subject.should be_valid end end it "is valid with a lib directory array" do FileUtils.mkdir_p(home("core-test", "vendor", "lib")) write_package do |package| package["directories"]["lib"] = ["./lib", "./vendor/lib"] end subject.valid? subject.should be_valid end it "is invalid if any lib directories don't exist" do write_package do |package| package["directories"]["lib"] = ["./lib", "./fake"] end subject.should have_error "'./fake', specified for lib directory, is not a directory" end it "is valid if the lib directory array is empty" do # This provides a mean to make a libless package # Since this is rare, you have to explicitly specify an empty array write_package do |package| package["directories"]["lib"] = [] end subject.should be_valid end end describe BPM::Package, 'InvalidPackagePathError' do it "should raise exception when loading invalid JSON" do package = BPM::Package.new(package_fixture('invalid_json')) lambda { package.load_json }.should raise_error(BPM::InvalidPackageError) end it "should raise exception when loading a package with no package.json" do FileUtils.mkdir_p home('empty_package') package = BPM::Package.new home('empty_package') lambda { package.load_json }.should raise_error(BPM::InvalidPackageError) end it "should raise exception when loading a package whose name does not package the one in the package.json" do goto_home FileUtils.cp_r package_fixture('jquery'), 'jquery2' package = BPM::Package.new home('jquery2') lambda { package.load_json }.should raise_error(BPM::InvalidPackagePathError) end it "should not raise exception for standalone packages" do goto_home FileUtils.cp_r package_fixture('jquery'), 'jquery2' package = BPM::Package.new home('jquery2'), :standalone => true lambda { package.load_json }.should_not raise_error end end describe BPM::Package, "templates" do subject do package = BPM::Package.new(package_fixture("custom_generator")) package.load_json package end it "should have project template" do subject.template_path('project').should == package_fixture("custom_generator", "templates", "project").to_s end end