brief 0.0.5 → 1.0.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.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +71 -55
- data/README.md +149 -48
- data/Rakefile +15 -5
- data/bin/brief +15 -28
- data/brief.gemspec +17 -11
- data/examples/blog/brief.rb +54 -0
- data/examples/blog/docs/an-intro-to-brief.html.md +9 -0
- data/lib/.DS_Store +0 -0
- data/lib/brief/briefcase.rb +78 -0
- data/lib/brief/cli/change.rb +14 -0
- data/lib/brief/cli/init.rb +66 -0
- data/{spec/fixtures/generated/project_overview.json → lib/brief/cli/publish.rb} +0 -0
- data/lib/brief/cli/write.rb +0 -0
- data/lib/brief/configuration.rb +19 -115
- data/lib/brief/core_ext.rb +11 -0
- data/lib/brief/document/content_extractor.rb +33 -0
- data/lib/brief/document/front_matter.rb +20 -0
- data/lib/brief/document/rendering.rb +37 -0
- data/lib/brief/document.rb +43 -38
- data/lib/brief/document_mapper.rb +158 -0
- data/lib/brief/dsl.rb +42 -0
- data/lib/brief/model/definition.rb +117 -0
- data/lib/brief/model.rb +177 -0
- data/lib/brief/repository.rb +57 -0
- data/lib/brief/version.rb +1 -7
- data/lib/brief.rb +35 -40
- data/spec/fixtures/example/brief.rb +27 -0
- data/spec/fixtures/example/docs/concept.html.md +5 -0
- data/spec/fixtures/example/docs/epic.html.md +19 -0
- data/spec/fixtures/example/docs/persona.html.md +5 -0
- data/spec/fixtures/example/docs/release.html.md +7 -0
- data/spec/fixtures/example/docs/resource.html.md +5 -0
- data/spec/fixtures/example/docs/user_story.html.md +24 -0
- data/spec/fixtures/example/docs/wireframe.html.md +5 -0
- data/spec/fixtures/example/models/epic.rb +16 -0
- data/spec/lib/brief/briefcase_spec.rb +27 -0
- data/spec/lib/brief/document_spec.rb +14 -22
- data/spec/lib/brief/dsl_spec.rb +4 -15
- data/spec/lib/brief/model_spec.rb +84 -0
- data/spec/lib/brief/repository_spec.rb +60 -0
- data/spec/spec_helper.rb +12 -14
- data/spec/support/test_helpers.rb +0 -0
- data/tasks/brief/release.rake +0 -0
- metadata +120 -110
- data/.gitignore +0 -1
- data/Guardfile +0 -5
- data/examples/project_overview.md +0 -23
- data/lib/brief/cli/commands/config.rb +0 -40
- data/lib/brief/cli/commands/publish.rb +0 -27
- data/lib/brief/cli/commands/write.rb +0 -27
- data/lib/brief/formatters/base.rb +0 -12
- data/lib/brief/formatters/github_milestone_rollup.rb +0 -52
- data/lib/brief/git.rb +0 -19
- data/lib/brief/github/wiki.rb +0 -9
- data/lib/brief/github.rb +0 -141
- data/lib/brief/github_client/authentication.rb +0 -32
- data/lib/brief/github_client/client.rb +0 -86
- data/lib/brief/github_client/commands.rb +0 -5
- data/lib/brief/github_client/issue_labels.rb +0 -65
- data/lib/brief/github_client/issues.rb +0 -22
- data/lib/brief/github_client/milestone_issues.rb +0 -13
- data/lib/brief/github_client/organization_activity.rb +0 -9
- data/lib/brief/github_client/organization_issues.rb +0 -13
- data/lib/brief/github_client/organization_repositories.rb +0 -20
- data/lib/brief/github_client/organization_users.rb +0 -9
- data/lib/brief/github_client/repository_events.rb +0 -8
- data/lib/brief/github_client/repository_issue_events.rb +0 -9
- data/lib/brief/github_client/repository_issues.rb +0 -8
- data/lib/brief/github_client/repository_labels.rb +0 -18
- data/lib/brief/github_client/repository_milestones.rb +0 -9
- data/lib/brief/github_client/request.rb +0 -181
- data/lib/brief/github_client/request_wrapper.rb +0 -121
- data/lib/brief/github_client/response_object.rb +0 -50
- data/lib/brief/github_client/single_repository.rb +0 -9
- data/lib/brief/github_client/user_activity.rb +0 -16
- data/lib/brief/github_client/user_gists.rb +0 -9
- data/lib/brief/github_client/user_info.rb +0 -9
- data/lib/brief/github_client/user_issues.rb +0 -13
- data/lib/brief/github_client/user_organizations.rb +0 -9
- data/lib/brief/github_client/user_repositories.rb +0 -9
- data/lib/brief/github_client.rb +0 -43
- data/lib/brief/handlers/base.rb +0 -62
- data/lib/brief/handlers/github_issue.rb +0 -41
- data/lib/brief/handlers/github_milestone.rb +0 -37
- data/lib/brief/handlers/github_wiki.rb +0 -11
- data/lib/brief/line.rb +0 -69
- data/lib/brief/parser.rb +0 -354
- data/lib/brief/publisher/handler_manager.rb +0 -47
- data/lib/brief/publisher.rb +0 -142
- data/lib/brief/tree.rb +0 -43
- data/lib/core_ext.rb +0 -37
- data/spec/fixtures/front_end_tutorial.md +0 -33
- data/spec/fixtures/generator_dsl_example.rb +0 -22
- data/spec/fixtures/project_overview.md +0 -48
- data/spec/fixtures/sample.md +0 -19
- data/spec/lib/brief/line_spec.rb +0 -11
- data/spec/lib/brief/parser_spec.rb +0 -12
@@ -0,0 +1,117 @@
|
|
1
|
+
module Brief
|
2
|
+
class Model::Definition
|
3
|
+
attr_accessor :type_alias,
|
4
|
+
:name,
|
5
|
+
:metadata_schema,
|
6
|
+
:content_schema,
|
7
|
+
:options,
|
8
|
+
:defined_helpers
|
9
|
+
|
10
|
+
def initialize(name, options={})
|
11
|
+
@name = name
|
12
|
+
@options = options
|
13
|
+
@type_alias = options.fetch(:type_alias) { name.downcase.parameterize.gsub(/-/,'_') }
|
14
|
+
@metadata_schema = {}.to_mash
|
15
|
+
@content_schema = {attributes:{}}.to_mash
|
16
|
+
@model_class = options[:model_class]
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid?
|
20
|
+
name.to_s.length > 0 && type_alias.to_s.length > 0
|
21
|
+
end
|
22
|
+
|
23
|
+
def validate!
|
24
|
+
definition = self
|
25
|
+
|
26
|
+
if valid?
|
27
|
+
create_model_class.tap do |k|
|
28
|
+
k.send(:include, Brief::Model)
|
29
|
+
|
30
|
+
k.definition = definition
|
31
|
+
|
32
|
+
k.name ||= name
|
33
|
+
k.type_alias ||= type_alias
|
34
|
+
|
35
|
+
Brief::Model.classes << k
|
36
|
+
end
|
37
|
+
|
38
|
+
apply_config
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def apply_config
|
43
|
+
metadata_schema.values.each do |settings|
|
44
|
+
if model_class.nil?
|
45
|
+
binding.pry
|
46
|
+
end
|
47
|
+
|
48
|
+
model_class.send(:attribute, *(settings[:args]))
|
49
|
+
end
|
50
|
+
|
51
|
+
Array(self.defined_helpers).each do |mod|
|
52
|
+
model_class.send(:include, mod)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_model_class
|
57
|
+
model_namespace.const_set(type_alias.camelize, Class.new) unless model_class
|
58
|
+
end
|
59
|
+
|
60
|
+
def model_class
|
61
|
+
@model_class || model_namespace.const_get(type_alias.camelize) rescue nil
|
62
|
+
end
|
63
|
+
|
64
|
+
def model_namespace
|
65
|
+
Brief.configuration.model_namespace || Brief::Model
|
66
|
+
end
|
67
|
+
|
68
|
+
def meta(options={}, &block)
|
69
|
+
@current = :meta
|
70
|
+
instance_eval(&block)
|
71
|
+
end
|
72
|
+
|
73
|
+
def content(options={}, &block)
|
74
|
+
@current = :content
|
75
|
+
instance_eval(&block)
|
76
|
+
end
|
77
|
+
|
78
|
+
def helpers(&block)
|
79
|
+
self.defined_helpers ||= []
|
80
|
+
|
81
|
+
if block
|
82
|
+
mod = Module.new
|
83
|
+
mod.module_eval(&block)
|
84
|
+
|
85
|
+
self.defined_helpers << mod
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def inside_meta?
|
90
|
+
@current == :meta
|
91
|
+
end
|
92
|
+
|
93
|
+
def inside_content?
|
94
|
+
@current == :content
|
95
|
+
end
|
96
|
+
|
97
|
+
def method_missing(meth, *args, &block)
|
98
|
+
args = args.dup
|
99
|
+
|
100
|
+
if inside_content?
|
101
|
+
if meth.to_s == :define_section
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
self.content_schema.attributes[meth] = {args: args, block: block}
|
106
|
+
elsif inside_meta?
|
107
|
+
if args.first.is_a?(Hash)
|
108
|
+
args.unshift(String)
|
109
|
+
end
|
110
|
+
args.unshift(meth)
|
111
|
+
self.metadata_schema[meth] = {args: args, block: block}
|
112
|
+
else
|
113
|
+
super
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/lib/brief/model.rb
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
module Brief
|
2
|
+
module Model
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
unless defined?(Virtus)
|
7
|
+
require 'inflecto'
|
8
|
+
require 'virtus'
|
9
|
+
end
|
10
|
+
|
11
|
+
include Virtus.model(finalize: false)
|
12
|
+
include Initializers
|
13
|
+
include AccessorMethods
|
14
|
+
include Persistence
|
15
|
+
|
16
|
+
class_attribute :models, :after_initialization_hooks, :defined_helpers
|
17
|
+
|
18
|
+
self.models = Array(self.models).to_set
|
19
|
+
|
20
|
+
class << self
|
21
|
+
include Enumerable
|
22
|
+
end
|
23
|
+
|
24
|
+
attribute :path, Pathname
|
25
|
+
attribute :document, Brief::Document
|
26
|
+
|
27
|
+
Brief::Model.classes << self
|
28
|
+
end
|
29
|
+
|
30
|
+
module AccessorMethods
|
31
|
+
def data
|
32
|
+
document.data
|
33
|
+
end
|
34
|
+
|
35
|
+
def content
|
36
|
+
document.content
|
37
|
+
end
|
38
|
+
|
39
|
+
def extracted
|
40
|
+
@extracted ||= Brief::Document::ContentExtractor.new(self.class.type_alias, document)
|
41
|
+
end
|
42
|
+
|
43
|
+
def method_missing(meth, *args, &block)
|
44
|
+
if args.empty?
|
45
|
+
if document.respond_to?(meth)
|
46
|
+
document.send(meth)
|
47
|
+
else
|
48
|
+
document.data.key?(meth) ? data[meth] : extracted.send(meth)
|
49
|
+
end
|
50
|
+
else
|
51
|
+
super
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.classes
|
57
|
+
@classes ||= Set.new
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.table
|
61
|
+
classes.inject({}.to_mash) do |memo, klass|
|
62
|
+
memo.tap { memo[klass.type_alias] = klass }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.for_type(type_alias)
|
67
|
+
table[type_alias]
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.finalize
|
71
|
+
Virtus.finalize
|
72
|
+
|
73
|
+
classes.each do |klass|
|
74
|
+
klass.name ||= klass.to_s.split('::').last.humanize
|
75
|
+
klass.type_alias ||= klass.name.parameterize.gsub(/-/,'_')
|
76
|
+
|
77
|
+
klass.attribute_set.map(&:name).each do |attr|
|
78
|
+
klass.define_singleton_method("find_by_#{ attr }") do |value|
|
79
|
+
where(attr => value).first
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
klass.definition.apply_config
|
84
|
+
end
|
85
|
+
|
86
|
+
Brief::Repository.define_document_finder_methods
|
87
|
+
end
|
88
|
+
|
89
|
+
def ==(other)
|
90
|
+
self.path == other.path
|
91
|
+
end
|
92
|
+
|
93
|
+
def extract_content(options={})
|
94
|
+
document.extract_content(options)
|
95
|
+
end
|
96
|
+
|
97
|
+
module ClassMethods
|
98
|
+
def where(*args, &block)
|
99
|
+
Brief::DocumentMapper::Query.new(self).send(:where, *args)
|
100
|
+
end
|
101
|
+
|
102
|
+
def each(*args, &block)
|
103
|
+
Array(self.models).send(:each, *args, &block)
|
104
|
+
end
|
105
|
+
|
106
|
+
def meta(options={}, &block)
|
107
|
+
definition.send(:meta, options, &block)
|
108
|
+
end
|
109
|
+
|
110
|
+
def content(options={}, &block)
|
111
|
+
definition.send(:content, options, &block)
|
112
|
+
end
|
113
|
+
|
114
|
+
def actions(&block)
|
115
|
+
definition.send(:helpers, &block)
|
116
|
+
end
|
117
|
+
|
118
|
+
def after_initialize(&block)
|
119
|
+
(self.after_initialization_hooks ||= []).push(block)
|
120
|
+
end
|
121
|
+
|
122
|
+
def name=(value)
|
123
|
+
@name = value
|
124
|
+
end
|
125
|
+
|
126
|
+
def name
|
127
|
+
@name || to_s.split('::').last.underscore.gsub('_',' ').titlecase
|
128
|
+
end
|
129
|
+
|
130
|
+
def type_alias=(value)
|
131
|
+
@type_alias = value
|
132
|
+
end
|
133
|
+
|
134
|
+
def type_alias
|
135
|
+
@type_alias || name.parameterize.gsub(/-/,'_')
|
136
|
+
end
|
137
|
+
|
138
|
+
def definition
|
139
|
+
@definition ||= Brief::Model::Definition.new(name, type_alias: type_alias, model_class: self)
|
140
|
+
end
|
141
|
+
|
142
|
+
def definition=(value)
|
143
|
+
@definition
|
144
|
+
end
|
145
|
+
|
146
|
+
def method_missing(meth, *args, &block)
|
147
|
+
if meth.to_s.match(/^on_(.*)_change$/)
|
148
|
+
create_change_handler($1, *args, &block)
|
149
|
+
else
|
150
|
+
super
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def create_change_handler(attribute, *args, &block)
|
155
|
+
block.call(self)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
module Initializers
|
160
|
+
def set_default_attributes
|
161
|
+
attribute_set.set_defaults(self)
|
162
|
+
send(:after_initialize) if respond_to?(:after_initialize)
|
163
|
+
self
|
164
|
+
end
|
165
|
+
|
166
|
+
def after_initialize
|
167
|
+
Array(self.class.after_initialization_hooks).each do |hook|
|
168
|
+
hook.call(self)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def set_slug_from(column=:name)
|
173
|
+
self.slug = send(column).to_s.downcase.parameterize if self.slug.to_s.length == 0
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Brief
|
2
|
+
class Repository
|
3
|
+
attr_reader :briefcase, :options
|
4
|
+
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
# should compare vs yield
|
8
|
+
def each(*args, &block)
|
9
|
+
documents.send(:each, *args, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(briefcase, options={})
|
13
|
+
@briefcase = briefcase
|
14
|
+
@options = options
|
15
|
+
|
16
|
+
load_documents
|
17
|
+
end
|
18
|
+
|
19
|
+
def documents
|
20
|
+
return @documents if @documents
|
21
|
+
load_documents
|
22
|
+
end
|
23
|
+
|
24
|
+
def where(*args)
|
25
|
+
Brief::DocumentMapper::Query.new(self).send(:where, *args)
|
26
|
+
end
|
27
|
+
|
28
|
+
def order_by(*args)
|
29
|
+
Brief::DocumentMapper::Query.new(self).send(:order_by, *args)
|
30
|
+
end
|
31
|
+
|
32
|
+
def root
|
33
|
+
briefcase.root
|
34
|
+
end
|
35
|
+
|
36
|
+
def load_documents
|
37
|
+
@documents = document_paths.map do |path|
|
38
|
+
Brief::Document.new(path)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def document_paths
|
43
|
+
Dir[root.join("**/*.md").to_s]
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.define_document_finder_methods
|
47
|
+
# Create a finder method on the repository
|
48
|
+
# which lets us find instances of models by their class name
|
49
|
+
Brief::Model.table.keys.each do |type|
|
50
|
+
define_method(type.to_s.pluralize) do
|
51
|
+
Brief::Model.for_type(type).models.to_a
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
data/lib/brief/version.rb
CHANGED
data/lib/brief.rb
CHANGED
@@ -1,56 +1,51 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require "pathname"
|
2
|
+
require "set"
|
3
|
+
require "hashie"
|
4
|
+
require "virtus"
|
5
|
+
require "inflecto"
|
6
|
+
require "active_support"
|
7
|
+
require "active_support/core_ext"
|
8
|
+
require "redcarpet"
|
9
|
+
require "nokogiri"
|
10
|
+
require "yaml"
|
3
11
|
|
4
12
|
module Brief
|
5
|
-
|
6
|
-
|
7
|
-
configuration
|
13
|
+
def self.case= value
|
14
|
+
@briefcase = value
|
8
15
|
end
|
9
16
|
|
10
|
-
def self.
|
11
|
-
|
17
|
+
def self.case
|
18
|
+
@briefcase
|
12
19
|
end
|
13
20
|
|
14
21
|
def self.configuration
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.root
|
19
|
-
Pathname(Dir.pwd())
|
22
|
+
Brief::Configuration.instance
|
20
23
|
end
|
21
24
|
|
22
25
|
def self.gem_root
|
23
26
|
Pathname(File.dirname(__FILE__))
|
24
27
|
end
|
25
28
|
|
26
|
-
def self.
|
27
|
-
|
29
|
+
def self.load_commands
|
30
|
+
Dir[gem_root.join("brief","cli","**/*.rb")].each {|f| require(f) }
|
28
31
|
end
|
29
|
-
end
|
30
|
-
|
31
|
-
require 'pathname'
|
32
|
-
require 'hashie'
|
33
|
-
require 'digest'
|
34
|
-
require 'yaml'
|
35
32
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
require 'brief/parser'
|
41
|
-
require 'brief/document'
|
42
|
-
require 'brief/tree'
|
43
|
-
require 'brief/version'
|
44
|
-
require 'brief/configuration'
|
45
|
-
|
46
|
-
require 'brief/publisher'
|
47
|
-
require 'brief/publisher/handler_manager'
|
48
|
-
# These should be able to be loaded separately
|
49
|
-
# some other way, but to help develoment..
|
50
|
-
require 'brief/handlers/base'
|
51
|
-
require 'brief/formatters/base'
|
33
|
+
def self.load_models(from_folder=nil)
|
34
|
+
Brief::Model.load_all(from_folder: from_folder)
|
35
|
+
end
|
36
|
+
end
|
52
37
|
|
53
|
-
|
54
|
-
require
|
55
|
-
require
|
56
|
-
require
|
38
|
+
require "brief/core_ext"
|
39
|
+
require "brief/version"
|
40
|
+
require "brief/configuration"
|
41
|
+
require "brief/document/rendering"
|
42
|
+
require "brief/document/front_matter"
|
43
|
+
require "brief/document/content_extractor"
|
44
|
+
require "brief/document"
|
45
|
+
require "brief/document_mapper"
|
46
|
+
require "brief/repository"
|
47
|
+
require "brief/model"
|
48
|
+
require "brief/model/definition"
|
49
|
+
require "brief/model/persistence"
|
50
|
+
require "brief/dsl"
|
51
|
+
require "brief/briefcase"
|
@@ -0,0 +1,27 @@
|
|
1
|
+
config do
|
2
|
+
set(:models => Pathname(File.dirname(__FILE__)).join("models"))
|
3
|
+
end
|
4
|
+
|
5
|
+
define "User Story" do
|
6
|
+
meta do
|
7
|
+
title
|
8
|
+
status :in => %w(draft published)
|
9
|
+
epic_title
|
10
|
+
end
|
11
|
+
|
12
|
+
content do
|
13
|
+
persona "p strong:first-child"
|
14
|
+
behavior "p strong:second-child"
|
15
|
+
goal "p strong:third-child"
|
16
|
+
end
|
17
|
+
|
18
|
+
helpers do
|
19
|
+
def defined_helper_method
|
20
|
+
true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
action "custom command" do
|
26
|
+
$custom_command = true
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
---
|
2
|
+
type: epic
|
3
|
+
title: Blueprint Epic Example
|
4
|
+
subheading: An example of an Epic
|
5
|
+
state: active
|
6
|
+
---
|
7
|
+
|
8
|
+
# Blueprint Epic Example
|
9
|
+
|
10
|
+
This is an example of an Epic Document. An Epic is a single document
|
11
|
+
which contains user stories and such.
|
12
|
+
|
13
|
+
# User Stories
|
14
|
+
|
15
|
+
## A user wants to write epics
|
16
|
+
|
17
|
+
## A user wants to annotate wireframes
|
18
|
+
|
19
|
+
## A user wants to provide details about domain concepts
|
@@ -0,0 +1,24 @@
|
|
1
|
+
---
|
2
|
+
type: user_story
|
3
|
+
title: Blueprint User Story Example
|
4
|
+
subheading: A way of describing desired behavior of the software, from the perspective of a persona who has a goal
|
5
|
+
epic: Blueprint Epic Example
|
6
|
+
release: Blueprint Release Example
|
7
|
+
state: active
|
8
|
+
title: A Blueprint Persona Example wants this behavior
|
9
|
+
---
|
10
|
+
|
11
|
+
As a **Blueprint Persona Example** I would like to **do this certain thing in the software** so that I can **accomplish this goal**
|
12
|
+
|
13
|
+
#### Wireframes
|
14
|
+
|
15
|
+
- Blueprint Wireframe Example
|
16
|
+
|
17
|
+
#### Concepts
|
18
|
+
|
19
|
+
- Blueprint Concept Example
|
20
|
+
|
21
|
+
#### Resources
|
22
|
+
|
23
|
+
- Blueprint Example Resource
|
24
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Brief::Epic
|
2
|
+
include Brief::Model
|
3
|
+
|
4
|
+
meta do
|
5
|
+
title String
|
6
|
+
status String, :in => %w(draft published)
|
7
|
+
end
|
8
|
+
|
9
|
+
content do
|
10
|
+
title "h1:first-child"
|
11
|
+
|
12
|
+
define_section "User Stories" do
|
13
|
+
has_many :user_stories, "h2" => "title", "p:first-child" => "paragraph"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "The Briefcase" do
|
4
|
+
let(:briefcase) { Brief.example }
|
5
|
+
|
6
|
+
it "has a root path" do
|
7
|
+
expect(briefcase.root).to be_exist
|
8
|
+
end
|
9
|
+
|
10
|
+
it "points to a file repository" do
|
11
|
+
expect(briefcase.repository).to be_a(Brief::Repository)
|
12
|
+
end
|
13
|
+
|
14
|
+
context "Model Loading" do
|
15
|
+
it "loads the model definitions from the models folder" do
|
16
|
+
end
|
17
|
+
|
18
|
+
it "loads the model definitions from the DSL in the config file" do
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "Document Mappings" do
|
23
|
+
it "has all of the documents" do
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,35 +1,27 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe Brief
|
4
|
-
let(:
|
5
|
-
|
6
|
-
|
7
|
-
Brief::Document.new(path: path)
|
3
|
+
describe "The Brief Document" do
|
4
|
+
let(:sample) do
|
5
|
+
path = Brief.example_path.join("docs","epic.html.md")
|
6
|
+
Brief::Document.new(path)
|
8
7
|
end
|
9
8
|
|
10
|
-
it "
|
11
|
-
|
12
|
-
expect(level_one.first.title).to eq("Heading One")
|
9
|
+
it "renders html" do
|
10
|
+
expect(sample.to_html).to include("<h1>User Stories</h1>")
|
13
11
|
end
|
14
12
|
|
15
|
-
it "
|
16
|
-
|
17
|
-
expect(level_one.first.title).to eq("Heading One")
|
13
|
+
it "parses the html" do
|
14
|
+
expect(sample.css("h1").length).to eq(2)
|
18
15
|
end
|
19
16
|
|
20
|
-
|
21
|
-
|
22
|
-
expect(tutorial.parser).not_to be_nil
|
23
|
-
end
|
24
|
-
|
25
|
-
it "should have a publisher" do
|
26
|
-
expect(tutorial.publisher).not_to be_nil
|
27
|
-
end
|
17
|
+
it "deserializes YAML frontmatter into attributes" do
|
18
|
+
expect(sample.frontmatter.type).to eq("epic")
|
28
19
|
end
|
29
20
|
|
30
|
-
|
31
|
-
it "
|
32
|
-
|
21
|
+
context "Content Extraction" do
|
22
|
+
it "extracts content from a css selector" do
|
23
|
+
extracted = sample.extract_content(:args => ["h1:first-child"])
|
24
|
+
expect(extracted).to eq("Blueprint Epic Example")
|
33
25
|
end
|
34
26
|
end
|
35
27
|
end
|
data/spec/lib/brief/dsl_spec.rb
CHANGED
@@ -1,21 +1,10 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe "The Publisher definition DSL" do
|
4
|
-
before(:all) do
|
5
|
-
require Brief.fixtures.join("generator_dsl_example.rb")
|
6
|
-
end
|
7
|
-
|
8
|
-
it "should define a generator called Project Overview" do
|
9
|
-
expect(Brief::Publisher.fetch("Project Overview")).to be_present
|
10
|
-
end
|
11
3
|
|
12
|
-
|
13
|
-
|
14
|
-
end
|
4
|
+
describe "The Configuration DSL" do
|
5
|
+
let(:briefcase) { Brief.example }
|
15
6
|
|
16
|
-
it "
|
17
|
-
expect(
|
7
|
+
it "can create methods on our models" do
|
8
|
+
expect(briefcase.user_stories.first.defined_helper_method).to eq(true)
|
18
9
|
end
|
19
|
-
|
20
|
-
|
21
10
|
end
|