brief 0.0.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +71 -55
  4. data/README.md +149 -48
  5. data/Rakefile +15 -5
  6. data/bin/brief +15 -28
  7. data/brief.gemspec +17 -11
  8. data/examples/blog/brief.rb +54 -0
  9. data/examples/blog/docs/an-intro-to-brief.html.md +9 -0
  10. data/lib/.DS_Store +0 -0
  11. data/lib/brief/briefcase.rb +78 -0
  12. data/lib/brief/cli/change.rb +14 -0
  13. data/lib/brief/cli/init.rb +66 -0
  14. data/{spec/fixtures/generated/project_overview.json → lib/brief/cli/publish.rb} +0 -0
  15. data/lib/brief/cli/write.rb +0 -0
  16. data/lib/brief/configuration.rb +19 -115
  17. data/lib/brief/core_ext.rb +11 -0
  18. data/lib/brief/document/content_extractor.rb +33 -0
  19. data/lib/brief/document/front_matter.rb +20 -0
  20. data/lib/brief/document/rendering.rb +37 -0
  21. data/lib/brief/document.rb +43 -38
  22. data/lib/brief/document_mapper.rb +158 -0
  23. data/lib/brief/dsl.rb +42 -0
  24. data/lib/brief/model/definition.rb +117 -0
  25. data/lib/brief/model.rb +177 -0
  26. data/lib/brief/repository.rb +57 -0
  27. data/lib/brief/version.rb +1 -7
  28. data/lib/brief.rb +35 -40
  29. data/spec/fixtures/example/brief.rb +27 -0
  30. data/spec/fixtures/example/docs/concept.html.md +5 -0
  31. data/spec/fixtures/example/docs/epic.html.md +19 -0
  32. data/spec/fixtures/example/docs/persona.html.md +5 -0
  33. data/spec/fixtures/example/docs/release.html.md +7 -0
  34. data/spec/fixtures/example/docs/resource.html.md +5 -0
  35. data/spec/fixtures/example/docs/user_story.html.md +24 -0
  36. data/spec/fixtures/example/docs/wireframe.html.md +5 -0
  37. data/spec/fixtures/example/models/epic.rb +16 -0
  38. data/spec/lib/brief/briefcase_spec.rb +27 -0
  39. data/spec/lib/brief/document_spec.rb +14 -22
  40. data/spec/lib/brief/dsl_spec.rb +4 -15
  41. data/spec/lib/brief/model_spec.rb +84 -0
  42. data/spec/lib/brief/repository_spec.rb +60 -0
  43. data/spec/spec_helper.rb +12 -14
  44. data/spec/support/test_helpers.rb +0 -0
  45. data/tasks/brief/release.rake +0 -0
  46. metadata +120 -110
  47. data/.gitignore +0 -1
  48. data/Guardfile +0 -5
  49. data/examples/project_overview.md +0 -23
  50. data/lib/brief/cli/commands/config.rb +0 -40
  51. data/lib/brief/cli/commands/publish.rb +0 -27
  52. data/lib/brief/cli/commands/write.rb +0 -27
  53. data/lib/brief/formatters/base.rb +0 -12
  54. data/lib/brief/formatters/github_milestone_rollup.rb +0 -52
  55. data/lib/brief/git.rb +0 -19
  56. data/lib/brief/github/wiki.rb +0 -9
  57. data/lib/brief/github.rb +0 -141
  58. data/lib/brief/github_client/authentication.rb +0 -32
  59. data/lib/brief/github_client/client.rb +0 -86
  60. data/lib/brief/github_client/commands.rb +0 -5
  61. data/lib/brief/github_client/issue_labels.rb +0 -65
  62. data/lib/brief/github_client/issues.rb +0 -22
  63. data/lib/brief/github_client/milestone_issues.rb +0 -13
  64. data/lib/brief/github_client/organization_activity.rb +0 -9
  65. data/lib/brief/github_client/organization_issues.rb +0 -13
  66. data/lib/brief/github_client/organization_repositories.rb +0 -20
  67. data/lib/brief/github_client/organization_users.rb +0 -9
  68. data/lib/brief/github_client/repository_events.rb +0 -8
  69. data/lib/brief/github_client/repository_issue_events.rb +0 -9
  70. data/lib/brief/github_client/repository_issues.rb +0 -8
  71. data/lib/brief/github_client/repository_labels.rb +0 -18
  72. data/lib/brief/github_client/repository_milestones.rb +0 -9
  73. data/lib/brief/github_client/request.rb +0 -181
  74. data/lib/brief/github_client/request_wrapper.rb +0 -121
  75. data/lib/brief/github_client/response_object.rb +0 -50
  76. data/lib/brief/github_client/single_repository.rb +0 -9
  77. data/lib/brief/github_client/user_activity.rb +0 -16
  78. data/lib/brief/github_client/user_gists.rb +0 -9
  79. data/lib/brief/github_client/user_info.rb +0 -9
  80. data/lib/brief/github_client/user_issues.rb +0 -13
  81. data/lib/brief/github_client/user_organizations.rb +0 -9
  82. data/lib/brief/github_client/user_repositories.rb +0 -9
  83. data/lib/brief/github_client.rb +0 -43
  84. data/lib/brief/handlers/base.rb +0 -62
  85. data/lib/brief/handlers/github_issue.rb +0 -41
  86. data/lib/brief/handlers/github_milestone.rb +0 -37
  87. data/lib/brief/handlers/github_wiki.rb +0 -11
  88. data/lib/brief/line.rb +0 -69
  89. data/lib/brief/parser.rb +0 -354
  90. data/lib/brief/publisher/handler_manager.rb +0 -47
  91. data/lib/brief/publisher.rb +0 -142
  92. data/lib/brief/tree.rb +0 -43
  93. data/lib/core_ext.rb +0 -37
  94. data/spec/fixtures/front_end_tutorial.md +0 -33
  95. data/spec/fixtures/generator_dsl_example.rb +0 -22
  96. data/spec/fixtures/project_overview.md +0 -48
  97. data/spec/fixtures/sample.md +0 -19
  98. data/spec/lib/brief/line_spec.rb +0 -11
  99. 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
@@ -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
@@ -1,9 +1,3 @@
1
1
  module Brief
2
- MAJOR = 0
3
- MINOR = 0
4
- REVISION = 1
5
-
6
- Version = "#{ MAJOR }.#{ MINOR }.#{ REVISION }"
7
-
8
- VERSION = Version
2
+ VERSION = "1.0.0"
9
3
  end
data/lib/brief.rb CHANGED
@@ -1,56 +1,51 @@
1
- lib = File.dirname(__FILE__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
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
- # Haven't decided if the brief config system should support different profiles or not
6
- def self.profile
7
- configuration
13
+ def self.case= value
14
+ @briefcase = value
8
15
  end
9
16
 
10
- def self.config
11
- configuration
17
+ def self.case
18
+ @briefcase
12
19
  end
13
20
 
14
21
  def self.configuration
15
- @configuration ||= Brief::Configuration.instance
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.define publisher_name, &config
27
- Brief::Publisher.define(publisher_name, &config)
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
- require 'active_support'
37
- require 'active_support/core_ext'
38
-
39
- require 'brief/line'
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
- # these may be optional one day
54
- require 'brief/github'
55
- require 'brief/git'
56
- require 'brief/github/wiki'
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,5 @@
1
+ ---
2
+ type: concept
3
+ title: Blueprint Concept Example
4
+ subheading: A key concept to the domain model
5
+ ---
@@ -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,5 @@
1
+ ---
2
+ type: persona
3
+ title: Blueprint Persona Example
4
+ subheading: A description of a typical user of the software
5
+ ---
@@ -0,0 +1,7 @@
1
+ ---
2
+ type: release
3
+ title: Blueprint Release Example
4
+ subheading: A release milestone for the software
5
+ status: Planned
6
+ date: 2018-12-18
7
+ ---
@@ -0,0 +1,5 @@
1
+ ---
2
+ type: resource
3
+ title: Blueprint Example Resource
4
+ subheading: An example API Resource document
5
+ ---
@@ -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,5 @@
1
+ ---
2
+ type: wireframe
3
+ title: Blueprint Wireframe Example
4
+ subheading: A key concept to the domain model
5
+ ---
@@ -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::Document do
4
- let(:path) { Brief.fixtures.join("sample.md") }
5
-
6
- let(:tutorial) do
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 "should let me pass raw markdown" do
11
- level_one = Brief::Document.new(path.read).tree.level(1)
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 "should let me pass a markdown file" do
16
- level_one = Brief::Document.new(path).tree.level(1)
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
- describe "Parsers and Publishers" do
21
- it "should have a parser" do
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
- describe "Finding code blocks by language" do
31
- it "should find the blocks of code and group them by their language" do
32
- expect(tutorial.code_blocks_by_language).not_to be_empty
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
@@ -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
- it "should find the appropriate Publisher by using an alias" do
13
- expect(Brief::Publisher.fetch("project_overview")).to be_present
14
- end
4
+ describe "The Configuration DSL" do
5
+ let(:briefcase) { Brief.example }
15
6
 
16
- it "should find the appropriate Publisher using a case insensitve search" do
17
- expect(Brief::Publisher.fetch("project overview")).to be_present
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