diff --git a/lib/budik.rb b/lib/budik.rb index c530308..98ae25a 100644 --- a/lib/budik.rb +++ b/lib/budik.rb @@ -19,7 +19,7 @@ #require './budik/devices.rb' #require './budik/player.rb' #require './budik/rng.rb' -#require './budik/sources.rb' +require './lib/budik/sources' require './lib/budik/version' module Budik diff --git a/lib/budik/config/lang/en.yml b/lib/budik/config/lang/en.yml index e6bd98b..d005d98 100644 --- a/lib/budik/config/lang/en.yml +++ b/lib/budik/config/lang/en.yml @@ -1,3 +1,5 @@ lang: "en" # Do not remove this line. config: example: "This is an example string." +sources: + invalid_item: "Item %1 is invalid." diff --git a/lib/budik/config/templates/sources_example.yml b/lib/budik/config/templates/sources_example.yml new file mode 100644 index 0000000..6d7da53 --- /dev/null +++ b/lib/budik/config/templates/sources_example.yml @@ -0,0 +1,24 @@ +--- +- "path" +- + - "path1" + - "path2" +- + name: "name" + path: "path" +- + name: "name" + category: ["category1", "subcategory1"] + path: "path" +- + name: "name" + category: ["category1", "subcategory2"] + path: ["path1", "path2"] +- + name: "name" + category: + - "category2" + - "subcategory1" + path: + - "path1" + - "path2" diff --git a/lib/budik/sources.rb b/lib/budik/sources.rb new file mode 100644 index 0000000..893df1b --- /dev/null +++ b/lib/budik/sources.rb @@ -0,0 +1,72 @@ +module Budik + class Sources + include Singleton + + def initialize + @sources = [] + end + + attr_accessor :sources + + def apply_mods(mods) + modified_sources = [] + + @sources.each do |source| + add = false + mods[:adds].each do |mod| + add = true if mod == (source[:category] & mod) + end + mods[:rms].each do |mod| + add = false if mod == (source[:category] & mod) + end + modified_sources << source if add + end + + @sources = modified_sources.uniq + end + + def parse(sources, mods = nil) + sources.each do |item| + if item.is_a? Array + normalized_item = { name: '', category: ['default'], path: []} + item.each do |subitem| + normalized_item[:name] += (subitem + ' + ') + normalized_item[:path] << subitem + end + 3.times { normalized_item[:name].chop! } + elsif item.is_a? Hash + normalized_item = {} + normalized_item[:name] = item['name'] + normalized_item[:category] = item['category'] ? item['category'] : ['default'] + normalized_item[:path] = item['path'] + elsif item.is_a? String + normalized_item = { name: item, category: ['default'], path: item } + else # TODO: test + fail Config.instance.lang.sources.invalid_item item.to_s + end + + @sources << normalized_item + end + + mods = (mods.is_a? String) ? parse_mods(mods) : mods + apply_mods(mods) if mods + end + + def parse_mods(mod_string) + parsed_mods = { adds: [], rms: [] } + + mods = mod_string.split(' ') + mods.each do |m| + mod = m.split('.') + if mod.first == '' + mod.shift + parsed_mods[:rms] << mod + else + parsed_mods[:adds] << mod + end + end + + return parsed_mods + end + end +end diff --git a/spec/lib/budik/sources_spec.rb b/spec/lib/budik/sources_spec.rb new file mode 100644 index 0000000..3302fb6 --- /dev/null +++ b/spec/lib/budik/sources_spec.rb @@ -0,0 +1,85 @@ +#require 'r18n-core' +require 'singleton' +require 'spec_helper' +require 'yaml' + +require 'budik/sources' + +describe Budik::Sources, '#apply_mods' do + it 'filters sources by applying modifiers' do + Budik::Sources.instance.parse(YAML.load_file('./lib/budik/config/templates/sources_example.yml')) + + mods = {adds: [['category1']], rms: [['subcategory1']]} + Budik::Sources.instance.apply_mods(mods) + sources_expected_result = [ + {name: 'name', + category: ['category1', 'subcategory2'], + path: ['path1', 'path2']} + ] + + expect(Budik::Sources.instance.sources).to eq sources_expected_result + Budik::Sources.instance.sources = [] + end +end + +describe Budik::Sources, '#parse' do + context 'without modifiers' do + it 'parses sources to program usable format' do + sources_example = YAML.load_file('./lib/budik/config/templates/sources_example.yml') + Budik::Sources.instance.parse(sources_example) + sources_expected_result = [ + {name: 'path', + category: ['default'], + path: 'path'}, + + {name: 'path1 + path2', + category: ['default'], + path: ['path1', 'path2']}, + + {name: 'name', + category: ['default'], + path: 'path'}, + + {name: 'name', + category: ['category1', 'subcategory1'], + path: 'path'}, + + {name: 'name', + category: ['category1', 'subcategory2'], + path: ['path1', 'path2']}, + + {name: 'name', + category: ['category2', 'subcategory1'], + path: ['path1', 'path2']} + ] + + expect(Budik::Sources.instance.sources).to eq sources_expected_result + Budik::Sources.instance.sources = [] + end + end + + context 'with modifiers' do + it 'parses sources to program usable format' do + mods_example = '.subcategory1 .default category1' + sources_example = YAML.load_file('./lib/budik/config/templates/sources_example.yml') + Budik::Sources.instance.parse(sources_example, mods_example) + sources_expected_result = [ + {name: 'name', + category: ['category1', 'subcategory2'], + path: ['path1', 'path2']} + ] + + expect(Budik::Sources.instance.sources).to eq sources_expected_result + Budik::Sources.instance.sources = [] + end + end +end + +describe Budik::Sources, '#parse_mods' do + it 'parses string with modifiers' do + parsed_mods = Budik::Sources.instance.parse_mods('a.b c.d.e .f .g.h i .j k.l .m.n.o') + expected_result = { adds: [['a', 'b'], ['c', 'd', 'e'], ['i'], ['k', 'l']], rms: [['f'], ['g', 'h'], ['j'], ['m', 'n', 'o']]} + + expect(parsed_mods).to eq expected_result + end +end