diff --git a/Guardfile b/Guardfile new file mode 100644 index 0000000..27e1c2c --- /dev/null +++ b/Guardfile @@ -0,0 +1,16 @@ +guard :rspec, cmd: 'bundle exec rspec' do + require 'guard/rspec/dsl' + dsl = Guard::RSpec::Dsl.new(self) + + # Feel free to open issues for suggestions and improvements + + # RSpec files + rspec = dsl.rspec + watch(rspec.spec_helper) { rspec.spec_dir } + watch(rspec.spec_support) { rspec.spec_dir } + watch(rspec.spec_files) + + # Ruby files + ruby = dsl.ruby + dsl.watch_spec_files_for(ruby.lib_files) +end diff --git a/README.md b/README.md index 43bf4ab..abf62e8 100644 --- a/README.md +++ b/README.md @@ -17,11 +17,11 @@ that are deliberately layed out in a symmetric form. To use ```laser-cutter``` you need to have a recent version of ruby interpreter, install it as a gem, and use command line to generate PDFs. -[Make-A-Box](http://makeabox.io) is a online web application that uses ```laser-cutter``` library +**[MakeABox.io](http://makeabox.io)** is a online web application that uses ```laser-cutter``` library and provides a straight-forward user interface for generating PDF designs without the need to install the gem or use command line. -Use whatever suites you better. +Use whatever suites you better. ### Design Goals @@ -186,7 +186,7 @@ laser-cutter -z 1x1.5x2/0.125/0.125 -O -o box.pdf ## Contributing -1. Fork it ( https://github.com/[my-github-username]/laser-cutter/fork ) +1. Fork it ( https://github.com/kigster/laser-cutter/fork ) 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit your changes (`git commit -am 'Add some feature'`) 4. Push to the branch (`git push origin my-new-feature`) diff --git a/laser-cutter.gemspec b/laser-cutter.gemspec index 874dd43..c3c42a4 100644 --- a/laser-cutter.gemspec +++ b/laser-cutter.gemspec @@ -20,9 +20,12 @@ Gem::Specification.new do |spec| spec.add_dependency 'prawn' spec.add_dependency 'hashie' - spec.add_dependency 'colored' + spec.add_dependency 'colored2' spec.add_development_dependency 'bundler' spec.add_development_dependency 'rake' spec.add_development_dependency 'rspec' + spec.add_development_dependency 'rspec-its' + spec.add_development_dependency 'guard' + spec.add_development_dependency 'guard-rspec' end diff --git a/lib/laser-cutter/cli/opt_parser.rb b/lib/laser-cutter/cli/opt_parser.rb index 27a7cfd..4f2175f 100644 --- a/lib/laser-cutter/cli/opt_parser.rb +++ b/lib/laser-cutter/cli/opt_parser.rb @@ -1,5 +1,5 @@ require 'optparse' -require 'colored' +require 'colored2' require 'json' require 'hashie/mash' require 'laser-cutter' diff --git a/lib/laser-cutter/configuration.rb b/lib/laser-cutter/configuration.rb index d274f38..df9efbd 100644 --- a/lib/laser-cutter/configuration.rb +++ b/lib/laser-cutter/configuration.rb @@ -1,71 +1,82 @@ require 'hashie/mash' +require 'hashie/extensions/stringify_keys' require 'prawn/measurement_extensions' require 'pdf/core/page_geometry' module Laser module Cutter - class MissingOption < RuntimeError; end - class ZeroValueNotAllowed < MissingOption; end + class MissingOption < RuntimeError; + end + class ZeroValueNotAllowed < MissingOption; + end class UnitsConverter def self.mm2in value 0.039370079 * value end + def self.in2mm value 25.4 * value end end class Configuration < Hashie::Mash + DEFAULTS = { - units: 'in', - page_layout: 'portrait', - metadata: true + units: 'in', + page_layout: 'portrait', + metadata: true } UNIT_SPECIFIC_DEFAULTS = { - 'in' => { - kerf: 0.0024, # smallest kerf for thin material, usually it's more than that. - margin: 0.125, - padding: 0.1, - stroke: 0.001, - } + 'in' => { + kerf: 0.0024, # smallest kerf for thin material, usually it's more than that. + margin: 0.125, + padding: 0.1, + stroke: 0.001, + } } - UNIT_SPECIFIC_DEFAULTS['mm'] = UNIT_SPECIFIC_DEFAULTS['in'].map{|k, v| [k, UnitsConverter.in2mm(v)] }.to_h + UNIT_SPECIFIC_DEFAULTS['mm'] = UNIT_SPECIFIC_DEFAULTS['in'].map {|k, v| [k, UnitsConverter.in2mm(v)]}.to_h SIZE_REGEXP = /[\d\.]+x[\d\.]+x[\d\.]+\/[\d\.]+(\/[\d\.]+)?/ - FLOATS = %w(width height depth thickness notch margin padding stroke kerf) - NON_ZERO = %w(width height depth thickness stroke) - REQUIRED = %w(width height depth thickness notch file) + FLOATS = %w[width height depth thickness notch margin padding stroke kerf] + NON_ZERO = %w[width height depth thickness stroke] + REQUIRED = %w[width height depth thickness notch file] def initialize(options = {}) - options.delete_if { |k, v| v.nil? } - if options['units'] && !UNIT_SPECIFIC_DEFAULTS.keys.include?(options['units']) - options.delete('units') - end - self.merge!(DEFAULTS) - self.merge!(options) - if self['size'] && self['size'] =~ SIZE_REGEXP - dim, self['thickness'], self['notch'] = self['size'].split('/') - self['width'], self['height'], self['depth'] = dim.split('x') - delete('size') + options = Hashie::Extensions::StringifyKeys.stringify_keys(options) + options.delete_if {|k, v| v.nil?} + options.delete('units') if options['units'] && !Hashie::Extensions::StringifyKeys.stringify_keys(UNIT_SPECIFIC_DEFAULTS).keys.include?(options['units']) + + options = Hashie::Extensions::StringifyKeys.stringify_keys(DEFAULTS).merge(options) + + if options['size'] && options['size'] =~ SIZE_REGEXP + dim, options['thickness'], options['notch'] = options['size'].split('/') + options['width'], options['height'], options['depth'] = dim.split('x') + options.delete('size') end - FLOATS.each do |k| - self[k] = self[k].to_f if (self[k] && self[k].is_a?(String)) + + FLOATS.each {|k| options[k] = options[k].to_f if options[k] && options[k].is_a?(String)} + + + options.merge!(Hashie::Extensions::StringifyKeys.stringify_keys(UNIT_SPECIFIC_DEFAULTS)[options['units']].merge(options)) + + if options['thickness'] && options['notch'].nil? + options['notch'] = (options['thickness'] * 3.0).round(5) end - self.merge!(UNIT_SPECIFIC_DEFAULTS[self['units']].merge(self)) - self['notch'] = (self['thickness'] * 3.0).round(5) if self['thickness'] && self['notch'].nil? + + super(options) end def validate! missing = [] - REQUIRED.each { |k| missing << k if self[k].nil? } + REQUIRED.each {|k| missing << k if self[k].nil?} raise MissingOption.new("#{missing.join(', ')} #{missing.size > 1 ? 'are' : 'is'} required, but missing.") unless missing.empty? zeros = [] - NON_ZERO.each { |k| zeros << k if self[k] == 0 } + NON_ZERO.each {|k| zeros << k if self[k] == 0} raise ZeroValueNotAllowed.new("#{zeros.join(', ')} #{zeros.size > 1 ? 'are' : 'is'} required, but is zero.") unless zeros.empty? end diff --git a/spec/box_spec.rb b/spec/box_spec.rb index 7d9a2b7..53cd416 100644 --- a/spec/box_spec.rb +++ b/spec/box_spec.rb @@ -1,40 +1,41 @@ -require_relative 'spec_helper' +require 'spec_helper' +require 'laser-cutter/box' -module Laser - module Cutter - describe Box do - let(:config) { {'width' => 50, 'height' => 60, 'depth' => 70, 'margin' => 5, 'padding' => 3, 'units' => 'mm'} } - let(:box1) { Box.new(config.merge('thickness' => 6, 'notch' => 10)) } - let(:box2) { Box.new(config.merge('thickness' => 6, )) } +RSpec.describe ::Laser::Cutter::Box do - context '#initialize' do - it 'should initialize with passed in parameters' do - expect(box1.w).to eq(50.0) - expect(box1.thickness).to eq(6.0) - expect(box1.notch_width).to eq(10.0) - end + context 'config #1' do + let(:config) { { 'width' => 50, 'height' => 60, 'depth' => 70, 'margin' => 5, 'padding' => 3, 'units' => 'mm' } } + let(:box1) { ::Laser::Cutter::Box.new(config.merge('thickness' => 6, 'notch' => 10)) } + let(:box2) { ::Laser::Cutter::Box.new(config.merge('thickness' => 6)) } - it 'should initialize with default notch' do - expect(box2.notch_width).to eq(70.0 / 5.0) - end + context '#initialize' do + it 'should initialize with passed in parameters' do + expect(box1.w).to eq(50.0) + expect(box1.thickness).to eq(6.0) + expect(box1.notch_width).to eq(10.0) end - context '#notches' do - before do - box1.generate_notches - box2.generate_notches - end - it 'should generate notches' do - expect(box1.notches).to_not be_nil - expect(box1.notches.size).to eql(368) - end + it 'should initialize with default notch' do + expect(box2.notch_width).to eq(70.0 / 5.0) + end + end - it 'should properly calculate enclosure' do - expect(box1.enclosure.to_a.flatten.map(&:round)).to eql([0,0, 232, 317]) - expect(box2.enclosure.to_a.flatten.map(&:round)).to eql([0,0, 232, 317]) - end + context '#notches' do + before do + box1.generate_notches + box2.generate_notches + end + it 'should generate notches' do + expect(box1.notches).to_not be_nil + expect(box1.notches.size).to eql(368) end + let(:dims) { [0, 0, 232, 317] } + it 'should properly calculate enclosure' do + expect(box1.enclosure.to_a.flatten.map(&:round)).to eql(dims) + expect(box2.enclosure.to_a.flatten.map(&:round)).to eql(dims) + end end end + end diff --git a/spec/configuration_spec.rb b/spec/configuration_spec.rb index f1414f5..64efa52 100644 --- a/spec/configuration_spec.rb +++ b/spec/configuration_spec.rb @@ -63,9 +63,10 @@ module Cutter end end context 'to inches' do - let(:opts) { {'size' => "20.0x30.0x40.0/5/5", 'margin' => '10.0', "units" => 'mm'} } + let(:opts) { { 'size' => '20.0x30.0x40.0/5/5', 'margin' => '10.0', 'units' => 'mm'} } it 'should be correct' do expect(config.width).to eql(20.0) + expect(config.units).to eql('mm') config.change_units('mm') expect(config.width).to eql(20.0) config.change_units('in') diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 96412a2..04eda97 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -10,8 +10,6 @@ require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) require 'laser-cutter' - - RSpec.configure do |config| #config.treat_symbols_as_metadata_keys_with_true_values = true config.run_all_when_everything_filtered = true